| | |
| | | <div class="project_add"> |
| | | <div class="side-header"> |
| | | <div class="side-option flex-display flex-align-center"> |
| | | <left-outlined :style="{ fontSize: '18px', marginRight: '8px' }" /> |
| | | <h2 class="title">创建项目</h2> |
| | | <left-outlined class="point" @click="goBack" :style="{ fontSize: '18px', marginRight: '8px' }" /> |
| | | <h2 class="title point" @click="goBack">创建项目</h2> |
| | | </div> |
| | | <div class="border-bottom"></div> |
| | | </div> |
| | | <div class="side-form-content"> |
| | | <a-form layout="vertical" :model="formState"> |
| | | <a-form-item label="项目名称"> |
| | | <a-form hideRequiredMark layout="vertical" :model="formState" :rules="rules" ref="projectForm"> |
| | | <a-form-item label="项目名称" :name="FormProject.PROJECT_NAME"> |
| | | <a-input v-model:value="formState[FormProject.PROJECT_NAME]" placeholder="项目名称" /> |
| | | </a-form-item> |
| | | <a-form-item label="项目简介"> |
| | | <a-form-item label="项目简介" :name="FormProject.PROJCECT_INTRO"> |
| | | <a-textarea :auto-size="{ minRows: 4, maxRows: 8 }" type="textarea" |
| | | v-model:value="formState[FormProject.PROJCECT_INTRO]" placeholder="项目简介" /> |
| | | </a-form-item> |
| | |
| | | <div class="application flex-display flex-align-center flex-justify-between"> |
| | | <p>天气阻飞设置</p> |
| | | <div class="btn"> |
| | | <a-button type="text" disabled> |
| | | <span class="button_name">未开启</span> |
| | | <a-button type="text" @click="openWeatherDrawer"> |
| | | <span class="button_name">{{formState.projectBlocking.cloudBlockingConfigEnable == 1 ? '已开启' : '未开启' }}</span> |
| | | <template #icon><right-outlined |
| | | :style="{ fontSize: '14px', color: '#fff', marginLeft: '8px' }" /></template> |
| | | </a-button> |
| | |
| | | </a-button> |
| | | </div> |
| | | </div> |
| | | <a-table :columns="columns" :data-source="dataSource" bordered> |
| | | <template v-for="col in ['name', 'age', 'address']" #[col]="{ text, record }" :key="col"> |
| | | <a-table class="ant-table-project" :columns="Usercolumns" :data-source="dataSource" bordered |
| | | :pagination="false" :rowClassName="() => 'project_dark'"> |
| | | <template v-for="col in ['name', 'role', 'edit']" #[col]="{ text, record }" :key="col"> |
| | | <div> |
| | | <a-input v-if="editableData[record.key]" v-model:value="editableData[record.key][col]" |
| | | style="margin: -5px 0" /> |
| | |
| | | <template #operation="{ record }"> |
| | | <div class="editable-row-operations"> |
| | | <span v-if="editableData[record.key]"> |
| | | <a @click="save(record.key)">Save</a> |
| | | <a-popconfirm title="Sure to cancel?" @confirm="cancel(record.key)"> |
| | | <a>Cancel</a> |
| | | </a-popconfirm> |
| | | <div class="flex-display flex-align-center flex-justify-between"> |
| | | <CheckOutlined :style="{ fontSize: '14px', color: '#28d445' }" |
| | | @click="save(record.key, 'editableData')" /> |
| | | <a-popconfirm title="确定取消?" ok-text="确定" cancel-text="取消" |
| | | @confirm="cancel(record.key, 'editableData')"> |
| | | <CloseOutlined :style="{ fontSize: '14px', color: '#e70102' }" /> |
| | | </a-popconfirm> |
| | | </div> |
| | | </span> |
| | | <span v-else> |
| | | <a @click="edit(record.key)">Edit</a> |
| | | <div class="flex-display flex-align-center flex-justify-between"> |
| | | <EditOutlined :style="{ fontSize: '14px', color: '#1180ff' }" |
| | | @click="edit(record.key, 'editableData')" /> |
| | | <DeleteOutlined :style="{ fontSize: '14px', color: '#e70102' }" |
| | | @click="del(record.key, 'editableData')" /> |
| | | </div> |
| | | </span> |
| | | </div> |
| | | </template> |
| | | </a-table> |
| | | </a-form-item> |
| | | <a-form-item> |
| | | <a-button type="primary">Submit</a-button> |
| | | <div class="application flex-display flex-align-center flex-justify-between"> |
| | | <p>项目设备</p> |
| | | <div> |
| | | <a-button type="text"> |
| | | <span class="button_add">添加飞行器</span> |
| | | <template #icon><plus-outlined :style="{ fontSize: '14px', color: '#2d8cf0' }" /></template> |
| | | </a-button> |
| | | </div> |
| | | </div> |
| | | <a-table class="ant-table-project" :columns="Devicecolumns" :data-source="deviceSource" bordered |
| | | :pagination="false" :rowClassName="() => 'project_dark'"> |
| | | <template v-for="col in ['name', 'role', 'edit']" #[col]="{ text, record }" :key="col"> |
| | | <div> |
| | | <a-input v-if="editDeviceData[record.key]" v-model:value="editDeviceData[record.key][col]" |
| | | style="margin: -5px 0" /> |
| | | <template v-else> |
| | | {{ text }} |
| | | </template> |
| | | </div> |
| | | </template> |
| | | <template #operation="{ record }"> |
| | | <div class="editable-row-operations"> |
| | | <span v-if="editDeviceData[record.key]"> |
| | | <div class="flex-display flex-align-center flex-justify-between"> |
| | | <CheckOutlined :style="{ fontSize: '14px', color: '#28d445' }" |
| | | @click="save(record.key, 'editDeviceData')" /> |
| | | <a-popconfirm title="确定取消?" ok-text="确定" cancel-text="取消" |
| | | @confirm="cancel(record.key, 'editDeviceData')"> |
| | | <CloseOutlined :style="{ fontSize: '14px', color: '#e70102' }" /> |
| | | </a-popconfirm> |
| | | </div> |
| | | </span> |
| | | <span v-else> |
| | | <div class="flex-display flex-align-center flex-justify-between"> |
| | | <EditOutlined :style="{ fontSize: '14px', color: '#1180ff' }" |
| | | @click="edit(record.key, 'editDeviceData')" /> |
| | | <DeleteOutlined :style="{ fontSize: '14px', color: '#e70102' }" |
| | | @click="del(record.key, 'editDeviceData')" /> |
| | | </div> |
| | | </span> |
| | | </div> |
| | | </template> |
| | | </a-table> |
| | | </a-form-item> |
| | | <a-form-item> |
| | | <div class="application flex-display flex-align-center flex-justify-between"> |
| | | <p>项目作业中心点</p> |
| | | <div> |
| | | <a-button type="text"> |
| | | <span class="button_add">设置项目中心点</span> |
| | | <template #icon> |
| | | <AimOutlined :style="{ fontSize: '14px', color: '#2d8cf0' }" /> |
| | | </template> |
| | | </a-button> |
| | | </div> |
| | | </div> |
| | | <div class="latitude">经纬度:35.6761919°N 139.65031.6°E</div> |
| | | </a-form-item> |
| | | </a-form> |
| | | <WeatherDrawer v-model:show="weatherDrawer" title="以下设置仅在当前项目中生效" > |
| | | <ComWeather v-model="formState" /> |
| | | </WeatherDrawer> |
| | | </div> |
| | | <div class="fix-button"> |
| | | <a-button @click="submit" style="width: 100%;height: 36px;justify-content: center;" class="flex-display flex-align-center" |
| | | type="primary">创建项目</a-button> |
| | | </div> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup lang="ts"> |
| | | import { LeftOutlined, RightOutlined, PlusOutlined } from '@ant-design/icons-vue' |
| | | import { FormState, FormProject } from './type' |
| | | import { LeftOutlined, RightOutlined, PlusOutlined, EditOutlined, DeleteOutlined, CheckOutlined, CloseOutlined, AimOutlined } from '@ant-design/icons-vue' |
| | | import { FormState, FormProject, Usercolumns, ProjectUser, Devicecolumns, ProjectDevice, rules, blocking } from './type' |
| | | import { UnwrapRef } from 'vue' |
| | | const columns = [ |
| | | { |
| | | title: '人员项目呼号', |
| | | dataIndex: 'name', |
| | | key: 'name', |
| | | }, |
| | | { |
| | | title: '项目角色', |
| | | dataIndex: 'role', |
| | | key: 'role', |
| | | responsive: ['md'], |
| | | }, |
| | | { |
| | | title: '编辑', |
| | | dataIndex: 'edit', |
| | | key: 'edit', |
| | | responsive: ['lg'], |
| | | }, |
| | | ] |
| | | interface DataItem { |
| | | key: string; |
| | | name: string; |
| | | role: number; |
| | | edit: string; |
| | | } |
| | | const dataSource = ref([ |
| | | { |
| | | key: '1', |
| | | name: '接口活', |
| | | role: '项目管理员' |
| | | } |
| | | ]) |
| | | const editableData: UnwrapRef<Record<string, DataItem>> = reactive({}) |
| | | import WeatherDrawer from '/@/components/Drawer/Drawer.vue' |
| | | import ComWeather from './components/WeatherDrawer.vue' |
| | | import { ValidateErrorEntity } from 'ant-design-vue/es/form/interface' |
| | | import { cloneDeep } from 'lodash' |
| | | import router from '/@/router' |
| | | const dataSource = ref([]) |
| | | const deviceSource = ref([]) |
| | | const weatherDrawer = ref(false) |
| | | const editableData: UnwrapRef<Record<string, ProjectUser>> = reactive({}) |
| | | const editDeviceData: UnwrapRef<Record<string, ProjectDevice>> = reactive({}) |
| | | const formState = ref<FormState>({ |
| | | [FormProject.PROJECT_NAME]: '', |
| | | [FormProject.PROJECT_NAME]: 'projectName', |
| | | [FormProject.PROJECT_STATUS]: '', |
| | | [FormProject.PROJCECT_INTRO]: '', |
| | | [FormProject.LONGITUDE]: 0, |
| | | [FormProject.LATITUDE]: 0, |
| | | [FormProject.USERLIST]: [] |
| | | [FormProject.USERLIST]: [], |
| | | [FormProject.PROJECT_BLOCKING]: { |
| | | [blocking.CLOUDBLOCKINGCONFIGENABLE]: 1, |
| | | [blocking.WEATHERREPORTENABLE]: 1, |
| | | [blocking.WINDSPEED]: 12, |
| | | [blocking.WINDSPEEDREPORT]: 15, |
| | | [blocking.RAIN]: 3 |
| | | } |
| | | }) |
| | | const projectForm = ref() |
| | | // 表格操作方法 |
| | | const edit = (key: string, type: string) => { |
| | | if (type === 'editableData') { |
| | | editableData[key] = cloneDeep(dataSource.value.filter(item => key === item.key)[0]) |
| | | } else { |
| | | editDeviceData[key] = cloneDeep(deviceSource.value.filter(item => key === item.key)[0]) |
| | | } |
| | | } |
| | | const save = (key: string, type: string) => { |
| | | if (type === 'editableData') { |
| | | Object.assign(dataSource.value.filter(item => key === item.key)[0], editableData[key]) |
| | | delete editableData[key] |
| | | } else { |
| | | Object.assign(deviceSource.value.filter(item => key === item.key)[0], editDeviceData[key]) |
| | | delete editDeviceData[key] |
| | | } |
| | | } |
| | | const cancel = (key: string, type: string) => { |
| | | if (type === 'editableData') { |
| | | delete editableData[key] |
| | | } else { |
| | | delete editDeviceData[key] |
| | | } |
| | | } |
| | | const del = (key: string, type: string) => { |
| | | console.log(key) |
| | | } |
| | | const goBack = () => { |
| | | router.go(-1) |
| | | } |
| | | // 天气组飞侧边栏 |
| | | const openWeatherDrawer = () => { |
| | | weatherDrawer.value = true |
| | | } |
| | | // 表单验证提交 |
| | | const submit = () => { |
| | | projectForm.value.validate().then(() => { |
| | | console.log('验证通过', formState) |
| | | }).catch((error:ValidateErrorEntity<FormState>) => { |
| | | console.log(error) |
| | | }) |
| | | } |
| | | </script> |
| | | |
| | | <style scoped lang="scss"> |
| | |
| | | flex-direction: column; |
| | | height: 100%; |
| | | color: #fff; |
| | | position: relative; |
| | | background-color: #232323; |
| | | |
| | | .side-header { |
| | |
| | | margin: 0; |
| | | } |
| | | } |
| | | |
| | | .latitude { |
| | | margin-top: 8px; |
| | | font-size: 12px; |
| | | line-height: 20px; |
| | | color: hsla(0, 0%, 100%, .45); |
| | | } |
| | | |
| | | .ant-table-project :deep(.project_dark) td { |
| | | background-color: #232323; |
| | | color: #fff; |
| | | border: none; |
| | | border-bottom: 1px solid #4f4f4f; |
| | | padding: 10px; |
| | | } |
| | | |
| | | .ant-table-project :deep(.ant-table-placeholder) { |
| | | background: #434343; |
| | | border: none !important; |
| | | } |
| | | |
| | | .ant-table-project :deep(.ant-table-thead) th { |
| | | background: #3c3c3c; |
| | | color: #fff; |
| | | border: 1px solid #4f4f4f; |
| | | padding: 10px; |
| | | } |
| | | |
| | | .ant-table-project :deep(.ant-table-body) table { |
| | | border: 1px solid #4f4f4f; |
| | | border-right: 1px solid #4f4f4f; |
| | | } |
| | | |
| | | .ant-table-project :deep(.ant-table-body) { |
| | | background: #434343; |
| | | } |
| | | |
| | | .ant-table-project :deep(.ant-empty-description) { |
| | | color: #fff; |
| | | } |
| | | } |
| | | |
| | | .fix-button { |
| | | position: sticky; |
| | | bottom: 0; |
| | | width: 100%; |
| | | padding: 16px; |
| | | border-top: 1px solid #4f4f4f; |
| | | } |
| | | |
| | | :deep(.ant-form-item-label > label) { |