项目列表和分包单位以及迁移人员
This commit is contained in:
		| @ -1,6 +1,6 @@ | |||||||
| import request from '@/utils/request'; | import request from '@/utils/request'; | ||||||
| import { AxiosPromise } from 'axios'; | import { AxiosPromise } from 'axios'; | ||||||
| import { ConstructionUserForm, ConstructionUserQuery, ConstructionUserVO } from '@/api/project/constructionUser/types'; | import { ConstructionUserForm, ConstructionUserQuery, ConstructionUserVO, skipType } from '@/api/project/constructionUser/types'; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * 查询施工人员列表 |  * 查询施工人员列表 | ||||||
| @ -27,6 +27,28 @@ export const getConstructionUser = (id: string | number): AxiosPromise<Construct | |||||||
|   }); |   }); | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * 人员迁移 | ||||||
|  |  * @param data | ||||||
|  |  */ | ||||||
|  | export const transferConstructionUser = (data: skipType) => { | ||||||
|  |   return request({ | ||||||
|  |     url: '/project/constructionUser/change/project', | ||||||
|  |     method: 'put', | ||||||
|  |     data: data | ||||||
|  |   }); | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * 查询项目以及项目下的分包公司列表 | ||||||
|  |  */ | ||||||
|  | export const getProjectContractorList = () => { | ||||||
|  |   return request({ | ||||||
|  |     url: '/project/project/list/project/contractorList', | ||||||
|  |     method: 'get' | ||||||
|  |   }); | ||||||
|  | }; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * 新增施工人员 |  * 新增施工人员 | ||||||
|  * @param data |  * @param data | ||||||
|  | |||||||
| @ -183,6 +183,46 @@ export interface ConstructionUserVO { | |||||||
|   createTime: string; |   createTime: string; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | export interface skipType { | ||||||
|  |   /** | ||||||
|  |    * 项目id | ||||||
|  |    */ | ||||||
|  |   projectId: string | number; | ||||||
|  |  | ||||||
|  |   /** | ||||||
|  |    * 分包id | ||||||
|  |    */ | ||||||
|  |   contractorId: string | number; | ||||||
|  |   id: string | number; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | export interface skipOptionType { | ||||||
|  |   /** | ||||||
|  |    * 名称 | ||||||
|  |    */ | ||||||
|  |   projectName: string | number; | ||||||
|  |  | ||||||
|  |   /** | ||||||
|  |    * id | ||||||
|  |    */ | ||||||
|  |   id: string | number; | ||||||
|  |   /** | ||||||
|  |    * 子项 | ||||||
|  |    */ | ||||||
|  |   contractorList: Array<skipTeamType>; | ||||||
|  | } | ||||||
|  | export interface skipTeamType { | ||||||
|  |   /** | ||||||
|  |    * 名称 | ||||||
|  |    */ | ||||||
|  |   name: string | number; | ||||||
|  |  | ||||||
|  |   /** | ||||||
|  |    * id | ||||||
|  |    */ | ||||||
|  |   id: string | number; | ||||||
|  | } | ||||||
|  |  | ||||||
| export interface ConstructionUserForm extends BaseEntity { | export interface ConstructionUserForm extends BaseEntity { | ||||||
|   /** |   /** | ||||||
|    * 主键id |    * 主键id | ||||||
|  | |||||||
| @ -51,6 +51,11 @@ export interface ContractorForm extends BaseEntity { | |||||||
|    */ |    */ | ||||||
|   id?: string | number; |   id?: string | number; | ||||||
|  |  | ||||||
|  |   /** | ||||||
|  |    * 主键id | ||||||
|  |    */ | ||||||
|  |   projectId?: string | number; | ||||||
|  |  | ||||||
|   /** |   /** | ||||||
|    * 公司名称 |    * 公司名称 | ||||||
|    */ |    */ | ||||||
|  | |||||||
| @ -37,12 +37,12 @@ export interface ProjectVO { | |||||||
|   /** |   /** | ||||||
|    * 项目类型 |    * 项目类型 | ||||||
|    */ |    */ | ||||||
|   type: string; |   projectType: string; | ||||||
|  |  | ||||||
|   /** |   /** | ||||||
|    * 项目类型(1光伏 2风电) |    * 项目类型(1光伏 2风电) | ||||||
|    */ |    */ | ||||||
|   isType: number; |   projectCategory: number; | ||||||
|  |  | ||||||
|   /** |   /** | ||||||
|    * 删除时间 |    * 删除时间 | ||||||
| @ -115,6 +115,18 @@ export interface ProjectVO { | |||||||
|   createTime: string; |   createTime: string; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | export interface locationType { | ||||||
|  |   /** | ||||||
|  |    * 经度 | ||||||
|  |    */ | ||||||
|  |   lng: string; | ||||||
|  |   // 纬度 | ||||||
|  |   lat: string; | ||||||
|  |   // 逆地理编码地址 | ||||||
|  |  | ||||||
|  |   projectSite: string; | ||||||
|  | } | ||||||
|  |  | ||||||
| export interface ProjectForm extends BaseEntity { | export interface ProjectForm extends BaseEntity { | ||||||
|   /** |   /** | ||||||
|    * |    * | ||||||
| @ -146,6 +158,16 @@ export interface ProjectForm extends BaseEntity { | |||||||
|    */ |    */ | ||||||
|   picUrl?: string; |   picUrl?: string; | ||||||
|  |  | ||||||
|  |   /** | ||||||
|  |    * 经度 | ||||||
|  |    */ | ||||||
|  |   lng?: string; | ||||||
|  |  | ||||||
|  |   /** | ||||||
|  |    * 纬度 | ||||||
|  |    */ | ||||||
|  |   lat?: string; | ||||||
|  |  | ||||||
|   /** |   /** | ||||||
|    * 备注 |    * 备注 | ||||||
|    */ |    */ | ||||||
| @ -154,12 +176,12 @@ export interface ProjectForm extends BaseEntity { | |||||||
|   /** |   /** | ||||||
|    * 项目类型 |    * 项目类型 | ||||||
|    */ |    */ | ||||||
|   type?: string; |   projectType?: string; | ||||||
|  |  | ||||||
|   /** |   /** | ||||||
|    * 项目类型(1光伏 2风电) |    * 项目类型(1光伏 2风电) | ||||||
|    */ |    */ | ||||||
|   isType?: number; |   projectCategory?: number; | ||||||
|  |  | ||||||
|   /** |   /** | ||||||
|    * 删除时间 |    * 删除时间 | ||||||
| @ -197,9 +219,14 @@ export interface ProjectForm extends BaseEntity { | |||||||
|   onStreamTime?: string; |   onStreamTime?: string; | ||||||
|  |  | ||||||
|   /** |   /** | ||||||
|    * 打卡范围(09:00,18:00) |    * 打卡开始时间(09:00,18:00) | ||||||
|    */ |    */ | ||||||
|   punchRange?: string; |   playCardStart?: string; | ||||||
|  |  | ||||||
|  |   /** | ||||||
|  |    * 打卡结束时间(09:00,18:00) | ||||||
|  |    */ | ||||||
|  |   playCardEnd?: string; | ||||||
|  |  | ||||||
|   /** |   /** | ||||||
|    * 设计总量 |    * 设计总量 | ||||||
| @ -256,12 +283,12 @@ export interface ProjectQuery extends PageQuery { | |||||||
|   /** |   /** | ||||||
|    * 项目类型 |    * 项目类型 | ||||||
|    */ |    */ | ||||||
|   type?: string; |   projectType?: string; | ||||||
|  |  | ||||||
|   /** |   /** | ||||||
|    * 项目类型(1光伏 2风电) |    * 项目类型(1光伏 2风电) | ||||||
|    */ |    */ | ||||||
|   isType?: number; |   projectCategory?: number; | ||||||
|  |  | ||||||
|   /** |   /** | ||||||
|    * 删除时间 |    * 删除时间 | ||||||
| @ -273,6 +300,16 @@ export interface ProjectQuery extends PageQuery { | |||||||
|    */ |    */ | ||||||
|   projectSite?: string; |   projectSite?: string; | ||||||
|  |  | ||||||
|  |   /** | ||||||
|  |    * 经度 | ||||||
|  |    */ | ||||||
|  |   lng?: string; | ||||||
|  |  | ||||||
|  |   /** | ||||||
|  |    * 纬度 | ||||||
|  |    */ | ||||||
|  |   lat?: string; | ||||||
|  |  | ||||||
|   /** |   /** | ||||||
|    * 负责人 |    * 负责人 | ||||||
|    */ |    */ | ||||||
| @ -299,9 +336,14 @@ export interface ProjectQuery extends PageQuery { | |||||||
|   onStreamTime?: string; |   onStreamTime?: string; | ||||||
|  |  | ||||||
|   /** |   /** | ||||||
|    * 打卡范围(09:00,18:00) |    * 打卡开始时间(09:00,18:00) | ||||||
|    */ |    */ | ||||||
|   punchRange?: string; |   playCardStart?: string; | ||||||
|  |  | ||||||
|  |   /** | ||||||
|  |    * 打卡结束时间(09:00,18:00) | ||||||
|  |    */ | ||||||
|  |   playCardEnd?: string; | ||||||
|  |  | ||||||
|   /** |   /** | ||||||
|    * 设计总量 |    * 设计总量 | ||||||
|  | |||||||
							
								
								
									
										136
									
								
								src/components/amap/index.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										136
									
								
								src/components/amap/index.vue
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,136 @@ | |||||||
|  | <template> | ||||||
|  |   <div class="map"> | ||||||
|  |     <input type="text" placeholder="请输入地址" v-model="searchValue" /> | ||||||
|  |     <button @click="onSearch">搜索</button> | ||||||
|  |     <div id="container" :style="{ 'height': mapProps.height }"></div> | ||||||
|  |  | ||||||
|  |     <div id="my-panel" @listElementClick="selectPostion"></div> | ||||||
|  |     <div class="flex justify-end"> | ||||||
|  |       <el-button type="primary" @click="submit"> 确定 </el-button> | ||||||
|  |       <el-button @click="emit('setLocation')">取消</el-button> | ||||||
|  |     </div> | ||||||
|  |   </div> | ||||||
|  | </template> | ||||||
|  | <script setup> | ||||||
|  | import { onMounted, onUnmounted } from 'vue'; | ||||||
|  | import AMapLoader from '@amap/amap-jsapi-loader'; | ||||||
|  | const { proxy } = getCurrentInstance(); | ||||||
|  | //props参数 | ||||||
|  | const mapProps = defineProps({ | ||||||
|  |   height: { | ||||||
|  |     type: String, | ||||||
|  |     default: '800px' | ||||||
|  |   } | ||||||
|  | }); | ||||||
|  | const emit = defineEmits(['setLocation']); | ||||||
|  | const center = ref([116.397428, 39.90923]); | ||||||
|  | const map = ref(null); | ||||||
|  | const placeSearch = ref(null); | ||||||
|  | const geocoder = ref(null); | ||||||
|  | const searchValue = ref(''); | ||||||
|  | const lnglat = ref([]); | ||||||
|  | onMounted(() => { | ||||||
|  |   window._AMapSecurityConfig = { | ||||||
|  |     securityJsCode: '3f418182f27c907265f69a708c5fa41c' | ||||||
|  |   }; | ||||||
|  |   AMapLoader.load({ | ||||||
|  |     key: 'ed8d05ca57affee582e2be654bac5baf', // 申请好的Web端开发者Key,首次调用 load 时必填 | ||||||
|  |     version: '2.0', // 指定要加载的 JSAPI 的版本,缺省时默认为 1.4.15 | ||||||
|  |     plugins: ['AMap.Scale', 'AMap.AutoComplete', 'AMap.PlaceSearch', 'AMap.Geolocation', 'AMap.Geocoder'] //需要使用的的插件列表,如比例尺'AMap.Scale',支持添加多个如:['...','...'] | ||||||
|  |   }) | ||||||
|  |     .then((AMap) => { | ||||||
|  |       map.value = new AMap.Map('container', { | ||||||
|  |         // 设置地图容器id | ||||||
|  |         viewMode: '3D', // 是否为3D地图模式 | ||||||
|  |         zoom: 8, // 初始化地图级别 | ||||||
|  |         center: center.value // 初始化地图中心点位置 | ||||||
|  |       }); | ||||||
|  |       //初始化搜索 | ||||||
|  |       placeSearch.value = new AMap.PlaceSearch({ | ||||||
|  |         pageSize: 5, //单页显示结果条数 | ||||||
|  |         // pageIndex: 1, //页码 | ||||||
|  |         // city: '010', //兴趣点城市 | ||||||
|  |         // citylimit: true, //是否强制限制在设置的城市内搜索 | ||||||
|  |         panel: 'my-panel', | ||||||
|  |         map: map.value, //展现结果的地图实例 | ||||||
|  |         autoFitView: true //是否自动调整地图视野使绘制的 Marker 点都处于视口的可见范围 | ||||||
|  |       }); | ||||||
|  |       // 初始化Geocoder | ||||||
|  |       geocoder.value = new AMap.Geocoder({ | ||||||
|  |         radius: 1000 //范围,默认:500 | ||||||
|  |       }); | ||||||
|  |  | ||||||
|  |       // 定位 | ||||||
|  |       const geolocation = new AMap.Geolocation({ | ||||||
|  |         enableHighAccuracy: true, //是否使用高精度定位,默认:true | ||||||
|  |         timeout: 10000, //超过10秒后停止定位,默认:无穷大 | ||||||
|  |         maximumAge: 0, //定位结果缓存0毫秒,默认:0 | ||||||
|  |         convert: true, //自动偏移坐标,偏移后的坐标为高德坐标,默认:true | ||||||
|  |         showButton: true, //显示定位按钮,默认:true | ||||||
|  |         buttonPosition: 'LB', //定位按钮停靠位置,默认:'LB',左下角 | ||||||
|  |         buttonOffset: new AMap.Pixel(10, 20), //定位按钮与设置的停靠位置的偏移量,默认:Pixel(10, 20) | ||||||
|  |         showMarker: true, //定位成功后在定位到的位置显示点标记,默认:true | ||||||
|  |         showCircle: true, //定位成功后用圆圈表示定位精度范围,默认:true | ||||||
|  |         panToLocation: true, //定位成功后将定位到的位置作为地图中心点,默认:true | ||||||
|  |         zoomToAccuracy: true //定位成功后调整地图视野范围使定位位置及精度范围视野内可见,默认:false | ||||||
|  |       }); | ||||||
|  |       map.value.addControl(geolocation); | ||||||
|  |  | ||||||
|  |       //定位到当前位置 | ||||||
|  |       geolocation.getCurrentPosition((status, result) => { | ||||||
|  |         console.log(status, result); | ||||||
|  |       }); | ||||||
|  |       placeSearch.value.on('selectChanged', (e) => { | ||||||
|  |         let { lng, lat } = e.selected.data.location; | ||||||
|  |         lnglat.value = [lng, lat]; | ||||||
|  |       }); | ||||||
|  |     }) | ||||||
|  |     .catch((e) => { | ||||||
|  |       console.log(e); | ||||||
|  |     }); | ||||||
|  | }); | ||||||
|  | const onSearch = () => { | ||||||
|  |   //搜索地址 | ||||||
|  |   placeSearch.value.search(searchValue.value, (status, result) => { | ||||||
|  |     if (result.info !== 'OK') return; | ||||||
|  |     let { lng, lat } = result.poiList.pois[0].location; | ||||||
|  |     lnglat.value = [lng, lat]; | ||||||
|  |   }); | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | const submit = () => { | ||||||
|  |   if (!lnglat.value.length) { | ||||||
|  |     proxy?.$modal.msgWarning('请选择正确地址'); | ||||||
|  |     return; | ||||||
|  |   } | ||||||
|  |   geocoder.value.getAddress(lnglat.value, function (status, result) { | ||||||
|  |     if (status === 'complete' && result.info === 'OK') { | ||||||
|  |       // result为对应的地理位置详细信息 | ||||||
|  |       const position = { | ||||||
|  |         lng: lnglat.value[0], | ||||||
|  |         lat: lnglat.value[1], | ||||||
|  |         projectSite: result.regeocode.formattedAddress | ||||||
|  |       }; | ||||||
|  |       emit('setLocation', position); | ||||||
|  |     } | ||||||
|  |   }); | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | onUnmounted(() => { | ||||||
|  |   map.value?.destroy(); | ||||||
|  | }); | ||||||
|  | </script> | ||||||
|  |  | ||||||
|  | <style scoped lang="scss"> | ||||||
|  | #container { | ||||||
|  |   width: 100%; | ||||||
|  |   position: relative; | ||||||
|  |   margin-bottom: 15px; | ||||||
|  | } | ||||||
|  | #my-panel { | ||||||
|  |   position: absolute; | ||||||
|  |   top: 103px; | ||||||
|  |   z-index: 1; | ||||||
|  |   left: 10px; | ||||||
|  | } | ||||||
|  | </style> | ||||||
| @ -115,6 +115,9 @@ | |||||||
|               <el-button link type="danger" icon="Avatar" @click="handleJoinBlacklist(scope.row)" v-hasPermi="['project:constructionBlacklist:add']"> |               <el-button link type="danger" icon="Avatar" @click="handleJoinBlacklist(scope.row)" v-hasPermi="['project:constructionBlacklist:add']"> | ||||||
|                 黑名单 |                 黑名单 | ||||||
|               </el-button> |               </el-button> | ||||||
|  |               <el-button link type="primary" icon="Switch" @click="handleChange(scope.row)" v-hasPermi="['project:constructionBlacklist:add']"> | ||||||
|  |                 人员迁移 | ||||||
|  |               </el-button> | ||||||
|               <el-button link type="danger" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['project:constructionUser:remove']"> |               <el-button link type="danger" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['project:constructionUser:remove']"> | ||||||
|                 删除 |                 删除 | ||||||
|               </el-button> |               </el-button> | ||||||
| @ -265,6 +268,24 @@ | |||||||
|     <el-dialog title="施工人员详情" v-model="showDetailDrawer"> |     <el-dialog title="施工人员详情" v-model="showDetailDrawer"> | ||||||
|       <construction-user-detail :user-id="currentUserId" /> |       <construction-user-detail :user-id="currentUserId" /> | ||||||
|     </el-dialog> |     </el-dialog> | ||||||
|  |     <el-dialog :title="skipName + '-人员迁移'" v-model="skip" width="500px"> | ||||||
|  |       <el-form-item label="所属项目" label-width="130px"> | ||||||
|  |         <el-select v-model="skipObject.projectId" @change="selectProject" placeholder="请选择所属项目" style="width: 240px"> | ||||||
|  |           <el-option v-for="item in skipOptions" :key="item.id" :label="item.projectName" :value="item.id" /> | ||||||
|  |         </el-select> | ||||||
|  |       </el-form-item> | ||||||
|  |       <el-form-item label="分包单位" label-width="130px"> | ||||||
|  |         <el-select v-model="skipObject.contractorId" :disabled="!skipObject.projectId" placeholder="请选择分包单位" style="width: 240px"> | ||||||
|  |           <el-option v-for="item in contractorList" :key="item.id" :label="item.name" :value="item.id" /> | ||||||
|  |         </el-select> | ||||||
|  |       </el-form-item> | ||||||
|  |       <template #footer> | ||||||
|  |         <div class="dialog-footer"> | ||||||
|  |           <el-button type="primary" @click="setUnits">确认</el-button> | ||||||
|  |           <el-button @click="skip = false"> 取消 </el-button> | ||||||
|  |         </div> | ||||||
|  |       </template> | ||||||
|  |     </el-dialog> | ||||||
|   </div> |   </div> | ||||||
| </template> | </template> | ||||||
|  |  | ||||||
| @ -274,9 +295,18 @@ import { | |||||||
|   delConstructionUser, |   delConstructionUser, | ||||||
|   getConstructionUser, |   getConstructionUser, | ||||||
|   listConstructionUser, |   listConstructionUser, | ||||||
|   updateConstructionUser |   updateConstructionUser, | ||||||
|  |   getProjectContractorList, | ||||||
|  |   transferConstructionUser | ||||||
| } from '@/api/project/constructionUser'; | } from '@/api/project/constructionUser'; | ||||||
| import { ConstructionUserForm, ConstructionUserQuery, ConstructionUserVO } from '@/api/project/constructionUser/types'; | import { | ||||||
|  |   ConstructionUserForm, | ||||||
|  |   ConstructionUserQuery, | ||||||
|  |   ConstructionUserVO, | ||||||
|  |   skipType, | ||||||
|  |   skipOptionType, | ||||||
|  |   skipTeamType | ||||||
|  | } from '@/api/project/constructionUser/types'; | ||||||
| import { useUserStoreHook } from '@/store/modules/user'; | import { useUserStoreHook } from '@/store/modules/user'; | ||||||
| import { listContractor } from '@/api/project/contractor'; | import { listContractor } from '@/api/project/contractor'; | ||||||
| import { listProjectTeam } from '@/api/project/projectTeam'; | import { listProjectTeam } from '@/api/project/projectTeam'; | ||||||
| @ -300,15 +330,25 @@ const ids = ref<Array<string | number>>([]); | |||||||
| const single = ref(true); | const single = ref(true); | ||||||
| const multiple = ref(true); | const multiple = ref(true); | ||||||
| const total = ref(0); | const total = ref(0); | ||||||
|  | const skip = ref(false); | ||||||
| const queryFormRef = ref<ElFormInstance>(); | const queryFormRef = ref<ElFormInstance>(); | ||||||
| const constructionUserFormRef = ref<ElFormInstance>(); | const constructionUserFormRef = ref<ElFormInstance>(); | ||||||
|  | const skipName = ref(''); | ||||||
| const dialog = reactive<DialogOption>({ | const dialog = reactive<DialogOption>({ | ||||||
|   visible: false, |   visible: false, | ||||||
|   title: '' |   title: '' | ||||||
| }); | }); | ||||||
|  |  | ||||||
|  | //人员迁移条件 | ||||||
|  | const skipObject: skipType = reactive({ | ||||||
|  |   id: '', | ||||||
|  |   projectId: '', | ||||||
|  |   contractorId: '' | ||||||
|  | }); | ||||||
|  | const contractorList = ref<Array<skipTeamType>>([]); | ||||||
|  | //项目列表 | ||||||
|  | const skipOptions = ref<Array<skipOptionType>>([]); | ||||||
|  |  | ||||||
| const initFormData: ConstructionUserForm = { | const initFormData: ConstructionUserForm = { | ||||||
|   id: undefined, |   id: undefined, | ||||||
|   openid: undefined, |   openid: undefined, | ||||||
| @ -392,6 +432,21 @@ const getList = async () => { | |||||||
|   loading.value = false; |   loading.value = false; | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | const selectProject = (e: any) => { | ||||||
|  |   //选中项目筛选出项目下的分包单位 | ||||||
|  |   contractorList.value = skipOptions.value.filter((item) => item.id == e)[0].contractorList; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | const setUnits = async () => { | ||||||
|  |   //人员迁移 | ||||||
|  |   console.log('🚀 ~ setUnits ~ skipObject:', skipObject); | ||||||
|  |   let res = await transferConstructionUser(skipObject); | ||||||
|  |   if (res.code == 200) { | ||||||
|  |     ElMessage.success(res.msg); | ||||||
|  |     skip.value = false; | ||||||
|  |     getList(); | ||||||
|  |   } | ||||||
|  | }; | ||||||
| const contractorOpt = ref(); | const contractorOpt = ref(); | ||||||
|  |  | ||||||
| /** 查询当前项目下的分包公司列表 */ | /** 查询当前项目下的分包公司列表 */ | ||||||
| @ -489,6 +544,16 @@ const handleShowDrawer = (row?: ConstructionUserVO) => { | |||||||
|   showDetailDrawer.value = true; |   showDetailDrawer.value = true; | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | /** 人员迁移 */ | ||||||
|  | const handleChange = async (row: ConstructionUserVO) => { | ||||||
|  |   const _id = row?.id || ids.value[0]; | ||||||
|  |   skipName.value = row?.userName; | ||||||
|  |   skipObject.id = _id; | ||||||
|  |   const res = await getProjectContractorList(); | ||||||
|  |   skipOptions.value = res.data; | ||||||
|  |   skip.value = true; | ||||||
|  | }; | ||||||
|  |  | ||||||
| /** 提交按钮 */ | /** 提交按钮 */ | ||||||
| const submitForm = () => { | const submitForm = () => { | ||||||
|   constructionUserFormRef.value?.validate(async (valid: boolean) => { |   constructionUserFormRef.value?.validate(async (valid: boolean) => { | ||||||
|  | |||||||
| @ -122,16 +122,6 @@ const contractorFormRef = ref<ElFormInstance>(); | |||||||
| const userStore = useUserStoreHook(); | const userStore = useUserStoreHook(); | ||||||
| // 从 store 中获取项目列表和当前选中的项目 | // 从 store 中获取项目列表和当前选中的项目 | ||||||
| const currentProject = computed(() => userStore.selectedProject); | const currentProject = computed(() => userStore.selectedProject); | ||||||
| //监听项目改变 |  | ||||||
| // watch( |  | ||||||
| //   () => currentProject.value, |  | ||||||
| //   (newId, oldId) => { |  | ||||||
| //     /* ... */ |  | ||||||
| //     queryParams.value.projectId=newId.id |  | ||||||
| //     // getList() |  | ||||||
|      |  | ||||||
| //   } |  | ||||||
| // ) |  | ||||||
| const dialog = reactive<DialogOption>({ | const dialog = reactive<DialogOption>({ | ||||||
|   visible: false, |   visible: false, | ||||||
|   title: '' |   title: '' | ||||||
| @ -145,7 +135,8 @@ const initFormData: ContractorForm = { | |||||||
|   custodian: undefined, |   custodian: undefined, | ||||||
|   custodianPhone: undefined, |   custodianPhone: undefined, | ||||||
|   fileMap: undefined, |   fileMap: undefined, | ||||||
|   remark: undefined |   remark: undefined, | ||||||
|  |   projectId: currentProject.value.id | ||||||
| }; | }; | ||||||
| const data = reactive<PageData<ContractorForm, ContractorQuery>>({ | const data = reactive<PageData<ContractorForm, ContractorQuery>>({ | ||||||
|   form: { ...initFormData }, |   form: { ...initFormData }, | ||||||
|  | |||||||
| @ -52,10 +52,14 @@ | |||||||
|             <dict-tag :options="sys_normal_disable" :value="scope.row.status" /> |             <dict-tag :options="sys_normal_disable" :value="scope.row.status" /> | ||||||
|           </template> |           </template> | ||||||
|         </el-table-column> |         </el-table-column> | ||||||
|         <el-table-column label="项目类型" align="center" prop="type" /> |         <el-table-column label="项目类型" align="center" prop="projectType"> | ||||||
|         <el-table-column label="项目类别" align="center" prop="isType"> |  | ||||||
|           <template #default="scope"> |           <template #default="scope"> | ||||||
|             <dict-tag :options="project_category_type" :value="scope.row.isType" /> |             <dict-tag :options="project_type" :value="scope.row.projectType" /> | ||||||
|  |           </template> | ||||||
|  |         </el-table-column> | ||||||
|  |         <el-table-column label="项目类别" align="center" prop="projectCategory"> | ||||||
|  |           <template #default="scope"> | ||||||
|  |             <dict-tag :options="project_category_type" :value="scope.row.projectCategory" /> | ||||||
|           </template> |           </template> | ||||||
|         </el-table-column> |         </el-table-column> | ||||||
|         <el-table-column label="项目地址" align="center" prop="projectSite" /> |         <el-table-column label="项目地址" align="center" prop="projectSite" /> | ||||||
| @ -82,44 +86,136 @@ | |||||||
|       <pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" /> |       <pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" /> | ||||||
|     </el-card> |     </el-card> | ||||||
|     <!-- 添加或修改项目对话框 --> |     <!-- 添加或修改项目对话框 --> | ||||||
|     <el-dialog :title="dialog.title" v-model="dialog.visible" width="500px" append-to-body> |     <el-dialog :title="dialog.title" v-model="dialog.visible" width="770px" append-to-body> | ||||||
|       <el-form ref="projectFormRef" :model="form" :rules="rules" label-width="100px"> |       <el-form ref="projectFormRef" :model="form" :rules="rules" label-width="100px"> | ||||||
|         <el-form-item label="项目名称" prop="projectName"> |         <div class="block-box"> | ||||||
|           <el-input v-model="form.projectName" placeholder="请输入项目名称" /> |           <div class="">基础信息</div> | ||||||
|         </el-form-item> |           <el-row :gutter="20"> | ||||||
|         <el-form-item label="项目简称" prop="shortName"> |             <el-col :span="12" :offset="0"> | ||||||
|           <el-input v-model="form.shortName" placeholder="请输入项目简称" /> |               <el-form-item label="项目名称" prop="projectName"> | ||||||
|         </el-form-item> |                 <el-input v-model="form.projectName" placeholder="请输入项目名称" /> | ||||||
|         <el-form-item label="项目地址" prop="projectSite"> |               </el-form-item> | ||||||
|           <el-input v-model="form.projectSite" placeholder="请输入项目地址" /> |             </el-col> | ||||||
|         </el-form-item> |             <el-col :span="12" :offset="0"> | ||||||
|         <el-form-item label="负责人" prop="principal"> |               <el-form-item label="项目简称" prop="shortName"> | ||||||
|           <el-input v-model="form.principal" placeholder="请输入负责人" /> |                 <el-input v-model="form.shortName" placeholder="请输入项目简称" /> | ||||||
|         </el-form-item> |               </el-form-item> | ||||||
|         <el-form-item label="负责人电话" prop="principalPhone"> |             </el-col> | ||||||
|           <el-input v-model="form.principalPhone" placeholder="请输入负责人电话" /> |             <el-col :span="12" :offset="0"> | ||||||
|         </el-form-item> |               <el-form-item label="负责人" prop="principal"> | ||||||
|         <el-form-item label="实际容量" prop="actual"> |                 <el-input v-model="form.principal" placeholder="请输入负责人" /> | ||||||
|           <el-input v-model="form.actual" placeholder="请输入实际容量" /> |               </el-form-item> | ||||||
|         </el-form-item> |             </el-col> | ||||||
|         <el-form-item label="计划容量" prop="plan"> |             <el-col :span="12" :offset="0"> | ||||||
|           <el-input v-model="form.plan" placeholder="请输入计划容量" /> |               <el-form-item label="负责人电话" prop="principalPhone"> | ||||||
|         </el-form-item> |                 <el-input v-model="form.principalPhone" placeholder="请输入负责人电话" /> | ||||||
|         <el-form-item label="开工时间" prop="onStreamTime"> |               </el-form-item> | ||||||
|           <el-date-picker clearable v-model="form.onStreamTime" type="date" value-format="YYYY-MM-DD" placeholder="请选择开工时间" /> |             </el-col> | ||||||
|         </el-form-item> |             <el-col :span="12" :offset="0"> | ||||||
|         <el-form-item label="打卡范围" prop="punchRange"> |               <el-form-item label="项目类型" prop="projectType" label-width="100px"> | ||||||
|           <el-input v-model="form.punchRange" placeholder="请输入打卡范围" /> |                 <el-select v-model="form.projectType" placeholder="请选择项目类型" clearable> | ||||||
|         </el-form-item> |                   <el-option v-for="dict in project_type" :key="dict.value" :label="dict.label" :value="dict.value" /> | ||||||
|         <el-form-item label="设计总量" prop="designTotal"> |                 </el-select> | ||||||
|           <el-input v-model="form.designTotal" placeholder="请输入设计总量" /> |               </el-form-item> | ||||||
|         </el-form-item> |             </el-col> | ||||||
|         <el-form-item label="安全协议书" prop="securityAgreement"> |             <el-col :span="12" :offset="0"> | ||||||
|           <file-upload v-model="form.securityAgreement" :limit="1" :file-type="['pdf']" :file-size="50" /> |               <el-form-item label="项目类别" prop="projectCategory" label-width="100px"> | ||||||
|         </el-form-item> |                 <el-select v-model="form.projectCategory" placeholder="请选择项目类别" clearable> | ||||||
|         <el-form-item label="备注" prop="remark"> |                   <el-option v-for="dict in project_category_type" :key="dict.value" :label="dict.label" :value="dict.value" /> | ||||||
|           <el-input v-model="form.remark" type="textarea" placeholder="请输入内容" /> |                 </el-select> | ||||||
|         </el-form-item> |               </el-form-item> | ||||||
|  |             </el-col> | ||||||
|  |             <el-col :span="12" :offset="0"> | ||||||
|  |               <el-form-item label="开工时间" prop="onStreamTime"> | ||||||
|  |                 <el-date-picker clearable v-model="form.onStreamTime" type="date" value-format="YYYY-MM-DD" placeholder="请选择开工时间" /> | ||||||
|  |               </el-form-item> | ||||||
|  |             </el-col> | ||||||
|  |             <el-col :span="12" :push="3"> | ||||||
|  |               <el-button type="primary" size="default" @click="amapStatus = true">获取经纬度</el-button> | ||||||
|  |             </el-col> | ||||||
|  |             <el-col :span="12" :offset="0"> | ||||||
|  |               <el-form-item label="经度" prop="lng"> | ||||||
|  |                 <el-input v-model="form.lng" disabled placeholder="请输入经度" /> | ||||||
|  |               </el-form-item> | ||||||
|  |             </el-col> | ||||||
|  |             <el-col :span="12" :offset="0"> | ||||||
|  |               <el-form-item label="纬度" prop="lat"> | ||||||
|  |                 <el-input v-model="form.lat" disabled placeholder="请输入纬度" /> | ||||||
|  |               </el-form-item> | ||||||
|  |             </el-col> | ||||||
|  |             <el-col :span="24" :offset="0"> | ||||||
|  |               <el-form-item label="项目地址" prop="projectSite"> | ||||||
|  |                 <el-input v-model="form.projectSite" disabled placeholder="请输入项目地址" /> | ||||||
|  |               </el-form-item> | ||||||
|  |             </el-col> | ||||||
|  |             <el-col :span="12" :offset="0"> | ||||||
|  |               <el-form-item label="计划容量" prop="plan"> | ||||||
|  |                 <el-input v-model="form.plan" placeholder="请输入计划容量" /> | ||||||
|  |               </el-form-item> | ||||||
|  |             </el-col> | ||||||
|  |             <el-col :span="12" :offset="0"> | ||||||
|  |               <el-form-item label="实际容量" prop="actual"> | ||||||
|  |                 <el-input v-model="form.actual" placeholder="请输入实际容量" /> | ||||||
|  |               </el-form-item> | ||||||
|  |             </el-col> | ||||||
|  |             <el-col :span="12" :offset="0"> | ||||||
|  |               <el-form-item label="设计总量" prop="designTotal"> | ||||||
|  |                 <el-input v-model="form.designTotal" placeholder="请输入设计总量" /> | ||||||
|  |               </el-form-item> | ||||||
|  |             </el-col> | ||||||
|  |             <el-col :span="24" :offset="0"> | ||||||
|  |               <el-form-item label="备注" prop="remark"> | ||||||
|  |                 <el-input v-model="form.remark" placeholder="请输入内容" /> | ||||||
|  |               </el-form-item> | ||||||
|  |             </el-col> | ||||||
|  |             <el-col :span="12" :offset="0"> | ||||||
|  |               <el-form-item label="项目排序" prop="remark"> | ||||||
|  |                 <el-input-number v-model="form.sort" :min="0" :max="10000" /> | ||||||
|  |               </el-form-item> | ||||||
|  |             </el-col> | ||||||
|  |           </el-row> | ||||||
|  |         </div> | ||||||
|  |         <div class="block-box"> | ||||||
|  |           <div class="">打卡设置</div> | ||||||
|  |           <el-row :gutter="20"> | ||||||
|  |             <el-col :span="12" :offset="0"> | ||||||
|  |               <el-form-item label="打卡开始时间" prop="playCardStart" label-width="110px"> | ||||||
|  |                 <!-- <el-time-picker value-format="HH:mm" v-model="form.playCardStart" placeholder="请输入打卡开始时间" /> --> | ||||||
|  |                 <el-time-select | ||||||
|  |                   v-model="form.playCardStart" | ||||||
|  |                   style="width: 100%" | ||||||
|  |                   class="mr-4" | ||||||
|  |                   placeholder="请输入打卡开始时间" | ||||||
|  |                   value-format="HH:mm" | ||||||
|  |                   start="00:00" | ||||||
|  |                   step="00:15" | ||||||
|  |                   end="23:59" | ||||||
|  |                 /> | ||||||
|  |               </el-form-item> | ||||||
|  |             </el-col> | ||||||
|  |             <el-col :span="12" :offset="0"> | ||||||
|  |               <el-form-item label="打卡结束时间" prop="playCardEnd" label-width="110px"> | ||||||
|  |                 <!-- <el-time-picker value-format="HH:mm" v-model="form.playCardEnd" placeholder="请输入打卡结束时间" /> --> | ||||||
|  |                 <el-time-select | ||||||
|  |                   v-model="form.playCardEnd" | ||||||
|  |                   style="width: 100%" | ||||||
|  |                   :min-time="form.playCardStart" | ||||||
|  |                   class="mr-4" | ||||||
|  |                   placeholder="请输入打卡结束时间" | ||||||
|  |                   value-format="HH:mm" | ||||||
|  |                   start="00:00" | ||||||
|  |                   step="00:15" | ||||||
|  |                   end="23:59" | ||||||
|  |                 /> | ||||||
|  |               </el-form-item> | ||||||
|  |             </el-col> | ||||||
|  |             <el-col :span="24" :offset="0"> | ||||||
|  |               <el-form-item label="安全协议书" prop="securityAgreement"> | ||||||
|  |                 <file-upload v-model="form.securityAgreement" :limit="1" :file-type="['pdf']" :file-size="50" /> | ||||||
|  |               </el-form-item> | ||||||
|  |             </el-col> | ||||||
|  |           </el-row> | ||||||
|  |         </div> | ||||||
|       </el-form> |       </el-form> | ||||||
|       <template #footer> |       <template #footer> | ||||||
|         <div class="dialog-footer"> |         <div class="dialog-footer"> | ||||||
| @ -137,16 +233,29 @@ | |||||||
|         </div> |         </div> | ||||||
|       </template> |       </template> | ||||||
|     </el-dialog> |     </el-dialog> | ||||||
|  |     <el-dialog v-model="amapStatus" title="获取经纬度" width="80%"> | ||||||
|  |       <amap height="620px" @setLocation="setPoi"></amap> | ||||||
|  |       <!-- <template #footer> | ||||||
|  |         <div class="dialog-footer"> | ||||||
|  |           <el-button v-loading="buttonLoading" type="primary" @click="amapStatus = false"> 确定</el-button> | ||||||
|  |           <el-button @click="amapStatus = false">取消</el-button> | ||||||
|  |         </div> | ||||||
|  |       </template> --> | ||||||
|  |     </el-dialog> | ||||||
|   </div> |   </div> | ||||||
| </template> | </template> | ||||||
|  |  | ||||||
| <script setup name="Project" lang="ts"> | <script setup name="Project" lang="ts"> | ||||||
| import { addProject, delProject, getProject, listProject, updateProject } from '@/api/project/project'; | import { addProject, delProject, getProject, listProject, updateProject } from '@/api/project/project'; | ||||||
| import { ProjectForm, ProjectQuery, ProjectVO } from '@/api/project/project/types'; | import { ProjectForm, ProjectQuery, ProjectVO, locationType } from '@/api/project/project/types'; | ||||||
|  | import amap from '@/components/amap/index.vue'; | ||||||
| const { proxy } = getCurrentInstance() as ComponentInternalInstance; | const { proxy } = getCurrentInstance() as ComponentInternalInstance; | ||||||
| const { sys_normal_disable, project_category_type } = toRefs<any>(proxy?.useDict('sys_normal_disable', 'project_category_type')); | const { sys_normal_disable, project_category_type, project_type } = toRefs<any>( | ||||||
|  |   proxy?.useDict('sys_normal_disable', 'project_category_type', 'project_type') | ||||||
|  | ); | ||||||
|  | const change = (val: any) => { | ||||||
|  |   console.log(val, 1212, form.value.playCardStart); | ||||||
|  | }; | ||||||
| const projectList = ref<ProjectVO[]>([]); | const projectList = ref<ProjectVO[]>([]); | ||||||
| const buttonLoading = ref(false); | const buttonLoading = ref(false); | ||||||
| const loading = ref(true); | const loading = ref(true); | ||||||
| @ -155,7 +264,7 @@ const ids = ref<Array<string | number>>([]); | |||||||
| const single = ref(true); | const single = ref(true); | ||||||
| const multiple = ref(true); | const multiple = ref(true); | ||||||
| const total = ref(0); | const total = ref(0); | ||||||
|  | const amapStatus = ref(false); | ||||||
| const queryFormRef = ref<ElFormInstance>(); | const queryFormRef = ref<ElFormInstance>(); | ||||||
| const projectFormRef = ref<ElFormInstance>(); | const projectFormRef = ref<ElFormInstance>(); | ||||||
| const dialog = reactive<DialogOption>({ | const dialog = reactive<DialogOption>({ | ||||||
| @ -171,19 +280,22 @@ const initFormData: ProjectForm = { | |||||||
|   status: undefined, |   status: undefined, | ||||||
|   picUrl: undefined, |   picUrl: undefined, | ||||||
|   remark: undefined, |   remark: undefined, | ||||||
|   type: undefined, |   projectType: undefined, | ||||||
|   isType: undefined, |   projectCategory: undefined, | ||||||
|   deletedAt: undefined, |   deletedAt: undefined, | ||||||
|   projectSite: undefined, |   projectSite: undefined, | ||||||
|   principal: undefined, |   principal: undefined, | ||||||
|   principalPhone: undefined, |   principalPhone: undefined, | ||||||
|   actual: undefined, |   actual: undefined, | ||||||
|  |   lng: undefined, | ||||||
|  |   lat: undefined, | ||||||
|   plan: undefined, |   plan: undefined, | ||||||
|   onStreamTime: undefined, |   onStreamTime: undefined, | ||||||
|   punchRange: undefined, |   playCardStart: undefined, | ||||||
|  |   playCardEnd: undefined, | ||||||
|   designTotal: undefined, |   designTotal: undefined, | ||||||
|   securityAgreement: undefined, |   securityAgreement: undefined, | ||||||
|   sort: undefined, |   sort: 0, | ||||||
|   showHidden: undefined, |   showHidden: undefined, | ||||||
|   isDelete: undefined |   isDelete: undefined | ||||||
| }; | }; | ||||||
| @ -197,16 +309,19 @@ const data = reactive<PageData<ProjectForm, ProjectQuery>>({ | |||||||
|     pId: undefined, |     pId: undefined, | ||||||
|     status: undefined, |     status: undefined, | ||||||
|     picUrl: undefined, |     picUrl: undefined, | ||||||
|     type: undefined, |     projectType: undefined, | ||||||
|     isType: undefined, |     projectCategory: undefined, | ||||||
|     deletedAt: undefined, |     deletedAt: undefined, | ||||||
|     projectSite: undefined, |     projectSite: undefined, | ||||||
|     principal: undefined, |     principal: undefined, | ||||||
|     principalPhone: undefined, |     principalPhone: undefined, | ||||||
|     actual: undefined, |     actual: undefined, | ||||||
|  |     lng: undefined, | ||||||
|  |     lat: undefined, | ||||||
|     plan: undefined, |     plan: undefined, | ||||||
|     onStreamTime: undefined, |     onStreamTime: undefined, | ||||||
|     punchRange: undefined, |     playCardStart: undefined, | ||||||
|  |     playCardEnd: undefined, | ||||||
|     designTotal: undefined, |     designTotal: undefined, | ||||||
|     securityAgreement: undefined, |     securityAgreement: undefined, | ||||||
|     sort: undefined, |     sort: undefined, | ||||||
| @ -215,10 +330,19 @@ const data = reactive<PageData<ProjectForm, ProjectQuery>>({ | |||||||
|     params: {} |     params: {} | ||||||
|   }, |   }, | ||||||
|   rules: { |   rules: { | ||||||
|     punchRange: [{ required: true, message: '打卡范围不能为空', trigger: 'blur' }], |     playCardStart: [{ required: true, message: '打卡开始时间不能为空', trigger: 'blur' }], | ||||||
|  |     playCardEnd: [{ required: true, message: '打卡结束时间不能为空', trigger: 'blur' }], | ||||||
|     projectName: [{ required: true, message: '项目名称不能为空', trigger: 'blur' }], |     projectName: [{ required: true, message: '项目名称不能为空', trigger: 'blur' }], | ||||||
|     shortName: [{ required: true, message: '项目简称不能为空', trigger: 'blur' }], |     shortName: [{ required: true, message: '项目简称不能为空', trigger: 'blur' }], | ||||||
|     projectSite: [{ required: true, message: '项目地址不能为空', trigger: 'blur' }] |     principalPhone: [{ required: true, message: '负责人电话不能为空', trigger: 'blur' }], | ||||||
|  |     principal: [{ required: true, message: '负责人不能为空', trigger: 'blur' }], | ||||||
|  |     projectType: [{ required: true, message: '项目类型不能为空', trigger: 'blur' }], | ||||||
|  |     projectCategory: [{ required: true, message: '项目类别不能为空', trigger: 'blur' }], | ||||||
|  |     projectSite: [{ required: true, message: '项目地址不能为空', trigger: 'blur' }], | ||||||
|  |     actual: [{ required: true, message: '实际容量不能为空', trigger: 'blur' }], | ||||||
|  |     lng: [{ required: true, message: '经度不能为空', trigger: 'blur' }], | ||||||
|  |     lat: [{ required: true, message: '纬度不能为空', trigger: 'blur' }], | ||||||
|  |     plan: [{ required: true, message: '计划容量不能为空', trigger: 'blur' }] | ||||||
|   } |   } | ||||||
| }); | }); | ||||||
|  |  | ||||||
| @ -243,6 +367,18 @@ const reset = () => { | |||||||
|   projectFormRef.value?.resetFields(); |   projectFormRef.value?.resetFields(); | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | // 设置位置信息 | ||||||
|  | const setPoi = (location: locationType) => { | ||||||
|  |   if (location) { | ||||||
|  |     console.log('🚀 ~ setPoi ~ poi:', location); | ||||||
|  |     form.value.lng = location.lng; | ||||||
|  |     form.value.lat = location.lat; | ||||||
|  |     form.value.projectSite = location.projectSite; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   amapStatus.value = false; | ||||||
|  | }; | ||||||
|  |  | ||||||
| /** 搜索按钮操作 */ | /** 搜索按钮操作 */ | ||||||
| const handleQuery = () => { | const handleQuery = () => { | ||||||
|   queryParams.value.pageNum = 1; |   queryParams.value.pageNum = 1; | ||||||
| @ -341,3 +477,17 @@ onMounted(() => { | |||||||
|   getList(); |   getList(); | ||||||
| }); | }); | ||||||
| </script> | </script> | ||||||
|  | <style scoped> | ||||||
|  | .block-box { | ||||||
|  |   border: 1px solid #9eccfa; | ||||||
|  |   border-radius: 6px; | ||||||
|  |   padding: 10px 20px 0 10px; | ||||||
|  |   margin-bottom: 20px; | ||||||
|  | } | ||||||
|  | .block-box > div { | ||||||
|  |   color: #409eff; | ||||||
|  |   font-weight: 700; | ||||||
|  |   font-size: 14px; | ||||||
|  |   margin-bottom: 10px; | ||||||
|  | } | ||||||
|  | </style> | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user