|
|
@ -49,7 +49,7 @@ |
|
|
|
>Select Device</router-link> |
|
|
|
>Select Device</router-link> |
|
|
|
</a-form-item> |
|
|
|
</a-form-item> |
|
|
|
<a-form-item v-if="planBody.dock_sn" style="margin-top: -15px;"> |
|
|
|
<a-form-item v-if="planBody.dock_sn" style="margin-top: -15px;"> |
|
|
|
<div class="panel" style="padding-top: 5px;" @click="selectDock(dock)"> |
|
|
|
<div class="panel" style="padding-top: 5px;"> |
|
|
|
<div class="title"> |
|
|
|
<div class="title"> |
|
|
|
<a-tooltip :title="dock.nickname"> |
|
|
|
<a-tooltip :title="dock.nickname"> |
|
|
|
<div class="pr10" style="width: 120px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden;">{{ dock.nickname }}</div> |
|
|
|
<div class="pr10" style="width: 120px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden;">{{ dock.nickname }}</div> |
|
|
@ -62,22 +62,64 @@ |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</a-form-item> |
|
|
|
</a-form-item> |
|
|
|
<!-- 任务类型 --> |
|
|
|
<!-- 任务类型 --> |
|
|
|
<a-form-item label="Plan Timer" class="plan-timer-form-item" :labelCol="{span: 23}"> |
|
|
|
<a-form-item label="Plan Timer" class="plan-timer-form-item"> |
|
|
|
<div style="white-space: nowrap;"> |
|
|
|
<div style="white-space: nowrap;"> |
|
|
|
<a-radio-group v-model:value="planBody.task_type" button-style="solid"> |
|
|
|
<a-radio-group v-model:value="planBody.task_type" button-style="solid"> |
|
|
|
<a-radio-button v-for="type in TaskTypeOptions" :value="type.value" :key="type.value">{{ type.label }}</a-radio-button> |
|
|
|
<a-radio-button v-for="type in TaskTypeOptions" :value="type.value" :key="type.value">{{ type.label }}</a-radio-button> |
|
|
|
</a-radio-group> |
|
|
|
</a-radio-group> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</a-form-item> |
|
|
|
</a-form-item> |
|
|
|
<!-- 执行时间 --> |
|
|
|
<!-- execute date --> |
|
|
|
<a-form-item label="Start Time" v-if="planBody.task_type === TaskType.Timed" name="select_execute_time" :labelCol="{span: 23}"> |
|
|
|
<a-form-item label="Date" v-if="planBody.task_type === TaskType.Timed || planBody.task_type === TaskType.Condition" name="select_execute_date" :labelCol="{span: 23}"> |
|
|
|
<a-date-picker |
|
|
|
<a-range-picker |
|
|
|
v-model:value="planBody.select_execute_time" |
|
|
|
v-model:value="planBody.select_execute_date" |
|
|
|
format="YYYY-MM-DD HH:mm:ss" |
|
|
|
:disabledDate="(current: Moment) => current < moment().subtract(1, 'days')" |
|
|
|
|
|
|
|
format="YYYY-MM-DD" |
|
|
|
|
|
|
|
:placeholder="['Start Time', 'End Time']" |
|
|
|
|
|
|
|
style="width: 100%;" |
|
|
|
|
|
|
|
/> |
|
|
|
|
|
|
|
</a-form-item> |
|
|
|
|
|
|
|
<!-- execute time --> |
|
|
|
|
|
|
|
<a-form-item label="Time" v-if="planBody.task_type === TaskType.Timed || planBody.task_type === TaskType.Condition" |
|
|
|
|
|
|
|
name="select_execute_time" ref="select_execute_time" :labelCol="{span: 23}" :autoLink="false"> |
|
|
|
|
|
|
|
<div class="mb10 flex-row flex-align-center flex-justify-around" v-for="n in planBody.select_time_number" :key="n"> |
|
|
|
|
|
|
|
<a-time-picker |
|
|
|
|
|
|
|
v-model:value="planBody.select_time[n - 1][0]" |
|
|
|
|
|
|
|
format="HH:mm:ss" |
|
|
|
show-time |
|
|
|
show-time |
|
|
|
placeholder="Select Time" |
|
|
|
placeholder="Start Time" |
|
|
|
|
|
|
|
:style="planBody.task_type === TaskType.Condition ? 'width: 40%' : 'width: 82%'" |
|
|
|
|
|
|
|
@change="() => $refs.select_execute_time.onFieldChange()" |
|
|
|
/> |
|
|
|
/> |
|
|
|
|
|
|
|
<template v-if="planBody.task_type === TaskType.Condition"> |
|
|
|
|
|
|
|
<div><span style="color: white;">-</span></div> |
|
|
|
|
|
|
|
<a-time-picker |
|
|
|
|
|
|
|
v-model:value="planBody.select_time[n - 1][1]" |
|
|
|
|
|
|
|
format="HH:mm:ss" |
|
|
|
|
|
|
|
show-time |
|
|
|
|
|
|
|
placeholder="End Time" |
|
|
|
|
|
|
|
style="width: 40%;" |
|
|
|
|
|
|
|
/> |
|
|
|
|
|
|
|
</template> |
|
|
|
|
|
|
|
<div class="ml5" style="font-size:18px"> |
|
|
|
|
|
|
|
<PlusCircleOutlined class="mr5" style="color: #1890ff" @click="addTime"/> |
|
|
|
|
|
|
|
<MinusCircleOutlined :style="planBody.select_time_number === 1 ? 'color: gray' : 'color: red;'" @click="removeTime"/> |
|
|
|
|
|
|
|
</div> |
|
|
|
|
|
|
|
</div> |
|
|
|
</a-form-item> |
|
|
|
</a-form-item> |
|
|
|
|
|
|
|
<template v-if="planBody.task_type === TaskType.Condition"> |
|
|
|
|
|
|
|
<!-- battery capacity --> |
|
|
|
|
|
|
|
<a-form-item label="Start task when battery level reaches" :labelCol="{span: 23}" name="min_battery_capacity"> |
|
|
|
|
|
|
|
<a-input-number class="width-100" v-model:value="planBody.min_battery_capacity" :min="50" :max="100" |
|
|
|
|
|
|
|
:formatter="(value: number) => `${value}%`" :parser="(value: string) => value.replace('%', '')"> |
|
|
|
|
|
|
|
</a-input-number> |
|
|
|
|
|
|
|
</a-form-item> |
|
|
|
|
|
|
|
<!-- storage capacity --> |
|
|
|
|
|
|
|
<a-form-item label="Start task when storage level reaches (MB)" :labelCol="{span: 23}" name="storage_capacity"> |
|
|
|
|
|
|
|
<a-input-number v-model:value="planBody.min_storage_capacity" class="width-100"> |
|
|
|
|
|
|
|
</a-input-number> |
|
|
|
|
|
|
|
</a-form-item> |
|
|
|
|
|
|
|
</template> |
|
|
|
<!-- RTH Altitude Relative to Dock --> |
|
|
|
<!-- RTH Altitude Relative to Dock --> |
|
|
|
<a-form-item label="RTH Altitude Relative to Dock (m)" :labelCol="{span: 23}" name="rth_altitude"> |
|
|
|
<a-form-item label="RTH Altitude Relative to Dock (m)" :labelCol="{span: 23}" name="rth_altitude"> |
|
|
|
<a-input-number v-model:value="planBody.rth_altitude" :min="20" :max="1500" class="width-100" required> |
|
|
|
<a-input-number v-model:value="planBody.rth_altitude" :min="20" :max="1500" class="width-100" required> |
|
|
@ -145,12 +187,16 @@ const disabled = ref(false) |
|
|
|
const routeName = ref('') |
|
|
|
const routeName = ref('') |
|
|
|
const planBody = reactive({ |
|
|
|
const planBody = reactive({ |
|
|
|
name: '', |
|
|
|
name: '', |
|
|
|
file_id: computed(() => store.state.waylineInfo.id), |
|
|
|
file_id: computed(() => store.state?.waylineInfo.id), |
|
|
|
dock_sn: computed(() => store.state.dockInfo.device_sn), |
|
|
|
dock_sn: computed(() => store.state?.dockInfo.device_sn), |
|
|
|
task_type: TaskType.Immediate, |
|
|
|
task_type: TaskType.Immediate, |
|
|
|
select_execute_time: undefined as Moment| undefined, |
|
|
|
select_execute_date: [moment(), moment()] as Moment[], |
|
|
|
|
|
|
|
select_time_number: 1, |
|
|
|
|
|
|
|
select_time: [[]] as Moment[][], |
|
|
|
rth_altitude: '', |
|
|
|
rth_altitude: '', |
|
|
|
out_of_control_action: OutOfControlAction.ReturnToHome, |
|
|
|
out_of_control_action: OutOfControlAction.ReturnToHome, |
|
|
|
|
|
|
|
min_battery_capacity: 90 as number, |
|
|
|
|
|
|
|
min_storage_capacity: undefined as number | undefined, |
|
|
|
}) |
|
|
|
}) |
|
|
|
|
|
|
|
|
|
|
|
const drawerVisible = ref(false) |
|
|
|
const drawerVisible = ref(false) |
|
|
@ -158,16 +204,35 @@ const valueRef = ref() |
|
|
|
const rules = { |
|
|
|
const rules = { |
|
|
|
name: [ |
|
|
|
name: [ |
|
|
|
{ required: true, message: 'Please enter plan name.' }, |
|
|
|
{ required: true, message: 'Please enter plan name.' }, |
|
|
|
{ max: 20, message: 'Length should be 1 to 20', trigger: 'blur' } |
|
|
|
{ max: 20, message: 'Length should be 1 to 20' } |
|
|
|
], |
|
|
|
], |
|
|
|
file_id: [{ required: true, message: 'Select Route' }], |
|
|
|
file_id: [{ required: true, message: 'Select Route' }], |
|
|
|
dock_sn: [{ required: true, message: 'Select Device' }], |
|
|
|
dock_sn: [{ required: true, message: 'Select Device' }], |
|
|
|
select_execute_time: [{ required: true, message: 'Select start time' }], |
|
|
|
select_execute_time: [{ |
|
|
|
|
|
|
|
validator: async (rule: RuleObject, value: Moment[]) => { |
|
|
|
|
|
|
|
validEndTime() |
|
|
|
|
|
|
|
validStartTime() |
|
|
|
|
|
|
|
if (planBody.select_time.length < planBody.select_time_number) { |
|
|
|
|
|
|
|
throw new Error('Select time') |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
validOverlapped() |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
}], |
|
|
|
|
|
|
|
select_execute_date: [{ required: true, message: 'Select date' }], |
|
|
|
rth_altitude: [ |
|
|
|
rth_altitude: [ |
|
|
|
{ |
|
|
|
{ |
|
|
|
validator: async (rule: RuleObject, value: string) => { |
|
|
|
validator: async (rule: RuleObject, value: string) => { |
|
|
|
if (!/^[0-9]{1,}$/.test(value)) { |
|
|
|
if (!/^[0-9]{1,}$/.test(value)) { |
|
|
|
throw new Error('RTH Altitude Relative Require number') |
|
|
|
throw new Error('RTH Altitude Require number') |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
], |
|
|
|
|
|
|
|
min_battery_capacity: [ |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
validator: async (rule: RuleObject, value: any) => { |
|
|
|
|
|
|
|
if (TaskType.Condition === planBody.task_type && !value) { |
|
|
|
|
|
|
|
throw new Error('Please enter battery capacity') |
|
|
|
} |
|
|
|
} |
|
|
|
}, |
|
|
|
}, |
|
|
|
} |
|
|
|
} |
|
|
@ -175,19 +240,61 @@ const rules = { |
|
|
|
out_of_control_action: [{ required: true, message: 'Select Lost Action' }], |
|
|
|
out_of_control_action: [{ required: true, message: 'Select Lost Action' }], |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function validStartTime (): Error | void { |
|
|
|
|
|
|
|
for (let i = 0; i < planBody.select_time.length; i++) { |
|
|
|
|
|
|
|
if (!planBody.select_time[i][0]) { |
|
|
|
|
|
|
|
throw new Error('Select start time') |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
function validEndTime (): Error | void { |
|
|
|
|
|
|
|
if (TaskType.Condition !== planBody.task_type) return |
|
|
|
|
|
|
|
for (let i = 0; i < planBody.select_time.length; i++) { |
|
|
|
|
|
|
|
if (!planBody.select_time[i][1]) { |
|
|
|
|
|
|
|
throw new Error('Select end time') |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if (planBody.select_time[i][0] && planBody.select_time[i][1].isSameOrBefore(planBody.select_time[i][0])) { |
|
|
|
|
|
|
|
throw new Error('End time should be later than start time') |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
function validOverlapped (): Error | void { |
|
|
|
|
|
|
|
if (TaskType.Condition !== planBody.task_type) return |
|
|
|
|
|
|
|
const arr = planBody.select_time.slice() |
|
|
|
|
|
|
|
arr.sort((a, b) => a[0].unix() - b[0].unix()) |
|
|
|
|
|
|
|
arr.forEach((v, i, arr) => { |
|
|
|
|
|
|
|
if (i > 0 && v[0] < arr[i - 1][1]) { |
|
|
|
|
|
|
|
throw new Error('Overlapping time periods.') |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
}) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
function onSubmit () { |
|
|
|
function onSubmit () { |
|
|
|
|
|
|
|
console.info(dock, '12131231') |
|
|
|
valueRef.value.validate().then(() => { |
|
|
|
valueRef.value.validate().then(() => { |
|
|
|
disabled.value = true |
|
|
|
disabled.value = true |
|
|
|
const createPlanBody = { ...planBody } as unknown as CreatePlan |
|
|
|
const createPlanBody = { ...planBody } as unknown as CreatePlan |
|
|
|
if (planBody.select_execute_time) { |
|
|
|
if (planBody.select_execute_date.length === 2) { |
|
|
|
createPlanBody.task_days = [moment(planBody.select_execute_time).unix()] |
|
|
|
createPlanBody.task_days = [] |
|
|
|
createPlanBody.task_periods = [createPlanBody.task_days] |
|
|
|
for (let i = planBody.select_execute_date[0]; i.isSameOrBefore(planBody.select_execute_date[1]); i.add(1, 'days')) { |
|
|
|
|
|
|
|
createPlanBody.task_days.push(i.unix()) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
createPlanBody.task_periods = [] |
|
|
|
|
|
|
|
if (TaskType.Immediate !== planBody.task_type) { |
|
|
|
|
|
|
|
for (let i = 0; i < planBody.select_time.length; i++) { |
|
|
|
|
|
|
|
const result = [] |
|
|
|
|
|
|
|
result.push(planBody.select_time[i][0].unix()) |
|
|
|
|
|
|
|
if (TaskType.Condition === planBody.task_type) { |
|
|
|
|
|
|
|
result.push(planBody.select_time[i][1].unix()) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
createPlanBody.task_periods.push(result) |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
createPlanBody.rth_altitude = Number(createPlanBody.rth_altitude) |
|
|
|
createPlanBody.rth_altitude = Number(createPlanBody.rth_altitude) |
|
|
|
if (wayline.value && wayline.value.template_types && wayline.value.template_types.length > 0) { |
|
|
|
if (wayline.value && wayline.value.template_types && wayline.value.template_types.length > 0) { |
|
|
|
createPlanBody.wayline_type = wayline.value.template_types[0] |
|
|
|
createPlanBody.wayline_type = wayline.value.template_types[0] |
|
|
|
} |
|
|
|
} |
|
|
|
// console.log('planBody', createPlanBody) |
|
|
|
|
|
|
|
createPlan(workspaceId, createPlanBody) |
|
|
|
createPlan(workspaceId, createPlanBody) |
|
|
|
.then(res => { |
|
|
|
.then(res => { |
|
|
|
disabled.value = false |
|
|
|
disabled.value = false |
|
|
@ -217,6 +324,18 @@ function selectDevice () { |
|
|
|
drawerVisible.value = true |
|
|
|
drawerVisible.value = true |
|
|
|
routeName.value = 'DockPanel' |
|
|
|
routeName.value = 'DockPanel' |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function addTime () { |
|
|
|
|
|
|
|
valueRef.value.validateFields(['select_execute_time']).then(() => { |
|
|
|
|
|
|
|
planBody.select_time_number++ |
|
|
|
|
|
|
|
planBody.select_time.push([]) |
|
|
|
|
|
|
|
}) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
function removeTime () { |
|
|
|
|
|
|
|
if (planBody.select_time_number === 1) return |
|
|
|
|
|
|
|
planBody.select_time_number-- |
|
|
|
|
|
|
|
planBody.select_time.splice(planBody.select_time_number) |
|
|
|
|
|
|
|
} |
|
|
|
</script> |
|
|
|
</script> |
|
|
|
|
|
|
|
|
|
|
|
<style lang="scss"> |
|
|
|
<style lang="scss"> |
|
|
@ -266,7 +385,7 @@ function selectDevice () { |
|
|
|
.ant-radio-button-wrapper{ |
|
|
|
.ant-radio-button-wrapper{ |
|
|
|
background-color: #232323; |
|
|
|
background-color: #232323; |
|
|
|
color: #fff; |
|
|
|
color: #fff; |
|
|
|
width: 80%; |
|
|
|
width: 33%; |
|
|
|
text-align: center; |
|
|
|
text-align: center; |
|
|
|
&.ant-radio-button-wrapper-checked{ |
|
|
|
&.ant-radio-button-wrapper-checked{ |
|
|
|
background-color: #1890ff; |
|
|
|
background-color: #1890ff; |
|
|
|