applications/mobile-web-view/src/api/map/address.js
New file @@ -0,0 +1,16 @@ import request from '@/axios' /** * @description: 获取地址搜索结果 * @param {*} data :{ * keyworld:string 搜索关键词 * } * @return {*} Promise */ export const getPlace = (data) => { return request({ url: `/webservice/address/getPlace`, method: 'post', data }) } applications/mobile-web-view/src/appComponents/LeafletMap/index.vue
@@ -1,18 +1,6 @@ <template> <div class="page-container"> <div class="map" id="map"></div> <div class="weather-box" v-show="weatherShow"> <div class="icon"> <van-image :src="WEATHER?.[weather] || ''" width="100%" height="100%"></van-image> </div> <div class="content"> <span class="tq">{{ weather }} {{ temperature }}</span> <span class="tq">风速:{{ windVelocity }}</span> </div> </div> <div class="layer-btn" @click="layerChangePopupShow = true" v-show="layerShow"> <van-image width="20" height="20" :src="layerIcon" /> <div class="label">图层</div> @@ -22,10 +10,7 @@ <van-image width="20" height="20" :src="locationIcon" /> <div class="label">定位</div> </div> <slot name="searchBar"></slot> <slot name="eventNav"></slot> <van-popup v-model:show="layerChangePopupShow" position="bottom" round> <div class="popup-container"> <div class="category-content"> @@ -48,33 +33,6 @@ </div> </div> </div> <div class="category-content"> <div class="header base-header"> <div class="title">基础图层</div> </div> <div class="content"> <BaseLayerManage v-if="isMapReady" :getCurMap="getCurMap" /> <!-- <el-tree--> <!-- :props="defaultProps"--> <!-- :data="treeData"--> <!-- show-checkbox--> <!-- node-key="id"--> <!-- :expand-on-click-node="false"--> <!-- :check-on-click-node="false"--> <!-- :check-on-click-leaf="false"--> <!-- @check="handleCheckChange"--> <!-- />--> </div> </div> <div class="category-content"> <MapLayerManage v-for="item in customizeLayer" :options="item" :key="item.id" v-if="isMapReady" :getCurMap="getCurMap" /> </div> </div> </van-popup> </div> @@ -87,21 +45,12 @@ import layerIcon from '@/appDataSource/leafletMapIcon/layer-icon.svg' import locationIcon from '@/appDataSource/leafletMapIcon/location-icon.svg' import { useStore } from 'vuex' import { getEventPageSimpleApi } from '@/api/home/event' import { getDroneSuggest, getLayerTreeApi } from '@/api/home/common' import DroneMarkerPopup from '@/appComponents/DroneMarkerPopup/index.vue' import EventMarkerPopup from '@/appComponents/EventMarkerPopup/index.vue' import MapLayerManage from './MapLayerManage.vue' import BaseLayerManage from '@/appComponents/LeafletMap/BaseLayerManage.vue' import { getDeviceRegion, getMapEvents } from '@/api/home/aggregation' import { getIimitationArea } from '@/api/map/dji' import L from 'leaflet' import 'leaflet/dist/leaflet.css' import sl from '@/appDataSource/leafletMapIcon/sl.svg' import yx from '@/appDataSource/leafletMapIcon/yx.svg' import EventBus from '@/utils/eventBus' import { getEventImage } from '@/utils/stateToImageMap/event' import { WEATHER } from '@/const/weather' const emit = defineEmits(['location-selected']) const { weatherShow, layerShow, locationShow, createWorkShow } = defineProps({ weatherShow: { @@ -125,7 +74,6 @@ const isProd = import.meta.env.VITE_APP_ENV === 'production' import { basemapLayer0, basemapLayer1, basemapLayer2, basemapLayer3 } from '@/const/leafletConst' import { useAreaBoundary } from '@/hooks/useAreaBoundary' const basemap0 = L.layerGroup([basemapLayer0, basemapLayer1]) const basemap1 = L.layerGroup([basemapLayer2, basemapLayer3]) @@ -136,13 +84,13 @@ const layers = [ { src: sl, name: '天地图电子', name: '矢量', key: 1, map: basemap0, }, { src: yx, name: '天地图影像', name: '影像', key: 2, map: basemap1, }, @@ -155,8 +103,6 @@ let eventMarkersLayer = null let addressMarkersLayer = null let boundaryInstance = useAreaBoundary({ initFly: true }) const initMap = () => { if (map) return map = L.map('map', { @@ -167,7 +113,6 @@ doubleClickZoom: false, editable: true, //绘制控件 }).setView([25.992338, 114.823254], 3) boundaryInstance.initBoundary(map) map.whenReady(() => { isMapReady.value = true @@ -262,7 +207,7 @@ } ) } else { console.log('Geolocation is not supported by this browser.') console.log('该浏览器不支持地理定位功能。') } } let lastLocationMarker = null @@ -294,9 +239,7 @@ const mapAddMarker = data => { if (!map) return const { lat, lng, zoom = 16, name = '', customClassName = '' } = data mapSetView(data) // 创建带有图标和文字的 divIcon @@ -317,142 +260,15 @@ L.marker([lat, lng], { icon: droneHtmlIcon }).addTo(addressMarkersLayer) } const mapOnlyShowDrone = (data = {}) => { const { device_sn = '' } = data eventMarkersLayer.clearLayers() if (droneAllData.length > 0 && device_sn !== '') { mapInitDroneMarkers(device_sn) } else { initDrone(device_sn) } if (device_sn !== '') { getSignDroneEvents(device_sn) } else { initEvents() } } const mapClearMarker = () => { addressMarkersLayer.clearLayers() } let droneAllData = [] const initDrone = (device_sn = '') => { getDeviceRegion({ hidden_flag: 0, }).then(res => { const data = res?.data?.data || [] droneAllData = data.filter(item => item.status !== 'OFFLINE') mapInitDroneMarkers(device_sn) }) } const mapInitDroneMarkers = (device_sn = '') => { droneMarkersLayer.clearLayers() let materialColor = 'rgba(27, 215, 89, 40)' let frameColor = 'rgba(27, 215, 89, 255)' droneAllData .filter(item => item.device_sn === device_sn || device_sn === '') .forEach(item => { let event_num = item.event_num || 0 if (event_num > 100) { materialColor = 'rgba(255, 37, 9, 40)' frameColor = 'rgba(255, 37, 9, 255)' } else if (event_num > 50) { materialColor = 'rgba(255, 171, 54, 40)' frameColor = 'rgba(255, 171, 54, 255)' } else { materialColor = 'rgba(27, 215, 89, 10)' frameColor = 'rgba(27, 215, 89, 255)' } buildCirclePolygon(item.latitude, item.longitude, materialColor, frameColor).addTo(droneMarkersLayer) publicAddMakers({ ...item, makerType: 1, }) }) } const initEvents = () => { getMapEvents({}).then(res => { const resData = res?.data?.data?.data || [] resData.forEach(item => { publicAddMakers({ ...item, makerType: 2, }) }) }) } const getSignDroneEvents = (device_sn = '') => { const params = { 'device_sn': device_sn, } getEventPageSimpleApi(params, { current: 1, size: 999999 }).then(res => { const resData = res?.data?.data || [] resData.forEach(item => { publicAddMakers({ ...item, makerType: 2, }) }) }) } // 天气 const store = useStore() const selectedAreaCode = computed(() => store.state.user.selectedAreaCode) const weather = ref('') // 风速 const windVelocity = ref('') const temperature = ref('') // 获取天气建议 const getWeatherSuggest = () => { getDroneSuggest({ areaCode: selectedAreaCode.value }).then(res => { if (res.data.code !== 0) return weather.value = res.data.data.weather windVelocity.value = res.data.data.windPower temperature.value = res.data.data.temperature }) } // 获取后台自定义图层 const customizeLayer = ref(null) function getLayerTree() { getLayerTreeApi().then(res => { const colorList = ['#00ff06', '#ff0000', '#00ffea'] // const imgList = [dzwlSvg,zdyjfqSvg,gtkjghSvg] customizeLayer.value = res.data.data.map((item, index) => ({ ...item, color: colorList[index], imgIcon: [], // imgList[index] })) if (isProd) { customizeLayer.value = customizeLayer.value.filter(i => i.id === 1) } }) } onMounted(async () => { getLayerTree() getWeatherSuggest() await nextTick() initMap() @@ -461,11 +277,7 @@ EventBus.on('mapSetView', mapSetView) EventBus.on('mapAddMarker', mapAddMarker) EventBus.on('mapClearMarker', mapClearMarker) EventBus.on('mapOnlyShowDrone', mapOnlyShowDrone) initDrone() initEvents() // initEvents() // L.circle([24, 112], { // color: 'red', // 边框颜色 // fillColor: '#f03', // 填充颜色 @@ -478,126 +290,8 @@ EventBus.off('mapSetView', mapSetView) EventBus.off('mapAddMarker', mapAddMarker) EventBus.off('mapClearMarker', mapClearMarker) EventBus.off('mapOnlyShowDrone', mapOnlyShowDrone) }) function publicAddMakers(data) { // makerType 1 = 机巢, 2 = 事件点 const { makerType, latitude, longitude } = data const customIcon = L.icon({ iconUrl: makerType === 1 ? droneIcon : getEventImage(data.status), // 替换为你的图片路径 iconSize: makerType === 1 ? [24, 24] : [20, 20], // 图标大小 iconAnchor: makerType === 1 ? [12, 12] : [10, 10], // 图标的锚点(设置图片的底部中心) }) let marker = null if (makerType === 1) { // 创建带有图标和文字的 divIcon let droneHtmlIcon = L.divIcon({ html: ` <div class="content"> <img src="${droneIcon}"> <span> ${data.nickname} </span> </div> `, className: 'ztzf-drone-custom-icon', // 可选,用于添加CSS类 iconSize: [24, 24], // 设置图标大小 iconAnchor: [12, 12], }) marker = L.marker([latitude, longitude], { icon: droneHtmlIcon, zIndexOffset: 9 }).addTo(droneMarkersLayer) } else { marker = L.marker([latitude, longitude], { icon: customIcon, zIndexOffset: 1, }).addTo(eventMarkersLayer) } marker.on('click', e => { // 当前点击要素---关联数据 marker.unbindPopup() const zoomLevel = map.getZoom() if (makerType === 1) { if (zoomLevel < 11) { mapSetView({ lat: e.latlng.lat, lng: e.latlng.lng, zoom: 11, }) return } } if (makerType !== 1) { if (zoomLevel < 13) { mapSetView({ lat: e.latlng.lat, lng: e.latlng.lng, zoom: 13, }) return } } const container = document.createElement('div') const popupApp = createApp(makerType === 1 ? DroneMarkerPopup : EventMarkerPopup, { data: e.target.options.customData, onClose: () => { marker.closePopup() popupApp.unmount() // 卸载 Vue 应用 }, }) popupApp.mount(container) marker .bindPopup(container, { closeButton: false, className: 'custom-leaflet-popup', offset: L.point(80, 0), }) .openPopup() }) // 使用 marker 的 id 作为标识符 marker.options.customData = data } // 构建圆形多边形 function buildCirclePolygon(lat, lng, materialColor, frameColor) { var radius = 5000 / 100460 // 5000米转为大约的纬度差(纬度上的1度大约是111km) var parts = [] for (var i = 0; i < 360; i++) { var radians = ((i + 1) * Math.PI) / 180 // 计算新的点 var circlePoint = [ Math.cos(radians) * radius + lat, // 纬度偏移 Math.sin(radians) * radius + lng, // 经度偏移,需考虑纬度的影响 ] parts[i] = circlePoint } // 生成多边形,近似圆形 var polygon = L.polygon(parts, { color: frameColor, fillColor: materialColor, weight: 1, }) return polygon } </script> <style lang="scss" scoped> @@ -611,61 +305,6 @@ height: 100%; } .weather-box { padding: 4px 0; padding-right: 6px; display: flex; justify-content: center; align-items: center; position: absolute; top: 12px; left: 12px; height: 48px; background: #fff; z-index: 996; box-shadow: 0px 4px 4px 0px rgba(0, 0, 0, 0.18); border-radius: 6px 6px 6px 6px; .icon { margin-left: 10px; width: 24px; height: 24px; } .content { height: 100%; margin-left: 4px; display: flex; flex-direction: column; justify-content: space-around; font-family: Source Han Sans CN, Source Han Sans CN; font-weight: 400; font-size: 12px; color: #757575; text-align: left; font-style: normal; text-transform: none; } .tq { margin: 0 5px; } .qk { margin-left: 5px; color: #04f043; } .yellowqk { margin-left: 5px; color: yellow; } .redqk { margin-left: 5px; color: red; } } .location-btn, .layer-btn { applications/mobile-web-view/src/appDataSource/leafletMapIcon/addressSearch.svg
New file @@ -0,0 +1,5 @@ <svg width="7" height="12" viewBox="0 0 7 12" fill="none" xmlns="http://www.w3.org/2000/svg"> <g id="Vector 185"> <path id="Vector 185_2" d="M6 11L1 6L6 1" stroke="#363636" stroke-linecap="round"/> </g> </svg> applications/mobile-web-view/src/appPages/Map/index.vue
@@ -1,13 +1,4 @@ <!-- * @Author : yuan * @Date : 2025-10-14 13:57:35 * @LastEditors : yuan * @LastEditTime : 2025-10-21 11:40:25 * @FilePath : \src\appPages\Map\index.vue * @Description : * Copyright 2025 OBKoro1, All Rights Reserved. * 2025-10-14 13:57:35 --> <template> <div class="wrapper" :style="{ paddingTop: route.query.topMargin + 'px' }"> <leaflet-map :weatherShow="true" :layerShow="true" :locationShow="true"> applications/mobile-web-view/src/appPages/Map/searchBar.vue
@@ -1,13 +1,3 @@ <!-- * @Author : yuan * @Date : 2025-10-13 16:15:19 * @LastEditors : yuan * @LastEditTime : 2025-12-19 15:32:56 * @FilePath : \applications\mobile-web-view\src\appPages\Map\searchBar.vue * @Description : * Copyright 2025 OBKoro1, All Rights Reserved. * 2025-10-13 16:15:19 --> <template> <van-floating-panel v-model:height="height" :anchors="anchors"> <template #header> @@ -24,16 +14,9 @@ :border="false" > <template #left-icon> <div class="search-left-box" @click="onSelect"> <div class="search-left-box"> <van-image width="16" height="16" :src="switchoverIcon" /> <div class="search-type">{{ curSearchType === 0 ? '机巢' : '地址' }}</div> </div> </template> <template #right-icon v-if="isWeb"> <div class="search-right-box" @click="scanCode"> <van-image width="20" height="20" :src="qrCodeIcon" /> <div class="search-type">地址</div> </div> </template> </van-field> @@ -48,29 +31,21 @@ </div> <van-list v-else :finished="finished" :finished-text="finishedText"> <van-cell v-show="curSearchType === 0" v-for="item in list" :key="item" @click="flyToDrone(item)"> <template #title>{{ item.nickname }}</template> </van-cell> <van-cell v-show="curSearchType === 1" v-for="item in list" :key="item" @click="flyToAddress(item)"> <van-cell v-for="item in list" :key="item" @click="flyToAddress(item)"> <template #title>{{ item.name }}</template> <template #value>{{ item.district }}</template> <template #value>{{ item?.pname }}{{ item?.cityname }}{{ item?.adname }}</template> </van-cell> </van-list> </van-floating-panel> </template> <script setup> import switchoverIcon from '@/appDataSource/leafletMapIcon/switchover-icon.svg' import qrCodeIcon from '@/appDataSource/leafletMapIcon/qr-code.svg' import switchoverIcon from '@/appDataSource/leafletMapIcon/addressSearch.svg' import { showToast } from 'vant' import _ from 'lodash' import { searchWithPlugin } from '@/utils/util' import { getPlace } from '@/api/map/address' import { useStore } from 'vuex' import { selectDeviceList } from '@/api/home/common' import { selectDevicePageSimplify } from '@/api/home/machineNest.js' import EventBus from '@/utils/eventBus' import { gcj02ToWgs84 } from '@/utils/coordinateTransformation' import { useRoute } from 'vue-router' @@ -78,7 +53,6 @@ const isWeb = ref(true) const store = useStore() const selectedAreaCode = computed(() => store.state.user.selectedAreaCode) const searchVal = ref('') const list = ref([]) const finished = ref(false) @@ -87,28 +61,10 @@ const anchors = [70, Math.round(0.6 * window.innerHeight)] const height = ref(anchors[0]) const actions = ref([{ text: '地址' }]) const curSearchType = ref(1) // 固定为地址搜索 const curSearchType = ref(0) // 0机巢 1地址 const onSelect = () => { searchVal.value = '' list.value = [] finished.value = false curSearchType.value = curSearchType.value === 0 ? 1 : 0 actions.value = [{ text: curSearchType.value === 0 ? '地址' : '机巢' }] EventBus.emit('mapClearMarker') EventBus.emit('mapOnlyShowDrone') if (curSearchType.value === 0) { getDeviceList() // 切换到机巢时展示全部机巢 } } // 获取地址搜索结果 const getAddressList = () => { // 使用插件搜索地址 const searchWithPluginAPI = () => { searchWithPlugin(searchVal.value, selectedAreaCode.value, (err, data) => { if (data && data.length > 0) { list.value = data @@ -124,29 +80,34 @@ }) } // 获取机巢搜索结果 const getDeviceList = async () => { const params = { nickname: searchVal.value, current: 1, size: 999, } const res = await selectDevicePageSimplify(params) // 使用新接口搜索地址 const searchWithNewAPI = () => { getPlace({ keyworld: searchVal.value }).then(res => { const data = res.data.data.pois || [] if (data && data.length > 0) { list.value = data finishedText.value = '' } else { finishedText.value = '暂无数据' } if (res.data.code !== 0) return setTimeout(() => { finished.value = true loadingTest.value = false }, 800) }).catch(err => { console.error('地址搜索失败:', err) finishedText.value = '搜索失败' setTimeout(() => { finished.value = true loadingTest.value = false }, 800) }) } if (res?.data?.data?.records && res?.data?.data?.records.length > 0) { list.value = res?.data?.data?.records.filter(item => item.status !== 'OFFLINE') || [] finishedText.value = list.value.length > 0 ? '' : '暂无数据' } else { finishedText.value = '暂无数据' } setTimeout(() => { finished.value = true loadingTest.value = false }, 800) // 获取地址搜索结果 const getAddressList = () => { searchWithNewAPI() } const tooltipText = computed(() => { @@ -154,7 +115,7 @@ return '' } if (searchVal.value.trim() === '') { return curSearchType.value === 0 ? '' : `支持搜索${curSearchType.value === 0 ? '机巢' : '地址'}` return '支持搜索地址' } return finishedText.value || '' }) @@ -167,24 +128,15 @@ EventBus.emit('mapClearMarker') if (curSearchType.value === 1) { getAddressList() } else if (curSearchType.value === 0) { getDeviceList() } getAddressList() } // 输入框input事件 const handlerInput = _.debounce(() => { if (searchVal.value.trim() === '') { if (curSearchType.value === 0) { // 搜索机巢时,输入框为空展示全部机巢 inputSelect() } else { loadingTest.value = false list.value = [] finishedText.value = '' } loadingTest.value = false list.value = [] finishedText.value = '' return } inputSelect() @@ -196,35 +148,20 @@ EventBus.emit('mapOnlyShowDrone') } // 飞到机巢位置 const flyToDrone = item => { height.value = anchors[0] searchVal.value = item.nickname inputSelect() EventBus.emit('mapOnlyShowDrone', { device_sn: item.device_sn }) EventBus.emit('mapSetView', { lat: item.latitude, lng: item.longitude, zoom: 11, }) } const flyToAddress = item => { if (!item.location) { showToast('当前地址无坐标信息') return } const [longitude, latitude] = gcj02ToWgs84(item.location.lng, item.location.lat) EventBus.emit('mapClearMarker') const location = typeof item.location === 'string' ? item.location.split(',').map(Number) : [item.location.lng, item.location.lat]; const [longitude, latitude] = gcj02ToWgs84(location[0], location[1]) height.value = anchors[0] searchVal.value = item.name inputSelect() EventBus.emit('mapAddMarker', { lat: latitude, @@ -232,13 +169,6 @@ name: searchVal.value, customClassName: 'address-marker', }) } const scanCode = () => { const transmitData = { data: { type: 'scanCode' } } wx.miniProgram.navigateTo({ url: "/subPackages/qrCode/index" }) wx.miniProgram.postMessage(transmitData) uni.postMessage(transmitData) } watch( @@ -252,10 +182,6 @@ ) onMounted(() => { if (curSearchType.value === 0) { getDeviceList() } const hash = window.location.hash.slice(1) const [hashPath, hashParamsStr] = hash.split('?') if (hashParamsStr) { @@ -307,7 +233,7 @@ .search-type { margin: 0 4px; color: #1d6fe9; color: #282828; } } } @@ -347,4 +273,4 @@ color: #000; } } </style> </style> applications/mobile-web-view/src/axios.js
@@ -56,10 +56,12 @@ //安全请求header config.headers['Blade-Requested-With'] = 'BladeHttpRequest' //headers判断是否需要 const authorization = config.authorization === false if (!authorization) { config.headers['Authorization'] = `Basic ${Base64.encode(`${website.clientId}:${website.clientSecret}`)}` } // const authorization = config.authorization === false // if (!authorization) { // config.headers['Authorization'] = `Basic ${Base64.encode(`${website.clientId}:${website.clientSecret}`)}` // } let authorization = store.state.user.token config.headers['Authorization'] = authorization // 根据后端要求,post的data为空的话传{} if (config.method === 'post') { config.data = config.data || {} uniapps/work-app/src/config/env.js
@@ -13,7 +13,7 @@ VITE_APP_ENV:'development', // 开发环境这里改为自己的 VITE_APP_WEBVIEW_URL: 'https://wrj.shuixiongit.com/drone-app-web-view/#/webViewWrapper', // VITE_APP_WEBVIEW_URL: 'http://localhost:5173/drone-app-web-view/#/webViewWrapper', // VITE_APP_WEBVIEW_URL: 'http://192.168.1.157:5176/mobile-web-view/#/webViewWrapper', VITE_API_BASE_URL: 'http://218.202.104.82:8200', // VITE_API_BASE_URL: 'https://aisky.org.cn/api', VITE_APP_WS_API_URL:'wss://wrj.shuixiongit.com/drone-wss/api/v1/ws', uniapps/work-app/src/pages/login/index.vue
@@ -5,17 +5,16 @@ <image class="logo" :src="logoSvg" /> <div class="title">低空经济服务一体化平台系统</div> <div class="user-name"> <!-- <image :src="usernameSvg" /> --> <input v-model="loginForm.username" placeholder="请输入用户名" /> </div> <div class="pass-word"> <!-- <image :src="passwordSvg" /> --> <input v-model="loginForm.password" type="password" :type="showPassword ? 'text' : 'password'" placeholder="请输入密码" /> <image :src="showPasswordSvg" /> <image :src="showPassword ? openPassword : showPasswordSvg" @click="toggleShowPassword" class="password-toggle-icon" /> </div> <div class="remember-password"> <label> @@ -28,16 +27,16 @@ </checkbox-group> 记住密码 </label> <div>忘记密码?</div> <div class="forgotPassword">忘记密码?</div> </div> <button class="login-btn" :style="[inputStyle]" @tap="submit">登录</button> <view class="agreement"> <!-- <view class="agreement"> <label> <checkbox :checked="agreed" @click="agreed = !agreed" /> 同意《用户协议》与《隐私政策》 </label> </view> </view> --> </view> </template> @@ -48,15 +47,10 @@ import { useUserStore } from "@/store/index.js"; import { HOME_PATH, LOGIN_PATH, removeQueryString } from "@/router"; import { ref } from "vue"; import logoSvg from "@/static/images/logo.svg"; import showPasswordSvg from "@/static/images/show-password.svg"; const droneSvg = getAssetsImage("/images/login/droneSvg.svg"); const usernameSvg = getAssetsImage("/images/login/username.svg"); const passwordSvg = getAssetsImage("/images/login/password.svg"); // const logoSvg = getAssetsImage("/images/login/logo.svg"); import openPassword from "@/static/images/openPassword.svg"; const agreed = ref(true); @@ -66,6 +60,7 @@ password: "", }); const rememberPassword = ref(false); const showPassword = ref(false); const inputStyle = computed(() => { const style = {}; if (loginForm.value.username && loginForm.value.password) { @@ -77,6 +72,10 @@ let redirect = HOME_PATH; function toggleRemember(e) { rememberPassword.value = e.detail.value.length > 0; } function toggleShowPassword() { showPassword.value = !showPassword.value; } async function submit() { @@ -182,8 +181,8 @@ } } .logo { width: 127px; height: 51px; width: 134rpx; height: 134rpx; margin: 0 auto; margin-top: 286rpx; margin-bottom: 16px; @@ -209,11 +208,16 @@ text-transform: none; color: #161B2C; text-align: center; margin-bottom: 168rpx; margin-bottom: 106rpx; } .user-name{ margin-bottom: 40rpx; } .pass-word{ display: flex; justify-content: space-around; align-items: center; } .user-name, .pass-word { display: flex; @@ -264,8 +268,9 @@ margin-right: 58rpx; margin-top: 20rpx; color: #666; font-weight: 400; font-size: 28rpx; color: #86909C; label { display: flex; @@ -287,11 +292,13 @@ @apply flex items-center justify-center py-12rpx px-0 text-30rpx border-none; background: #1d6fe9; color: white; width: 590rpx; height: 76rpx; border-radius: 40rpx 40rpx 40rpx 40rpx; margin-top: 100rpx; width: 670rpx; height: 100rpx; border-radius: 8rpx 8rpx 8rpx 8rpx; margin-top: 184rpx; font-size: 36rpx; font-weight: 400; font-family: Source Han Sans CN, Source Han Sans CN; &::after { @apply border-none; } @@ -345,4 +352,10 @@ align-items: center; text-align: center; } .forgotPassword { font-family: PingFang SC, PingFang SC; font-weight: 500; font-size: 28rpx; color: #4E5969; } </style> uniapps/work-app/src/pages/user/index.vue
@@ -17,7 +17,7 @@ <span>{{ user?.sysDept?.deptName }}</span> </view> </view> </view> <view class="personalInformation"> <div class="message"> @@ -35,13 +35,13 @@ </div> </div> </view> <view class="goOutBtn"> <div class="goOutStyle" @click="logOut">退出登录</div> </view> </view> </view> </view> </template> @@ -100,7 +100,7 @@ } .pageUser { background: url("@/static/images/user/userbg.svg") no-repeat ; background-size: 100% ; } .userBox { padding-top: 212rpx; uniapps/work-app/src/static/images/openPassword.svg
New file @@ -0,0 +1,11 @@ <svg width="22" height="22" viewBox="0 0 22 22" fill="none" xmlns="http://www.w3.org/2000/svg"> <g id="Frame" clip-path="url(#clip0_91_2535)"> <path id="Vector" d="M11.0058 3.21024C8.59131 3.21242 6.23676 3.96254 4.26594 5.35746C2.29513 6.75237 0.804838 8.72357 0 11H1.77495C2.53969 9.18334 3.82348 7.63271 5.46549 6.54235C7.10751 5.452 9.03476 4.87039 11.0058 4.87039C12.9769 4.87039 14.9041 5.452 16.5462 6.54235C18.1882 7.63271 19.472 9.18334 20.2367 11H22.0117C21.2068 8.72357 19.7165 6.75237 17.7457 5.35746C15.7749 3.96254 13.4203 3.21242 11.0058 3.21024ZM20.2367 11C19.472 12.8167 18.1882 14.3673 16.5462 15.4576C14.9041 16.548 12.9769 17.1296 11.0058 17.1296C9.03476 17.1296 7.10751 16.548 5.46549 15.4576C3.82348 14.3673 2.53969 12.8167 1.77495 11H0C0.809784 13.2709 2.30219 15.2357 4.27259 16.6249C6.24299 18.0142 8.59489 18.76 11.0058 18.76C13.4168 18.76 15.7687 18.0142 17.7391 16.6249C19.7095 15.2357 21.2019 13.2709 22.0117 11H20.2367Z" fill="#1D2129"/> <path id="Vector_2" d="M11.0057 7.66153C10.3454 7.66153 9.69996 7.85733 9.15095 8.22416C8.60194 8.591 8.17404 9.1124 7.92136 9.72242C7.66868 10.3324 7.60257 11.0037 7.73139 11.6513C7.8602 12.2989 8.17816 12.8938 8.64505 13.3607C9.11195 13.8275 9.70681 14.1455 10.3544 14.2743C11.002 14.4031 11.6733 14.337 12.2833 14.0843C12.8933 13.8317 13.4147 13.4038 13.7815 12.8548C14.1484 12.3057 14.3442 11.6603 14.3442 11C14.3442 10.5616 14.2578 10.1275 14.0901 9.72242C13.9223 9.31738 13.6764 8.94935 13.3664 8.63934C13.0564 8.32934 12.6883 8.08343 12.2833 7.91566C11.8782 7.74788 11.4441 7.66153 11.0057 7.66153ZM11.0057 12.6692C10.6756 12.6692 10.3528 12.5713 10.0783 12.3879C9.80383 12.2045 9.58988 11.9438 9.46354 11.6388C9.3372 11.3338 9.30414 10.9981 9.36855 10.6743C9.43295 10.3505 9.59193 10.0531 9.82538 9.81967C10.0588 9.58623 10.3563 9.42725 10.6801 9.36284C11.0039 9.29843 11.3395 9.33149 11.6445 9.45783C11.9495 9.58417 12.2102 9.79812 12.3936 10.0726C12.577 10.3471 12.6749 10.6699 12.6749 11C12.6749 11.4427 12.4991 11.8673 12.186 12.1803C11.873 12.4934 11.4484 12.6692 11.0057 12.6692Z" fill="#1D2129"/> </g> <defs> <clipPath id="clip0_91_2535"> <rect width="22" height="22" fill="white"/> </clipPath> </defs> </svg> uniapps/work-app/src/subPackages/userDetail/password/index.vue
@@ -235,7 +235,7 @@ } }).catch(err => { uni.showToast({ title: '网络错误,请稍后重试', title: err.data.msg, icon: 'none', duration: 2000 });