|  |  | 
 |  |  | <template> | 
 |  |  |   <ContentScrollView :paddingH="false"> | 
 |  |  |     <nut-form :model-value="form" ref="formRef" :rules="rules"> | 
 |  |  |       <nut-form-item label="任务名称:" class="bole-form-item" prop="taskName" label-width="90px"> | 
 |  |  |         <nut-input v-model="form.taskName" placeholder="请输入任务名称"> </nut-input> | 
 |  |  |       <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" | 
 |  |  |         prop="feeType" | 
 |  |  |         class="bole-form-item alignTop" | 
 |  |  |         prop="billingMethod" | 
 |  |  |         required | 
 |  |  |         label-width="90px" | 
 |  |  |         label-position="top" | 
 |  |  |       > | 
 |  |  |         <nut-radio-group v-model="form.feeType" direction="horizontal"> | 
 |  |  |           <BlRadio :label="Number(key)" v-for="(val, key) in FlexTaskFeeTypeEnumText" :key="key">{{ | 
 |  |  |         <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="fee" label-width="90px"> | 
 |  |  |       <nut-form-item label=" " class="bole-form-item" prop="serviceFee" label-width="0"> | 
 |  |  |         <div class="bole-form-input-wrapper"> | 
 |  |  |           <nut-input | 
 |  |  |             v-model.trim="form.fee" | 
 |  |  |           <NumberInput | 
 |  |  |             v-model.trim="form.serviceFee" | 
 |  |  |             class="nut-input-text bole-input-text" | 
 |  |  |             placeholder="请输入服务费" | 
 |  |  |             type="text" | 
 |  |  |             :min="0" | 
 |  |  |           /> | 
 |  |  |           <div class="form-input-unit">{{ SalaryTimeTypeEnumUnit[form.feeType] }}</div> | 
 |  |  |           <div class="form-input-unit">{{ BillingMethodEnumUnit[form.billingMethod] }}</div> | 
 |  |  |         </div> | 
 |  |  |       </nut-form-item> | 
 |  |  |       <nut-form-item | 
 |  |  | 
 |  |  |         required | 
 |  |  |         label-width="90px" | 
 |  |  |       > | 
 |  |  |         <nut-radio-group v-model="form.settleType" direction="horizontal"> | 
 |  |  |           <BlRadio | 
 |  |  |             :label="Number(key)" | 
 |  |  |             v-for="(val, key) in FlexTaskSettleTypeEnumText" | 
 |  |  |             :key="key" | 
 |  |  |             >{{ val }}</BlRadio | 
 |  |  |           > | 
 |  |  |         <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="listAideIds" label-width="90px"> | 
 |  |  |         <ChooseInputWithPicker | 
 |  |  |           v-model="form.listAideIds" | 
 |  |  |       <nut-form-item label="福利:" class="bole-form-item" prop="benefits" label-width="90px"> | 
 |  |  |         <ChooseInputWithCheckbox | 
 |  |  |           v-model="form.benefits" | 
 |  |  |           title="请选择福利" | 
 |  |  |           :columns="WelfareTypeList" | 
 |  |  |           placeholder="请选择福利" | 
 |  |  |           :value-enum="TaskStatusText" | 
 |  |  |         /> | 
 |  |  |       </nut-form-item> | 
 |  |  |       <nut-form-item | 
 |  |  |         label="年龄范围:" | 
 |  |  |         class="bole-form-item" | 
 |  |  |         prop="ageStart" | 
 |  |  |         prop="ageMinLimit" | 
 |  |  |         required | 
 |  |  |         label-width="90px" | 
 |  |  |       > | 
 |  |  |         <div class="bole-form-input-wrapper"> | 
 |  |  |           <NumberInput | 
 |  |  |             v-model.trim="form.ageStart" | 
 |  |  |             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.ageEnd" | 
 |  |  |             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="welfare" label-width="90px"> | 
 |  |  |       <nut-form-item | 
 |  |  |         label="性别要求:" | 
 |  |  |         class="bole-form-item" | 
 |  |  |         prop="genderLimit" | 
 |  |  |         label-width="90px" | 
 |  |  |         required | 
 |  |  |       > | 
 |  |  |         <ChooseInputWithPicker | 
 |  |  |           v-model="form.welfare" | 
 |  |  |           v-model="form.genderLimit" | 
 |  |  |           placeholder="请选择性别要求" | 
 |  |  |           :value-enum="TaskStatusText" | 
 |  |  |           :value-enum="EnumUserGenderTextOptions" | 
 |  |  |         /> | 
 |  |  |       </nut-form-item> | 
 |  |  |       <nut-form-item label="资格证书:" class="bole-form-item" prop="welfare" label-width="90px"> | 
 |  |  |         <ChooseInputWithPicker | 
 |  |  |           v-model="form.welfare" | 
 |  |  |           placeholder="请选择要求的资格证书" | 
 |  |  |           :value-enum="TaskStatusText" | 
 |  |  |       <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" /> | 
 |  |  |         <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="name" label-width="90px"> | 
 |  |  |         <nut-input v-model="form.name" placeholder="请输入详细地址"> </nut-input> | 
 |  |  |       <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="startDate" | 
 |  |  |         prop="beginTime" | 
 |  |  |         label-width="90px" | 
 |  |  |       > | 
 |  |  |         <ChooseInputWithDatePicker v-model="form.startDate"></ChooseInputWithDatePicker> | 
 |  |  |         <ChooseInputWithDatePicker | 
 |  |  |           v-model="form.beginTime" | 
 |  |  |           :minDate="nowDate" | 
 |  |  |           placeholder="请选择任务开始日期" | 
 |  |  |         ></ChooseInputWithDatePicker> | 
 |  |  |       </nut-form-item> | 
 |  |  |       <nut-form-item label="任务结束日期:" class="bole-form-item" prop="endDate" label-width="90px"> | 
 |  |  |         <ChooseInputWithDatePicker v-model="form.endDate"></ChooseInputWithDatePicker> | 
 |  |  |       <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> | 
 |  |  | 
 |  |  | </template> | 
 |  |  |  | 
 |  |  | <script setup lang="ts"> | 
 |  |  | import { | 
 |  |  |   TaskStatus, | 
 |  |  |   TaskStatusText, | 
 |  |  |   FlexTaskSettleTypeEnum, | 
 |  |  |   FlexTaskSettleTypeEnumText, | 
 |  |  |   FlexTaskFeeTypeEnum, | 
 |  |  |   FlexTaskFeeTypeEnumText, | 
 |  |  |   SalaryTimeTypeEnumUnit, | 
 |  |  | } from '@/constants/task'; | 
 |  |  | 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?.taskId ?? ''; | 
 |  |  | const isEdit = computed(() => !!taskId); | 
 |  |  | 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({ | 
 |  |  |   taskName: '', | 
 |  |  |   feeType: FlexTaskFeeTypeEnum.OfMonth, | 
 |  |  |   fee: 0, | 
 |  |  |   settleType: FlexTaskSettleTypeEnum.OfMonth, | 
 |  |  |   listAideIds: [] as string[], | 
 |  |  |   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[], | 
 |  |  |  | 
 |  |  |   welfare: TaskStatus.All, | 
 |  |  |   salaryTimeType: SalaryTimeTypeEnum.Month, | 
 |  |  |   salaryType: SalaryType.month, | 
 |  |  |   startDate: '', | 
 |  |  |   endDate: '', | 
 |  |  |   ageStart: '', | 
 |  |  |   ageEnd: '', | 
 |  |  |   weMapInfo: {} as WeMapModel, | 
 |  |  |   addressDetail: '', | 
 |  |  | }); | 
 |  |  |  | 
 |  |  | const rules = reactive<FormRules>({ | 
 |  |  |   taskName: [{ required: true, message: '请输入任务名称' }], | 
 |  |  |  | 
 |  |  |   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 }, | 
 |  |  |   // ], | 
 |  |  |  | 
 |  |  |   ageStart: [ | 
 |  |  |   ageMinLimit: [ | 
 |  |  |     { | 
 |  |  |       required: true, | 
 |  |  |       message: '请输入年龄要求', | 
 |  |  |       validator: () => { | 
 |  |  |         if (!form.ageStart) { | 
 |  |  |         if (!form.ageMinLimit && form.ageMinLimit > 0) { | 
 |  |  |           return Promise.reject('请输入年龄要求'); | 
 |  |  |         } | 
 |  |  |         if (!form.ageEnd) { | 
 |  |  |         if (!form.ageMaxLimit && form.ageMaxLimit > 0) { | 
 |  |  |           return Promise.reject('请输入年龄要求'); | 
 |  |  |         } | 
 |  |  |         if (Number(form.ageEnd) <= Number(form.ageStart)) { | 
 |  |  |         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; | 
 |  |  | 
 |  |  |  | 
 |  |  | async function confirm() { | 
 |  |  |   try { | 
 |  |  |     let params: API.AddEidtFlexTaskInput = { | 
 |  |  |       taskName: form.taskName, | 
 |  |  |       feeType: form.salaryType, | 
 |  |  |     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.value) { | 
 |  |  |       params.taskId = taskId; | 
 |  |  |     if (isEdit) { | 
 |  |  |       params.id = taskId; | 
 |  |  |     } | 
 |  |  |     let res = await flexWorkerServices.addEidtFlexTask(params); | 
 |  |  |     if (isCopy) { | 
 |  |  |       params.id = ''; | 
 |  |  |     } | 
 |  |  |     let res = await taskServices.saveTaskInfo(params); | 
 |  |  |     if (res) { | 
 |  |  |       Message.success(isEdit.value ? '编辑成功' : '发布成功', { | 
 |  |  |       Message.success(isEdit && !isCopy ? '编辑成功' : '发布成功', { | 
 |  |  |         onClosed() { | 
 |  |  |           goBack(); | 
 |  |  |         }, | 
 |  |  | 
 |  |  | } | 
 |  |  |  | 
 |  |  | function handleCancel() { | 
 |  |  |   Taro.navigateBack(); | 
 |  |  |   goBack(); | 
 |  |  | } | 
 |  |  | </script> | 
 |  |  |  | 
 |  |  | 
 |  |  |     color: boleGetCssVar('text-color', 'primary'); | 
 |  |  |     flex-shrink: 0; | 
 |  |  |   } | 
 |  |  |  | 
 |  |  |   .form-input-separator { | 
 |  |  |     margin-right: 10px; | 
 |  |  |   } | 
 |  |  | } | 
 |  |  | </style> |