|
|
@ -118,8 +118,8 @@ |
|
|
<label class="form-label required">服务开始时间</label> |
|
|
<label class="form-label required">服务开始时间</label> |
|
|
<a-date-picker |
|
|
<a-date-picker |
|
|
show-time |
|
|
show-time |
|
|
format="YYYY-MM-DD HH:00:00" |
|
|
format="YYYY-MM-DD HH:mm:ss" |
|
|
valueFormat="YYYY-MM-DD HH:00:00" |
|
|
valueFormat="YYYY-MM-DD HH:mm:ss" |
|
|
v-model:value="form.serviceStart" |
|
|
v-model:value="form.serviceStart" |
|
|
class="form-input" |
|
|
class="form-input" |
|
|
placeholder="服务开始时间" |
|
|
placeholder="服务开始时间" |
|
|
@ -131,8 +131,8 @@ |
|
|
<label class="form-label required">服务结束时间</label> |
|
|
<label class="form-label required">服务结束时间</label> |
|
|
<a-date-picker |
|
|
<a-date-picker |
|
|
show-time |
|
|
show-time |
|
|
format="YYYY-MM-DD HH:00:00" |
|
|
format="YYYY-MM-DD HH:mm:ss" |
|
|
valueFormat="YYYY-MM-DD HH:00:00" |
|
|
valueFormat="YYYY-MM-DD HH:mm:ss" |
|
|
v-model:value="form.serviceEnd" |
|
|
v-model:value="form.serviceEnd" |
|
|
class="form-input" |
|
|
class="form-input" |
|
|
placeholder="服务结束时间" |
|
|
placeholder="服务结束时间" |
|
|
@ -145,12 +145,16 @@ |
|
|
服务时长(小时) |
|
|
服务时长(小时) |
|
|
<span style="color: #999; font-size: 12px; margin-left: 4px;">可通过时间选择也可手动填写</span> |
|
|
<span style="color: #999; font-size: 12px; margin-left: 4px;">可通过时间选择也可手动填写</span> |
|
|
</label> |
|
|
</label> |
|
|
<input |
|
|
<a-input-number |
|
|
v-model="form.serviceDuration" |
|
|
style="width: 100%" |
|
|
class="form-input" |
|
|
v-model:value="form.serviceDuration" |
|
|
placeholder="服务时长(小时)" |
|
|
placeholder="服务时长(小时)" |
|
|
|
|
|
:min="0" |
|
|
|
|
|
:precision="1" |
|
|
|
|
|
:parser="value => value.replace(/[^\d.]/g, '')" |
|
|
|
|
|
@blur="handleServiceDurationBlur" |
|
|
/> |
|
|
/> |
|
|
<div style="font-size: 12px; color: #f00d0d; margin-top: 6px;">注:不足30分钟(不含本数)的,按照0.5小时填报,超过30分钟不足1个小时的(含本数),按照一个小时填报</div> |
|
|
<div style="font-size: 12px; color: #f00d0d; margin-top: 6px;">注:不足30分钟(含30分钟)的,按照0.5小时填报,超过30分钟不足1小时的(含1小时),按照1小时填报</div> |
|
|
</div> |
|
|
</div> |
|
|
</template> |
|
|
</template> |
|
|
|
|
|
|
|
|
@ -248,7 +252,7 @@ |
|
|
<div class="form-item"> |
|
|
<div class="form-item"> |
|
|
<label class="form-label required"> |
|
|
<label class="form-label required"> |
|
|
服务内容描述 |
|
|
服务内容描述 |
|
|
<span style="font-size: 12px; color: #ff4d4f; margin-left: 8px;">内容描述需要包括的内容主要是时间、地点、主题、参与人员、服务内容、活动效果等</span> |
|
|
<span style="font-size: 12px; color: #f00d0dff; margin-left: 4px;">注:内容描述需要包括的内容主要是时间、地点、主题、参与人员、服务内容、活动效果等</span> |
|
|
</label> |
|
|
</label> |
|
|
<textarea |
|
|
<textarea |
|
|
v-model="form.serviceContent" |
|
|
v-model="form.serviceContent" |
|
|
@ -393,18 +397,54 @@ const form = reactive({ |
|
|
const currentActivity = ref({}); |
|
|
const currentActivity = ref({}); |
|
|
const currentActivityType = ref(''); |
|
|
const currentActivityType = ref(''); |
|
|
|
|
|
|
|
|
// 监听服务开始时间和结束时间变化,自动计算服务时长 |
|
|
// 服务时长格式化函数(修复计算逻辑) |
|
|
|
|
|
function formatServiceDuration(minutes) { |
|
|
|
|
|
if (minutes <= 30) { |
|
|
|
|
|
return 0.5; // 30分钟及以下按0.5小时 |
|
|
|
|
|
} else if (minutes <= 60) { |
|
|
|
|
|
return 1; // 超过30分钟但不超过60分钟按1小时 |
|
|
|
|
|
} else { |
|
|
|
|
|
// 超过1小时的,按实际小时数计算,但遵循同样的分钟规则 |
|
|
|
|
|
const hours = Math.floor(minutes / 60); |
|
|
|
|
|
const remainingMinutes = minutes % 60; |
|
|
|
|
|
|
|
|
|
|
|
if (remainingMinutes === 0) { |
|
|
|
|
|
return hours; // 整小时,直接返回小时数 |
|
|
|
|
|
} else if (remainingMinutes <= 30) { |
|
|
|
|
|
return hours + 0.5; // 剩余30分钟及以下加0.5小时 |
|
|
|
|
|
} else { |
|
|
|
|
|
return hours + 1; // 剩余超过30分钟加1小时 |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// 服务时长输入验证函数(用于手动输入,与PC端保持一致) |
|
|
|
|
|
function validateServiceDuration(hours) { |
|
|
|
|
|
if (hours === undefined || hours === null || isNaN(hours) || hours < 0) { |
|
|
|
|
|
return undefined; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// 将小时转换为分钟 |
|
|
|
|
|
const totalMinutes = Math.round(hours * 60); |
|
|
|
|
|
|
|
|
|
|
|
// 使用格式化函数计算正确的值 |
|
|
|
|
|
return formatServiceDuration(totalMinutes); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// 监听服务开始时间和结束时间变化,自动计算服务时长(与PC端保持一致) |
|
|
watch( |
|
|
watch( |
|
|
() => [form.serviceStart, form.serviceEnd], |
|
|
() => [form.serviceStart, form.serviceEnd], |
|
|
([startTime, endTime]) => { |
|
|
([startTime, endTime]) => { |
|
|
// 只有在非编辑模式下或当前活动类型为DICT时才自动计算服务时长 |
|
|
// 只有在当前活动类型为DICT时才自动计算服务时长(新增服务时isEditMode为false) |
|
|
if ((!isEditMode.value || currentActivityType.value === 'DICT') && (startTime && endTime)) { |
|
|
if (currentActivityType.value === 'DICT' && (startTime && endTime)) { |
|
|
const start = dayjs(startTime); |
|
|
const start = dayjs(startTime); |
|
|
const end = dayjs(endTime); |
|
|
const end = dayjs(endTime); |
|
|
if (end.isAfter(start)) { |
|
|
if (end.isAfter(start)) { |
|
|
// 计算时间差(分钟),然后转换为小时(保留2位小数) |
|
|
// 计算时间差(分钟) |
|
|
const durationMinutes = end.diff(start, 'minute'); |
|
|
const durationMinutes = end.diff(start, 'minute'); |
|
|
form.serviceDuration = parseFloat((durationMinutes / 60).toFixed(2)); |
|
|
|
|
|
|
|
|
// 根据规则计算服务时长(与PC端保持一致) |
|
|
|
|
|
form.serviceDuration = formatServiceDuration(durationMinutes); |
|
|
} else { |
|
|
} else { |
|
|
form.serviceDuration = undefined; |
|
|
form.serviceDuration = undefined; |
|
|
message.warning('服务结束时间必须晚于开始时间'); |
|
|
message.warning('服务结束时间必须晚于开始时间'); |
|
|
@ -417,6 +457,46 @@ watch( |
|
|
{ immediate: true } |
|
|
{ immediate: true } |
|
|
) |
|
|
) |
|
|
|
|
|
|
|
|
|
|
|
// 服务时长输入框blur事件处理(与PC端保持一致) |
|
|
|
|
|
function handleServiceDurationBlur() { |
|
|
|
|
|
const value = form.serviceDuration; |
|
|
|
|
|
|
|
|
|
|
|
// 当用户删除输入时,value会是null或undefined,允许这种情况 |
|
|
|
|
|
if (value === null || value === undefined) { |
|
|
|
|
|
return; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// 验证输入值是否为有效数字,防止异常输入 |
|
|
|
|
|
if (isNaN(value) || value < 0) { |
|
|
|
|
|
// 无效输入,清空并提示 |
|
|
|
|
|
form.serviceDuration = undefined; |
|
|
|
|
|
message.warning('请输入有效的服务时长'); |
|
|
|
|
|
return; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// 限制输入范围,防止异常值 |
|
|
|
|
|
if (value > 50) { |
|
|
|
|
|
form.serviceDuration = 50; |
|
|
|
|
|
message.warning('服务时长不能超过50小时'); |
|
|
|
|
|
return; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// 无论是否有时间选择,都对用户手动输入进行格式化验证 |
|
|
|
|
|
// 将小时转换为分钟进行验证 |
|
|
|
|
|
const inputMinutes = Math.round(value * 60); |
|
|
|
|
|
|
|
|
|
|
|
// 使用相同的格式化规则 |
|
|
|
|
|
const formattedDuration = formatServiceDuration(inputMinutes); |
|
|
|
|
|
|
|
|
|
|
|
// 如果格式化后的值与输入值不同,说明用户输入了不符合规则的值 |
|
|
|
|
|
if (Math.abs(formattedDuration - value) > 0.01) { |
|
|
|
|
|
// 提示用户并自动修正为符合规则的值 |
|
|
|
|
|
|
|
|
|
|
|
// 直接设置格式化后的值 |
|
|
|
|
|
form.serviceDuration = formattedDuration; |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
// 下拉选项数据 |
|
|
// 下拉选项数据 |
|
|
const positionList = ref([]) |
|
|
const positionList = ref([]) |
|
|
const activityCategoryList = ref([]) |
|
|
const activityCategoryList = ref([]) |
|
|
|