项目-抽屉组件封装、天气阻飞设置页面搭建以及功能完善
8 files modified
4 files added
| | |
| | | }, |
| | | "devDependencies": { |
| | | "@types/crypto-js": "^4.1.1", |
| | | "@types/lodash": "^4.14.197", |
| | | "@types/node": "^16.3.2", |
| | | "@types/urlencode": "^1.1.2", |
| | | "@typescript-eslint/eslint-plugin": "^5.8.1", |
| | |
| | | "license": "MIT" |
| | | }, |
| | | "node_modules/@types/lodash": { |
| | | "version": "4.14.178", |
| | | "resolved": "https://registry.npmmirror.com/@types/lodash/download/@types/lodash-4.14.178.tgz", |
| | | "integrity": "sha512-0d5Wd09ItQWH1qFbEyQ7oTQ3GZrMfth5JkbN3EvTKLXcHLRDSXeLnlvlOn0wvxVIwK5o2M8JzP/OWz7T3NRsbw==", |
| | | "license": "MIT" |
| | | "version": "4.14.197", |
| | | "resolved": "https://registry.npmmirror.com/@types/lodash/-/lodash-4.14.197.tgz", |
| | | "integrity": "sha512-BMVOiWs0uNxHVlHBgzTIqJYmj+PgCo4euloGF+5m4okL3rEYzM2EEv78mw8zWSMM57dM7kVIgJ2QDvwHSoCI5g==" |
| | | }, |
| | | "node_modules/@types/node": { |
| | | "version": "16.11.19", |
| | |
| | | "dev": true |
| | | }, |
| | | "@types/lodash": { |
| | | "version": "4.14.178", |
| | | "resolved": "https://registry.npmmirror.com/@types/lodash/download/@types/lodash-4.14.178.tgz", |
| | | "integrity": "sha512-0d5Wd09ItQWH1qFbEyQ7oTQ3GZrMfth5JkbN3EvTKLXcHLRDSXeLnlvlOn0wvxVIwK5o2M8JzP/OWz7T3NRsbw==" |
| | | "version": "4.14.197", |
| | | "resolved": "https://registry.npmmirror.com/@types/lodash/-/lodash-4.14.197.tgz", |
| | | "integrity": "sha512-BMVOiWs0uNxHVlHBgzTIqJYmj+PgCo4euloGF+5m4okL3rEYzM2EEv78mw8zWSMM57dM7kVIgJ2QDvwHSoCI5g==" |
| | | }, |
| | | "@types/node": { |
| | | "version": "16.11.19", |
| | |
| | | }, |
| | | "devDependencies": { |
| | | "@types/crypto-js": "^4.1.1", |
| | | "@types/lodash": "^4.14.197", |
| | | "@types/node": "^16.3.2", |
| | | "@types/urlencode": "^1.1.2", |
| | | "@typescript-eslint/eslint-plugin": "^5.8.1", |
| New file |
| | |
| | | <template> |
| | | <div class="drawer" :class="[show ? 'active':'none']" v-show="show"> |
| | | <div class="side-header"> |
| | | <div class="side-option flex-display flex-align-center flex-justify-between"> |
| | | <h2 class="title">{{ title }}</h2> |
| | | <CloseOutlined @click="close" /> |
| | | </div> |
| | | <div class="border-bottom"></div> |
| | | </div> |
| | | <slot></slot> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup lang="ts"> |
| | | import { defineProps, defineEmits } from 'vue' |
| | | import { CloseOutlined } from '@ant-design/icons-vue' |
| | | const porps = defineProps({ |
| | | show: { |
| | | type: Boolean, |
| | | default: false |
| | | }, |
| | | title: { |
| | | type: String, |
| | | required: true |
| | | } |
| | | }) |
| | | const emits = defineEmits(['update:show']) |
| | | const close = () => { |
| | | emits('update:show', false) |
| | | } |
| | | </script> |
| | | |
| | | <style scoped lang="scss"> |
| | | .active { |
| | | z-index: 1; |
| | | left: 100%; |
| | | } |
| | | .none { |
| | | z-index: -1; |
| | | left: 0; |
| | | } |
| | | .drawer { |
| | | position: absolute; |
| | | top: 0; |
| | | width: 100%; |
| | | height: 100%; |
| | | transition: all .5s; |
| | | box-shadow: -12px 0px 13px -6px rgba(0,0,0,0.1); |
| | | background: #232323; |
| | | |
| | | .side-header { |
| | | height: 60px; |
| | | font-size: 16px; |
| | | line-height: 60px; |
| | | box-sizing: border-box; |
| | | background-color: #232323; |
| | | border-bottom: 1px solid #4f4f4f; |
| | | |
| | | .side-option { |
| | | padding: 0 16px; |
| | | |
| | | .title { |
| | | color: $text-white-basic; |
| | | font-size: 18px; |
| | | margin: 0; |
| | | font-weight: 700; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | </style> |
| | |
| | | const emit = defineEmits(['update:modelValue', 'handleChange']) |
| | | type Option = { |
| | | label: string, |
| | | value: string |
| | | value: any |
| | | } |
| | | const props = defineProps({ |
| | | options: { |
| | | type: Object as () => Option[], |
| | | required: true, |
| | | }, |
| | | modelValue: String, |
| | | modelValue: [String, Number], |
| | | }) |
| | | const value = computed({ |
| | | get: () => props.modelValue, |
| New file |
| | |
| | | export function useVModel (props:any, propName:string, emit:any) { |
| | | return computed({ |
| | | get () { |
| | | return new Proxy(props[propName], { |
| | | get (target, key) { |
| | | return Reflect.get(target, key) |
| | | }, |
| | | set (target, key, value) { |
| | | emit('update:' + propName, { |
| | | ...target, |
| | | [key]: value |
| | | }) |
| | | return true |
| | | } |
| | | }) |
| | | }, |
| | | set (val) { |
| | | emit('update:' + propName, val) |
| | | } |
| | | }) |
| | | } |
| | |
| | | <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) { |
| New file |
| | |
| | | <template> |
| | | <div class="com_weather"> |
| | | <div class="option"> |
| | | <div class="option-item" :style="[model.projectBlocking[blocking.CLOUDBLOCKINGCONFIGENABLE]!==1?'border:none' : '']"> |
| | | <span class="mr10">云端天气组飞设置</span> |
| | | <a-switch :checkedValue="1" :unCheckedValue="2" v-model:checked="model.projectBlocking[blocking.CLOUDBLOCKINGCONFIGENABLE]" /> |
| | | <div v-if="model.projectBlocking[blocking.CLOUDBLOCKINGCONFIGENABLE]==1"> |
| | | <p class="mt10 describe">当风速或雨量大于设置值时,将对机场的飞行器进行阻飞。</p> |
| | | </div> |
| | | <div v-else> |
| | | <p class="mt10 describe">关闭后,机场的阻飞仍生效。</p> |
| | | <p class="mt10 describe">机场的阻飞条件:</p> |
| | | <p class="mt10 describe">风速 (风速计) ≥12m/s 或 雨量 (雨量计) ≥大雨 </p> |
| | | </div> |
| | | </div> |
| | | <div class="option-item" v-if="model.projectBlocking[blocking.CLOUDBLOCKINGCONFIGENABLE]==1"> |
| | | <span class="mr10">天气预报</span> |
| | | <a-switch :checkedValue="1" :unCheckedValue="2" v-model:checked="model.projectBlocking[blocking.WEATHERREPORTENABLE]" /> |
| | | <p class="mt10 describe">天气阻飞将使用天气预报,同时也会使用机场风速计和雨量计数据。</p> |
| | | </div> |
| | | <div class="option-item-edit" v-if="model.projectBlocking[blocking.CLOUDBLOCKINGCONFIGENABLE]==1"> |
| | | <a-form ref="weatherFormRef" :model="FormWeatherModel" :rules="weatherRules"> |
| | | <a-form-item :name="FormWeather.WINDSPEED" ref="windDevice"> |
| | | <div class="edit-item flex-display flex-align-center flex-justify-between"> |
| | | <div class="white-color">风速<span class="describe">(风速计) (1-12m/s)</span></div> |
| | | <div class="form-option flex-display flex-align-center white-color"> |
| | | <div :class="{ w48: edit }"> |
| | | <span v-if="!edit">{{ model.projectBlocking[FormWeather.WINDSPEED] }}</span> |
| | | <a-input v-else v-model:value.number="FormWeatherModel[FormWeather.WINDSPEED]"></a-input> |
| | | </div> |
| | | <span>m/s</span> |
| | | </div> |
| | | </div> |
| | | </a-form-item> |
| | | <a-form-item :name="FormWeather.WINDSPEEDREPORT" v-if="model.projectBlocking.weatherReportEnable"> |
| | | <div class="edit-item flex-display flex-align-center flex-justify-between"> |
| | | <div class="white-color">风速<span class="describe">(天气预报) (1-15m/s)</span></div> |
| | | <div class="form-option flex-display flex-align-center white-color"> |
| | | <div :class="{ w48: edit }"> |
| | | <span v-if="!edit">{{ model.projectBlocking[FormWeather.WINDSPEEDREPORT] }}</span> |
| | | <a-input v-else v-model:value.number="FormWeatherModel[FormWeather.WINDSPEEDREPORT]"></a-input> |
| | | </div> |
| | | <span>m/s</span> |
| | | </div> |
| | | </div> |
| | | </a-form-item> |
| | | <a-form-item :name="FormWeather.RAIN"> |
| | | <div class="edit-item flex-display flex-align-center flex-justify-between"> |
| | | <div class="white-color">雨量<span class="describe">(雨量计/天气预报)</span></div> |
| | | <div class="form-option flex-display flex-align-center white-color"> |
| | | <div :class="{ w60: edit }"> |
| | | <span v-if="!edit">{{ WeatherEnum[model.projectBlocking[FormWeather.RAIN]] }}</span> |
| | | <Select :bordered="false" :options="rainSelect" v-model='FormWeatherModel[FormWeather.RAIN]' v-else /> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </a-form-item> |
| | | </a-form> |
| | | <div class="btn-group" v-if="!edit"> |
| | | <a-button class="w96" type="primary" @click="() => edit = true">编辑</a-button> |
| | | </div> |
| | | <div class="btn-group" v-if="edit"> |
| | | <a-button class="mr20 w96" @click="cancel">取消</a-button> |
| | | <a-button class='w96' type="primary" @click="submit">保存</a-button> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup lang="ts"> |
| | | import { defineProps, defineEmits } from 'vue' |
| | | import { cloneDeep } from 'lodash' |
| | | import { blocking } from '../type' |
| | | import { weatherRules, FormWeather, rainSelect, WeatherEnum, } from './type' |
| | | import { ValidateErrorEntity } from 'ant-design-vue/es/form/interface' |
| | | import Select from '/@/components/Search/Select.vue' |
| | | import { useVModel } from '/@/hooks/use-v-model' |
| | | interface FormState { |
| | | [FormWeather.WINDSPEEDREPORT]: number |
| | | [FormWeather.WINDSPEED]: number |
| | | [FormWeather.RAIN]: number |
| | | } |
| | | const props = defineProps({ |
| | | modelValue: { |
| | | type: Object, |
| | | required: true |
| | | }, |
| | | }) |
| | | const emit = defineEmits(['update:modelValue']) |
| | | const model = useVModel(props, 'modelValue', emit) |
| | | const edit = ref(false) |
| | | const weatherFormRef = ref() |
| | | const FormWeatherModel = ref<FormState>(cloneDeep(model.value.projectBlocking)) |
| | | const submit = () => { |
| | | weatherFormRef.value |
| | | .validate() |
| | | .then(() => { |
| | | edit.value = false |
| | | model.value.projectBlocking = { ...model.value.projectBlocking, ...FormWeatherModel.value } |
| | | }) |
| | | .catch((error: ValidateErrorEntity<FormState>) => { |
| | | console.log('error', error) |
| | | }) |
| | | } |
| | | const cancel = () => { |
| | | FormWeatherModel.value = model.value.projectBlocking |
| | | edit.value = false |
| | | } |
| | | </script> |
| | | |
| | | <style scoped lang="scss"> |
| | | .com_weather { |
| | | padding: 16px; |
| | | |
| | | .option { |
| | | &-item { |
| | | border-bottom: 1px solid #4f4f4f; |
| | | margin-bottom: 16px; |
| | | } |
| | | |
| | | .form-option :deep(.ant-select-single .ant-select-selector) { |
| | | background-color: inherit !important; |
| | | color: #fff !important; |
| | | padding: 0 !important; |
| | | } |
| | | |
| | | .form-option :deep(.ant-select-arrow) { |
| | | color: #fff; |
| | | } |
| | | |
| | | // .form-option :deep(.) |
| | | } |
| | | } |
| | | </style> |
| New file |
| | |
| | | import { RuleObject, ValidateErrorEntity } from 'ant-design-vue/es/form/interface' |
| | | |
| | | export enum FormWeather { |
| | | WINDSPEED = 'windDevice', |
| | | WINDSPEEDREPORT = 'windWeatherReport', |
| | | RAIN = 'rain', |
| | | } |
| | | export enum WeatherEnum { |
| | | '小雨' = 1, |
| | | '中雨' = 2, |
| | | '大雨' = 3 |
| | | } |
| | | export const rainSelect = [ |
| | | { |
| | | label: '小雨', |
| | | value: 1, |
| | | }, |
| | | { |
| | | label: '中雨', |
| | | value: 2, |
| | | }, |
| | | { |
| | | label: '大雨', |
| | | value: 3, |
| | | }, |
| | | ] |
| | | // export interface FormWeatherState { |
| | | // [FormWeather.WINDSPEED]: number |
| | | // [FormWeather.WINDSPEEDREPORT]: number |
| | | // [FormWeather.RAIN]: string |
| | | // } |
| | | // export const formWeatherState = { |
| | | |
| | | // } |
| | | |
| | | export const weatherRules = { |
| | | [FormWeather.WINDSPEED]: [ |
| | | { required: true, type: 'number', message: '请输入风速', trigger: 'blur' }, |
| | | { min: 1, max: 12, type: 'number', message: '风速有效值在1-12m/s之间' }, |
| | | ], |
| | | [FormWeather.WINDSPEEDREPORT]: [ |
| | | { required: true, type: 'number', message: '请输入风速', trigger: 'blur' }, |
| | | { min: 1, max: 15, type: 'number', message: '风速有效值在1-15m/s之间' }, |
| | | ], |
| | | [FormWeather.RAIN]: [ |
| | | { required: true, message: '请选择雨量', type: 'number', trigger: 'blur' }, |
| | | ], |
| | | } |
| | |
| | | export enum FormProject{ |
| | | PROJECT_NAME = 'projectName', |
| | | PROJECT_STATUS = 'projectStatus', |
| | | PROJCECT_INTRO = 'projectIntro', |
| | | LONGITUDE = 'longitude', |
| | | LATITUDE = 'latitude', |
| | | DEVICELIST = 'deviceList', |
| | | USERLIST = 'userList', |
| | | PROJECT_BLOCKING = 'projectBlocking', |
| | | export enum FormProject { |
| | | PROJECT_NAME = 'projectName', |
| | | PROJECT_STATUS = 'projectStatus', |
| | | PROJCECT_INTRO = 'projectIntro', |
| | | LONGITUDE = 'longitude', |
| | | LATITUDE = 'latitude', |
| | | DEVICELIST = 'deviceList', |
| | | USERLIST = 'userList', |
| | | PROJECT_BLOCKING = 'projectBlocking', |
| | | } |
| | | enum weather{ |
| | | '开启'=1, |
| | | '关闭'=2 |
| | | export enum blocking { |
| | | WINDSPEED = 'windDevice', |
| | | WINDSPEEDREPORT = 'windWeatherReport', |
| | | RAIN = 'rain', |
| | | CLOUDBLOCKINGCONFIGENABLE = 'cloudBlockingConfigEnable', |
| | | WEATHERREPORTENABLE = 'weatherReportEnable', |
| | | } |
| | | enum weather { |
| | | '开启' = 1, |
| | | '关闭' = 2 |
| | | } |
| | | interface deviceList { |
| | | nickName:string |
| | | deviceSource:number |
| | | deviceType:number |
| | | [key:string]:any |
| | | nickName: string |
| | | deviceSource: number |
| | | deviceType: number |
| | | [key: string]: any |
| | | } |
| | | interface projectBlocking { |
| | | weatherBlockingConfigEnable:weather |
| | | cloudBlockingConfigEnable:weather |
| | | |
| | | [blocking.WEATHERREPORTENABLE]?: weather |
| | | [blocking.CLOUDBLOCKINGCONFIGENABLE]: weather |
| | | [blocking.WINDSPEED]?: number |
| | | [blocking.WINDSPEEDREPORT]?: number |
| | | [blocking.RAIN]?: number |
| | | } |
| | | export interface FormState { |
| | | [FormProject.PROJECT_NAME]: string |
| | | [FormProject.PROJECT_STATUS]:string |
| | | [FormProject.PROJCECT_INTRO]:string |
| | | [FormProject.LONGITUDE]:number |
| | | [FormProject.LATITUDE]:number |
| | | [FormProject.DEVICELIST]?:deviceList[] |
| | | [FormProject.USERLIST]:number[] |
| | | [FormProject.PROJECT_BLOCKING]?:{} |
| | | [FormProject.PROJECT_NAME]: string |
| | | [FormProject.PROJECT_STATUS]: string |
| | | [FormProject.PROJCECT_INTRO]: string |
| | | [FormProject.LONGITUDE]: number |
| | | [FormProject.LATITUDE]: number |
| | | [FormProject.DEVICELIST]?: deviceList[] |
| | | [FormProject.USERLIST]: number[] |
| | | [FormProject.PROJECT_BLOCKING]: projectBlocking |
| | | } |
| | | |
| | | /* |
| | | 项目成员表格 |
| | | */ |
| | | export const Usercolumns = [ |
| | | { |
| | | title: '人员项目呼号', |
| | | dataIndex: 'name', |
| | | key: 'name', |
| | | ellipsis: true, |
| | | slots: { customRender: 'name' }, |
| | | }, |
| | | { |
| | | title: '项目角色', |
| | | dataIndex: 'role', |
| | | key: 'role', |
| | | responsive: ['md'], |
| | | ellipsis: true, |
| | | slots: { customRender: 'role' }, |
| | | }, |
| | | { |
| | | title: '编辑', |
| | | dataIndex: 'edit', |
| | | key: 'edit', |
| | | responsive: ['lg'], |
| | | width: '24%', |
| | | ellipsis: true, |
| | | slots: { customRender: 'operation' }, |
| | | }, |
| | | ] |
| | | |
| | | export interface ProjectUser { |
| | | key: string; |
| | | name: string; |
| | | role: number; |
| | | } |
| | | |
| | | /* |
| | | 项目设备表格数据 |
| | | */ |
| | | export const Devicecolumns = [ |
| | | { |
| | | title: '项目设备呼号', |
| | | dataIndex: 'device', |
| | | key: 'device', |
| | | ellipsis: true, |
| | | slots: { customRender: 'device' }, |
| | | }, |
| | | { |
| | | title: '设备型号', |
| | | dataIndex: 'model', |
| | | key: 'model', |
| | | responsive: ['md'], |
| | | ellipsis: true, |
| | | slots: { customRender: 'model' }, |
| | | }, |
| | | { |
| | | title: '编辑', |
| | | dataIndex: 'edit', |
| | | key: 'edit', |
| | | responsive: ['lg'], |
| | | width: '24%', |
| | | ellipsis: true, |
| | | slots: { customRender: 'operation' }, |
| | | }, |
| | | ] |
| | | |
| | | export interface ProjectDevice { |
| | | key: string; |
| | | device: string; |
| | | model: string; |
| | | } |
| | | |
| | | // 校验表单规则 |
| | | export const rules = { |
| | | [FormProject.PROJECT_NAME]: [ |
| | | { required: true, message: '请输入项目名称', trigger: 'blur' }, |
| | | ], |
| | | } |
| | |
| | | .dis_opticy{ |
| | | opacity: .25; |
| | | } |
| | | .white-color { |
| | | color: #fff; |
| | | } |
| | | .describe{ |
| | | font-size: 12px; |
| | | color: hsla(0,0%,100%,.6); |
| | | } |
| | | body { |
| | | background-color: #f7f9fa; |
| | | -webkit-font-smoothing: antialiased; |
| | |
| | | margin-left: 10px !important; |
| | | } |
| | | |
| | | .w48 { |
| | | width: 48px; |
| | | } |
| | | |
| | | .w60 { |
| | | width: 60px; |
| | | } |
| | | .point { |
| | | cursor: pointer; |
| | | } |
| | | .w96 { |
| | | width: 96px; |
| | | } |
| | | |
| | | .mr10 { |
| | | margin-right: 10px !important; |
| | | } |
| | |
| | | "resolved" "https://registry.npm.taobao.org/@types/json5/download/@types/json5-0.0.29.tgz" |
| | | "version" "0.0.29" |
| | | |
| | | "@types/lodash@^4.14.165": |
| | | "integrity" "sha512-0d5Wd09ItQWH1qFbEyQ7oTQ3GZrMfth5JkbN3EvTKLXcHLRDSXeLnlvlOn0wvxVIwK5o2M8JzP/OWz7T3NRsbw==" |
| | | "resolved" "https://registry.npmmirror.com/@types/lodash/download/@types/lodash-4.14.178.tgz" |
| | | "version" "4.14.178" |
| | | "@types/lodash@^4.14.165", "@types/lodash@^4.14.197": |
| | | "integrity" "sha512-BMVOiWs0uNxHVlHBgzTIqJYmj+PgCo4euloGF+5m4okL3rEYzM2EEv78mw8zWSMM57dM7kVIgJ2QDvwHSoCI5g==" |
| | | "resolved" "https://registry.npmmirror.com/@types/lodash/-/lodash-4.14.197.tgz" |
| | | "version" "4.14.197" |
| | | |
| | | "@types/node@*", "@types/node@^16.3.2", "@types/node@>= 14", "@types/node@>=13.7.0": |
| | | "integrity" "sha512-BPAcfDPoHlRQNKktbsbnpACGdypPFBuX4xQlsWDE7B8XXcfII+SpOLay3/qZmCLb39kV5S1RTYwXdkx2lwLYng==" |