<template> 
 | 
  <ContentScrollView :paddingH="false"> 
 | 
    <nut-form :model-value="form" ref="formRef" :rules="rules"> 
 | 
      <nut-form-item label="任务名称:" class="bole-form-item" prop="name" label-width="90px"> 
 | 
        <nut-input v-model="form.name" placeholder="请输入任务名称"> </nut-input> 
 | 
      </nut-form-item> 
 | 
      <nut-form-item 
 | 
        label="服务费:" 
 | 
        class="bole-form-item alignTop" 
 | 
        prop="billingMethod" 
 | 
        required 
 | 
        label-width="90px" 
 | 
        label-position="top" 
 | 
      > 
 | 
        <nut-radio-group v-model="form.billingMethod" direction="horizontal"> 
 | 
          <BlRadio :label="Number(key)" v-for="(val, key) in EnumBillingMethodText" :key="key">{{ 
 | 
            val 
 | 
          }}</BlRadio> 
 | 
        </nut-radio-group> 
 | 
      </nut-form-item> 
 | 
      <nut-form-item label=" " class="bole-form-item" prop="serviceFee" label-width="0"> 
 | 
        <div class="bole-form-input-wrapper"> 
 | 
          <NumberInput 
 | 
            v-model.trim="form.serviceFee" 
 | 
            class="nut-input-text bole-input-text" 
 | 
            placeholder="请输入服务费" 
 | 
            :min="0" 
 | 
          /> 
 | 
          <div class="form-input-unit">{{ BillingMethodEnumUnit[form.billingMethod] }}</div> 
 | 
        </div> 
 | 
      </nut-form-item> 
 | 
      <nut-form-item 
 | 
        label="结算方式:" 
 | 
        class="bole-form-item" 
 | 
        prop="settleType" 
 | 
        required 
 | 
        label-width="90px" 
 | 
      > 
 | 
        <nut-radio-group v-model="form.settlementCycle" direction="horizontal"> 
 | 
          <BlRadio :label="Number(key)" v-for="(val, key) in EnumSettlementCycleText" :key="key">{{ 
 | 
            val 
 | 
          }}</BlRadio> 
 | 
        </nut-radio-group> 
 | 
      </nut-form-item> 
 | 
      <nut-form-item label="福利:" class="bole-form-item" prop="benefits" label-width="90px"> 
 | 
        <ChooseInputWithCheckbox 
 | 
          v-model="form.benefits" 
 | 
          title="请选择福利" 
 | 
          :columns="WelfareTypeList" 
 | 
          placeholder="请选择福利" 
 | 
        /> 
 | 
      </nut-form-item> 
 | 
      <nut-form-item 
 | 
        label="年龄范围:" 
 | 
        class="bole-form-item" 
 | 
        prop="ageMinLimit" 
 | 
        required 
 | 
        label-width="90px" 
 | 
      > 
 | 
        <div class="bole-form-input-wrapper"> 
 | 
          <NumberInput 
 | 
            v-model.trim="form.ageMinLimit" 
 | 
            class="nut-input-text bole-input-text" 
 | 
            placeholder="请选择年龄范围" 
 | 
            :min="1" 
 | 
          /> 
 | 
          <div class="form-input-separator">至</div> 
 | 
          <NumberInput 
 | 
            v-model.trim="form.ageMaxLimit" 
 | 
            class="nut-input-text bole-input-text" 
 | 
            placeholder="请选择年龄范围" 
 | 
            :min="1" 
 | 
          /> 
 | 
        </div> 
 | 
      </nut-form-item> 
 | 
      <nut-form-item 
 | 
        label="性别要求:" 
 | 
        class="bole-form-item" 
 | 
        prop="genderLimit" 
 | 
        label-width="90px" 
 | 
        required 
 | 
      > 
 | 
        <ChooseInputWithPicker 
 | 
          v-model="form.genderLimit" 
 | 
          placeholder="请选择性别要求" 
 | 
          :value-enum="EnumUserGenderTextOptions" 
 | 
        /> 
 | 
      </nut-form-item> 
 | 
      <nut-form-item 
 | 
        label="资格证书:" 
 | 
        class="bole-form-item" 
 | 
        prop="credentialLimits" 
 | 
        label-width="90px" 
 | 
      > 
 | 
        <ChooseInputWithCheckbox 
 | 
          v-model="form.credentialLimits" 
 | 
          title="请选择资格证书" 
 | 
          :columns="CertificateTypeList" 
 | 
          placeholder="请选择资格证书" 
 | 
        /> 
 | 
      </nut-form-item> 
 | 
      <nut-form-item label="任务地点" class="bole-form-item" prop="weMapInfo" required> 
 | 
        <ChooseLocationInput placeholder="请选择任务地点" v-model="form.weMapInfo" /> 
 | 
        <!-- <ChooseInputWithAreaPicker 
 | 
          :columns="areaTreeList" 
 | 
          v-model="form.areaList" 
 | 
          placeholder="请选择所在地区" 
 | 
        ></ChooseInputWithAreaPicker> --> 
 | 
      </nut-form-item> 
 | 
      <nut-form-item 
 | 
        label="详细地址:" 
 | 
        class="bole-form-item" 
 | 
        prop="addressDetail" 
 | 
        label-width="90px" 
 | 
        required 
 | 
      > 
 | 
        <nut-input v-model="form.addressDetail" placeholder="请输入详细地址"> </nut-input> 
 | 
      </nut-form-item> 
 | 
      <nut-form-item 
 | 
        label="任务开始日期:" 
 | 
        class="bole-form-item" 
 | 
        prop="beginTime" 
 | 
        label-width="90px" 
 | 
      > 
 | 
        <ChooseInputWithDatePicker 
 | 
          v-model="form.beginTime" 
 | 
          :minDate="nowDate" 
 | 
          placeholder="请选择任务开始日期" 
 | 
        ></ChooseInputWithDatePicker> 
 | 
      </nut-form-item> 
 | 
      <nut-form-item label="任务结束日期:" class="bole-form-item" prop="endTime" label-width="90px"> 
 | 
        <ChooseInputWithDatePicker 
 | 
          v-model="form.endTime" 
 | 
          :minDate="nowDate" 
 | 
          placeholder="请选择任务结束日期" 
 | 
        ></ChooseInputWithDatePicker> 
 | 
      </nut-form-item> 
 | 
    </nut-form> 
 | 
  </ContentScrollView> 
 | 
  <PageFooter> 
 | 
    <PageFooterBtn type="primary" plain @click="handleCancel">取消</PageFooterBtn> 
 | 
    <PageFooterBtn type="primary" @click="handleConfirm">发布</PageFooterBtn> 
 | 
  </PageFooter> 
 | 
</template> 
 | 
  
 | 
<script setup lang="ts"> 
 | 
import { useUser } from '@/hooks'; 
 | 
import { 
 | 
  CategoryCode, 
 | 
  EnumBillingMethod, 
 | 
  EnumSettlementCycle, 
 | 
  EnumUserGender, 
 | 
  EnumBillingMethodText, 
 | 
  EnumUserGenderText, 
 | 
  EnumSettlementCycleText, 
 | 
  BillingMethodEnumUnit, 
 | 
  EnumUserGenderTextOptions, 
 | 
} from '@12333/constants'; 
 | 
import { 
 | 
  ChooseInputWithPicker, 
 | 
  ChooseInputWithDatePicker, 
 | 
  NumberInput, 
 | 
  ChooseLocationInput, 
 | 
  Radio as BlRadio, 
 | 
  ChooseInputWithAreaPicker, 
 | 
  ChooseInputWithCheckbox, 
 | 
} from '@12333/components'; 
 | 
import { FormValidator, Message } from '@12333/utils'; 
 | 
import * as flexWorkerServices from '@12333/services/api/FlexWorker'; 
 | 
import * as taskServices from '@12333/services/apiV2/task'; 
 | 
import { FormRules } from '@nutui/nutui-taro/dist/types/__VUE/form/types'; 
 | 
import Taro from '@tarojs/taro'; 
 | 
import { goBack } from '@/utils'; 
 | 
import { useAllAreaList, useDictionaryDataSelect } from '@12333/hooks'; 
 | 
import { useQuery } from '@tanstack/vue-query'; 
 | 
import dayjs from 'dayjs'; 
 | 
  
 | 
defineOptions({ 
 | 
  name: 'InnerPage', 
 | 
}); 
 | 
  
 | 
const { userDetail } = useUser(); 
 | 
const { findAreaNameFromCode } = useAllAreaList(); 
 | 
const router = Taro.useRouter(); 
 | 
const taskId = router.params?.id ?? ''; 
 | 
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, 
 | 
}); 
 | 
const { dictionaryDataList: CertificateTypeList } = useDictionaryDataSelect({ 
 | 
  categoryCode: CategoryCode.CertificateType, 
 | 
}); 
 | 
  
 | 
const form = reactive({ 
 | 
  name: '', 
 | 
  billingMethod: EnumBillingMethod.Day, 
 | 
  serviceFee: '' as any as number, 
 | 
  settlementCycle: EnumSettlementCycle.Day, 
 | 
  benefits: [] as string[], 
 | 
  ageMinLimit: '' as any as number, 
 | 
  ageMaxLimit: '' as any as number, 
 | 
  genderLimit: 0 as any as EnumUserGender, 
 | 
  credentialLimits: [] as string[], 
 | 
  // address: '', 
 | 
  beginTime: '', 
 | 
  endTime: '', 
 | 
  // areaList: [] as number[], 
 | 
  
 | 
  weMapInfo: {} as WeMapModel, 
 | 
  addressDetail: '', 
 | 
}); 
 | 
  
 | 
const rules = reactive<FormRules>({ 
 | 
  name: [{ required: true, message: '请输入任务名称' }], 
 | 
  genderLimit: [{ required: true, message: '请选择性别要求' }], 
 | 
  addressDetail: [{ required: true, message: '请输入详细地址' }], 
 | 
  billingMethod: [ 
 | 
    { 
 | 
      required: true, 
 | 
      message: '请选择收费方式', 
 | 
      validator: () => { 
 | 
        if (!form.billingMethod) { 
 | 
          return Promise.reject('请选择服务费类型'); 
 | 
        } 
 | 
        if (!form.serviceFee) { 
 | 
          return Promise.reject('请输入服务费'); 
 | 
        } 
 | 
        return Promise.resolve(true); 
 | 
      }, 
 | 
    }, 
 | 
  ], 
 | 
  weMapInfo: [ 
 | 
    { required: true, message: '请设置工作地点', validator: FormValidator.validatorWeMap }, 
 | 
  ], 
 | 
  // areaList: [ 
 | 
  //   { required: true, message: '请添加工作地点', validator: FormValidator.validatorArray }, 
 | 
  // ], 
 | 
  
 | 
  ageMinLimit: [ 
 | 
    { 
 | 
      required: true, 
 | 
      message: '请输入年龄要求', 
 | 
      validator: () => { 
 | 
        if (!form.ageMinLimit && form.ageMinLimit > 0) { 
 | 
          return Promise.reject('请输入年龄要求'); 
 | 
        } 
 | 
        if (!form.ageMaxLimit && form.ageMaxLimit > 0) { 
 | 
          return Promise.reject('请输入年龄要求'); 
 | 
        } 
 | 
        if (Number(form.ageMaxLimit) <= Number(form.ageMinLimit)) { 
 | 
          return Promise.reject('最大年龄不能小于最小年龄'); 
 | 
        } 
 | 
        return Promise.resolve(true); 
 | 
      }, 
 | 
    }, 
 | 
  ], 
 | 
  
 | 
  beginTime: [ 
 | 
    { 
 | 
      required: true, 
 | 
      message: '请选择开始日期', 
 | 
    }, 
 | 
  ], 
 | 
  endTime: [ 
 | 
    { 
 | 
      required: true, 
 | 
      message: '请选择结束日期', 
 | 
      validator(value) { 
 | 
        if (!value) return Promise.reject('请选择结束日期'); 
 | 
        if (dayjs(value).isBefore(dayjs(form.beginTime))) 
 | 
          return Promise.reject('结束日期需大于开始日期'); 
 | 
        return Promise.resolve(true); 
 | 
      }, 
 | 
    }, 
 | 
  ], 
 | 
}); 
 | 
  
 | 
const { 
 | 
  isLoading, 
 | 
  isError, 
 | 
  data: detail, 
 | 
  refetch, 
 | 
} = useQuery({ 
 | 
  queryKey: ['taskServices/getTaskInfo', taskId], 
 | 
  queryFn: async () => { 
 | 
    return await taskServices.getTaskInfo( 
 | 
      { id: taskId }, 
 | 
      { 
 | 
        showLoading: false, 
 | 
      } 
 | 
    ); 
 | 
  }, 
 | 
  placeholderData: () => ({} as API.GetTaskInfoQueryResult), 
 | 
  enabled: isEdit, 
 | 
  onSuccess(data) { 
 | 
    form.name = data.name; 
 | 
    form.billingMethod = data.billingMethod; 
 | 
    form.serviceFee = data.serviceFee; 
 | 
    form.settlementCycle = data.settlementCycle; 
 | 
    form.benefits = (data.benefits ?? []).map((item) => item.benefitCode); 
 | 
    form.ageMinLimit = data.ageMinLimit; 
 | 
    form.ageMaxLimit = data.ageMaxLimit; 
 | 
    form.genderLimit = data.genderLimit; 
 | 
    form.credentialLimits = (data.credentialLimits ?? []).map((item) => item.typeCode); 
 | 
    form.beginTime = dayjs(data.beginTime).format('YYYY-MM-DD'); 
 | 
    form.endTime = dayjs(data.endTime).format('YYYY-MM-DD'); 
 | 
    form.addressDetail = data.addressDetail; 
 | 
    form.weMapInfo = { 
 | 
      provinceName: data.provinceContent, 
 | 
      cityName: data.cityContent, 
 | 
      provinceCode: data.provinceCode, 
 | 
      cityCode: data.cityCode, 
 | 
      latitude: data.latitude, 
 | 
      longitude: data.longitude, 
 | 
      addressName: data.addressName, 
 | 
    }; 
 | 
  }, 
 | 
}); 
 | 
  
 | 
const formRef = ref<any>(null); 
 | 
function handleConfirm() { 
 | 
  if (!formRef.value) return; 
 | 
  formRef.value.validate().then(({ valid, errors }: any) => { 
 | 
    if (valid) { 
 | 
      confirm(); 
 | 
    } 
 | 
  }); 
 | 
} 
 | 
  
 | 
async function confirm() { 
 | 
  try { 
 | 
    let params: API.SaveTaskInfoCommand = { 
 | 
      name: form.name, 
 | 
      billingMethod: form.billingMethod, 
 | 
      serviceFee: form.serviceFee, 
 | 
      settlementCycle: form.settlementCycle, 
 | 
      benefits: form.benefits, 
 | 
      ageMinLimit: form.ageMinLimit, 
 | 
      ageMaxLimit: form.ageMaxLimit, 
 | 
      genderLimit: form.genderLimit, 
 | 
      credentialLimits: form.credentialLimits, 
 | 
      provinceCode: form.weMapInfo.provinceCode, 
 | 
      cityCode: form.weMapInfo.cityCode, 
 | 
      addressName: form.weMapInfo.addressName, 
 | 
      addressDetail: form.addressDetail, 
 | 
      longitude: form.weMapInfo.longitude, 
 | 
      latitude: form.weMapInfo.latitude, 
 | 
      beginTime: dayjs(form.beginTime).format('YYYY-MM-DD 00:00:00'), 
 | 
      endTime: dayjs(form.endTime).format('YYYY-MM-DD 23:59:59'), 
 | 
    }; 
 | 
    if (isEdit) { 
 | 
      params.id = taskId; 
 | 
    } 
 | 
    if (isCopy) { 
 | 
      params.id = ''; 
 | 
    } 
 | 
    let res = await taskServices.saveTaskInfo(params); 
 | 
    if (res) { 
 | 
      Message.success(isEdit && !isCopy ? '编辑成功' : '发布成功', { 
 | 
        onClosed() { 
 | 
          goBack(); 
 | 
        }, 
 | 
      }); 
 | 
    } 
 | 
  } catch (error) {} 
 | 
} 
 | 
  
 | 
function handleCancel() { 
 | 
  goBack(); 
 | 
} 
 | 
</script> 
 | 
  
 | 
<style lang="scss"> 
 | 
@import '@/styles/common.scss'; 
 | 
  
 | 
.publishTask-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; 
 | 
  } 
 | 
  
 | 
  .form-input-separator { 
 | 
    margin-right: 10px; 
 | 
  } 
 | 
} 
 | 
</style> 
 |