Merge branch 'refs/heads/feature/v9.0/9.0.4' into prod
19 files modified
2 files added
| | |
| | | /software/service/drone/web/drone-app |
| | | 正式 |
| | | /app/service/drone/web/drone-app |
| | | |
| | | # app更新步骤 |
| | | |
| | | 修改 /src/config 里面的development的参数,改为对应环境的对应变量 |
| | | |
| | | # 小程序app更新步骤 |
| | | |
| | | 1. 修改 /src/config 里面的development的参数,改为对应环境的对应变量 |
| | | 2. hbuild里面点击运行 =》到小程序 =》自动打开了小程序 =》 |
| | | 3. 调试好=》上传 =》[微信公众号](https://mp.weixin.qq.com/) =》 提交审核 |
| | | |
| | | # 开发者文档 |
| | | |
| | | |
| | | |
| | | - 本项目大量采用webview方式开发,只有登录页是原生的uniapp,其他的都是webview |
| | | - 登录了之后在userStore里面存了用户信息(包括token) |
| | | - 每个页面都会走WebViewPlus组件 |
| | | - WebViewPlus里面有个属性src都会走getWebViewUrl方法 |
| | | - WebViewPlus会监听webview发送给app的消息,统一处理 |
| | | - getWebViewUrl方法里面 会把 路径自动拼接上userInfo(包括token)和一些其他参数 |
| | | |
| | | - 然后到webview这里的 permission.js会去自动接收这些参数并存储到stroe里面 |
| | | |
| | | webview跟app通信 |
| | | |
| | | h5或app的webview |
| | | |
| | | ``` |
| | | webview |
| | | const transmitData = { data: { type: 'submitSuccess', fun: 'add' } } |
| | | uni.postMessage(transmitData) |
| | | |
| | | app 接收到了 然后再跳页面 |
| | | |
| | | uni.switchTab({ |
| | | url: `/pages/work/index?addLog=111`, |
| | | }); |
| | | ``` |
| | | |
| | | 微信小程序的webview 只能在微信里面直接跳,postMessage无效 |
| | | |
| | | ``` |
| | | webview |
| | | |
| | | // 跳转到小程序页面 |
| | | wx.miniProgram.navigateTo({ url: '/pages/xxx/xxx' }) |
| | | |
| | | // 重定向到小程序页面 |
| | | wx.miniProgram.redirectTo({ url: '/pages/xxx/xxx' }) |
| | | |
| | | // 切换Tab页 |
| | | wx.miniProgram.switchTab({ url: '/pages/xxx/xxx' }) |
| | | |
| | | // 返回上一页 |
| | | wx.miniProgram.navigateBack({ delta: 1 }) |
| | | |
| | | // 退出小程序 |
| | | wx.miniProgram.exit() |
| | | |
| | | // 获取小程序环境信息 |
| | | wx.miniProgram.getEnv(function(res) { |
| | | console.log(res.miniprogram) // true |
| | | }) |
| | | |
| | | ``` |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| New file |
| | |
| | | <template> |
| | | <view v-if="showPrivacy" :class="privacyClass"> |
| | | <view :class="contentClass"> |
| | | <view class="title">用户隐私保护指引</view> |
| | | <view class="des"> |
| | | 感谢您选择使用掌控智飞小程序,我们非常重视您的个人信息安全和隐私保护。使用我们的产品前,请您仔细阅读“ |
| | | <text class="link" @tap="openPrivacyContract">{{privacyContractName}} </text>”, |
| | | 如您同意此隐私保护指引,请点击同意按钮,开始使用此小程序,我们将尽全力保护您的个人信息及合法权益,感谢您的信任!<br /> |
| | | </view> |
| | | <view class="btns"> |
| | | <button class="item reject" @click="exitMiniProgram">拒绝</button> |
| | | <button id="agree-btn" class="item agree" open-type="agreePrivacyAuthorization" |
| | | @agreeprivacyauthorization="handleAgreePrivacyAuthorization">同意</button> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { ref, computed, onMounted } from 'vue'; |
| | | |
| | | const props = defineProps({ |
| | | position: { |
| | | type: String, |
| | | default: 'center' |
| | | } |
| | | }); |
| | | |
| | | const emit = defineEmits(['allowPrivacy']); |
| | | |
| | | const isRead = ref(false); |
| | | const showPrivacy = ref(false); |
| | | const privacyContractName = ref(''); |
| | | const resolvePrivacyAuthorization = ref(null); |
| | | |
| | | const privacyClass = computed(() => { |
| | | return props.position === 'bottom' ? 'privacy privacy-bottom' : 'privacy'; |
| | | }); |
| | | |
| | | const contentClass = computed(() => { |
| | | return props.position === 'bottom' ? 'content content-bottom' : 'content'; |
| | | }); |
| | | |
| | | onMounted(() => { |
| | | if (uni.onNeedPrivacyAuthorization) { |
| | | uni.onNeedPrivacyAuthorization((resolve) => { |
| | | resolvePrivacyAuthorization.value = resolve; |
| | | }); |
| | | } |
| | | |
| | | if (uni.getPrivacySetting) { |
| | | uni.getPrivacySetting({ |
| | | success: (res) => { |
| | | if (res.needAuthorization) { |
| | | privacyContractName.value = res.privacyContractName; |
| | | showPrivacy.value = true; |
| | | } else { |
| | | console.log('已经同意隐私授权,不需要再次授权') |
| | | showPrivacy.value = false; |
| | | } |
| | | }, |
| | | }); |
| | | } |
| | | }); |
| | | |
| | | const openPrivacyContract = () => { |
| | | uni.openPrivacyContract({ |
| | | success: () => { |
| | | isRead.value = true; |
| | | }, |
| | | fail: () => { |
| | | uni.showToast({ |
| | | title: '遇到错误', |
| | | icon: 'error', |
| | | }); |
| | | }, |
| | | }); |
| | | }; |
| | | |
| | | const exitMiniProgram = () => { |
| | | wx.exitMiniProgram(); |
| | | }; |
| | | |
| | | const handleAgreePrivacyAuthorization = () => { |
| | | showPrivacy.value = false; |
| | | emit('allowPrivacy'); |
| | | if (typeof resolvePrivacyAuthorization.value === 'function') { |
| | | resolvePrivacyAuthorization.value({ |
| | | buttonId: 'agree-btn', |
| | | event: 'agree', |
| | | }); |
| | | } |
| | | }; |
| | | |
| | | const closePrivacy = () => { |
| | | showPrivacy.value = false; |
| | | }; |
| | | |
| | | // 暴露给父组件使用 |
| | | defineExpose({ |
| | | closePrivacy |
| | | }); |
| | | </script> |
| | | |
| | | <style scoped> |
| | | .privacy { |
| | | position: fixed; |
| | | top: 0; |
| | | right: 0; |
| | | bottom: 0; |
| | | left: 0; |
| | | background: rgba(0, 0, 0, .5); |
| | | z-index: 9999999; |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | } |
| | | |
| | | .privacy-bottom { |
| | | align-items: flex-end; |
| | | } |
| | | |
| | | .content { |
| | | width: 632rpx; |
| | | padding: 48rpx; |
| | | box-sizing: border-box; |
| | | background: #fff; |
| | | border-radius: 16rpx; |
| | | } |
| | | |
| | | .content-bottom { |
| | | position: absolute; |
| | | bottom: 0; |
| | | width: 96%; |
| | | padding: 36rpx; |
| | | border-radius: 16rpx 16rpx 0 0; |
| | | } |
| | | |
| | | .content .title { |
| | | text-align: center; |
| | | color: #333; |
| | | font-weight: bold; |
| | | font-size: 32rpx; |
| | | } |
| | | |
| | | .content .des { |
| | | font-size: 26rpx; |
| | | color: #666; |
| | | margin-top: 40rpx; |
| | | text-align: justify; |
| | | line-height: 1.6; |
| | | } |
| | | |
| | | .content .des .link { |
| | | color: #1989ff; |
| | | text-decoration: underline; |
| | | } |
| | | |
| | | .btns { |
| | | margin-top: 48rpx; |
| | | margin-bottom: 12rpx; |
| | | display: flex; |
| | | } |
| | | |
| | | .btns .item { |
| | | width: 200rpx; |
| | | height: 72rpx; |
| | | overflow: visible; |
| | | display: flex; |
| | | align-items: center; |
| | | |
| | | justify-content: center; |
| | | /* border-radius: 16rpx; */ |
| | | box-sizing: border-box; |
| | | border: none !important; |
| | | } |
| | | |
| | | .btns .reject { |
| | | background: #f4f4f5; |
| | | color: #1989ff; |
| | | font-size: 14px; |
| | | background: #edf5fe; |
| | | font-weight: 300; |
| | | margin-right: 16rpx; |
| | | } |
| | | |
| | | .btns .agree { |
| | | width: 200rpx; |
| | | background: #1989ff; |
| | | color: #fff; |
| | | font-size: 16px; |
| | | |
| | | } |
| | | |
| | | .privacy-bottom .btns .agree { |
| | | width: 440rpx; |
| | | |
| | | } |
| | | </style> |
| | |
| | | } |
| | | |
| | | // WEB_INVOKE_APPSERVICE |
| | | |
| | | |
| | | // 下载图片一次 |
| | | function oneImageDownload(url) { |
| | | return new Promise((resolve, reject) => { |
| | | wx.downloadFile({ |
| | | url, |
| | | success: (res) => { |
| | | wx.saveImageToPhotosAlbum({ |
| | | filePath: res.tempFilePath, |
| | | success: function (res) { |
| | | resolve() |
| | | }, |
| | | }); |
| | | }, |
| | | }); |
| | | }) |
| | | } |
| | | |
| | | // 多次图片下载 |
| | | function multipleImageDownloads(all){ |
| | | // const downloadUrlList = [ |
| | | // // 'https://wrj.shuixiongit.com/aiskyminioTwo/cloud-bucket//089a4039-9c98-4441-abb7-1f9ac56caa8c/DJI_202604270944_002_089a4039-9c98-4441-abb7-1f9ac56caa8c/%E8%BD%A6AI20260427100047007.jpeg', |
| | | // // 'https://aisky.org.cn/command-center-dashboard/assets/zhddpt-BgsJ8s7S.png', |
| | | // 'https://wrj.shuixiongit.com/aiskyminioTwo/cloud-bucket/8d9ba6b4-d255-4f49-b3f8-bdeaf99773b4/DJI_202602121039_002_8d9ba6b4-d255-4f49-b3f8-bdeaf99773b4-flyto/DJI_20260212104641_0003_V.mp4' |
| | | // ] |
| | | const downloadUrlList = all.map(item => { |
| | | return item.replace('aiskyminio', 'aiskyminioTwo') |
| | | }) |
| | | const async = ['https://aisky.org.cn/command-center-dashboard/assets/zhddpt-BgsJ8s7S.png'].map(item => oneImageDownload(item)) |
| | | return Promise.all(async) |
| | | } |
| | | |
| | | // 公共图片下载 |
| | | function publicImageDownloads(data) { |
| | | wx.getSetting({ |
| | | success(res) { |
| | | if (res?.authSetting?.['scope.writePhotosAlbum']) { |
| | | multipleImageDownloads(data.urlList) |
| | | }else{ |
| | | wx.authorize({ |
| | | scope: 'scope.writePhotosAlbum', |
| | | success() { |
| | | multipleImageDownloads(data.urlList) |
| | | } |
| | | }) |
| | | } |
| | | } |
| | | }) |
| | | } |
| | | |
| | | |
| | | // 公共定位 |
| | | function publicPosit(data) { |
| | | wx.openLocation({ |
| | | latitude: data.latitude, |
| | | longitude: data.longitude, |
| | | name: data.name, |
| | | address: data.name, |
| | | scale: 18 |
| | | }) |
| | | } |
| | | |
| | | |
| | | function messageFun(e) { |
| | | if (e.data.type === "WEB_INVOKE_APPSERVICE") { |
| | | if (e.data.data.arg.type === "tokenExpired") { |
| | | return uni.reLaunch({ |
| | | url: "/pages/login/index", |
| | | }); |
| | | const {type,data} = e.data.data.arg |
| | | if (type === "tokenExpired") { |
| | | uni.reLaunch({url: "/pages/login/index"}); |
| | | }else if(type === "wxImageDownload"){ |
| | | publicImageDownloads(data) |
| | | }else if(type === "wxOpenLocation"){ |
| | | publicPosit(data) |
| | | }else{ |
| | | emit("webMessage", e.data.data.arg); |
| | | } |
| | | emit("webMessage", e.data.data.arg); |
| | | } |
| | | } |
| | | |
| | |
| | | // 如果是打包app,需要改这里,h5不需要改这里 |
| | | const development = { |
| | | VITE_APP_ENV:'development', |
| | | // 开发环境这里改为自己的 |
| | | |
| | | // 本地webview |
| | | // VITE_APP_WEBVIEW_URL: 'http://localhost:5175/drone-app-web-view/#/webViewWrapper', |
| | | |
| | | // 测试环境 |
| | | 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_API_BASE_URL: 'https://wrj.shuixiongit.com/api', |
| | | // VITE_API_BASE_URL: 'https://aisky.org.cn/api', |
| | | VITE_APP_WS_API_URL:'wss://wrj.shuixiongit.com/drone-wss/api/v1/ws', |
| | | |
| | | |
| | | // 生产环境 |
| | | // VITE_APP_WEBVIEW_URL: 'https://aisky.org.cn/drone-app-web-view/#/webViewWrapper', |
| | | // VITE_API_BASE_URL: 'https://aisky.org.cn/api', |
| | | // VITE_APP_WS_API_URL: 'wss://aisky.org.cn/drone-wss/api/v1/ws', |
| | | |
| | | // 静态资源存放地址' |
| | | VITE_APP_ASSETS_URL: 'https://wrj.shuixiongit.com/aiskyminio/cloud-bucket/ztzf_app_assets' |
| | | } |
| | |
| | | "<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>", |
| | | "<uses-feature android:name=\"android.hardware.camera\"/>", |
| | | "<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>", |
| | | "<uses-permission android:name=\"android.permission.RECORD_AUDIO\" />" |
| | | "<uses-permission android:name=\"android.permission.RECORD_AUDIO\" />", |
| | | "<uses-permission android:name=\"android.permission.MODIFY_AUDIO_SETTINGS\" />", |
| | | "<uses-permission android:name=\"android.permission.ACCESS_FINE_LOCATION\" />", |
| | | "<uses-permission android:name=\"android.permission.FOREGROUND_SERVICE\" />", |
| | | "<uses-permission android:name=\"android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS\" />", |
| | | "<uses-permission android:name=\"android.permission.SYSTEM_ALERT_WINDOW\" />", |
| | | "<uses-permission android:name=\"android.permission.USE_FULL_SCREEN_INTENT\" />" |
| | | ] |
| | | }, |
| | | /* ios打包配置 */ |
| | |
| | | } |
| | | } |
| | | }, |
| | | "nativePlugins" : { |
| | | } |
| | | "nativePlugins" : {} |
| | | }, |
| | | /* 快应用特有相关 */ |
| | | "quickapp" : {}, |
| | |
| | | "setting" : { |
| | | "urlCheck" : false |
| | | }, |
| | | "usingComponents" : true |
| | | "usingComponents" : true, |
| | | "__usePrivacyCheck__" : true |
| | | }, |
| | | "mp-alipay" : { |
| | | "usingComponents" : true |
| | |
| | | } |
| | | }, |
| | | { |
| | | "path": "downloadPage/index", |
| | | "style": { |
| | | "navigationBarTitleText": "下载" |
| | | } |
| | | }, |
| | | { |
| | | "path": "userDetail/password/index", |
| | | "style": { |
| | | "navigationBarTitleText": "修改密码" |
| | |
| | | "navigationBarBackgroundColor": "#F8F8F8", |
| | | "backgroundColor": "#F8F8F8" |
| | | } |
| | | } |
| | | } |
| | |
| | | <image :src="passwordSvg" /> |
| | | <input |
| | | v-model="loginForm.password" |
| | | type="password" |
| | | type="text" |
| | | :password="showPassword" |
| | | placeholder="请输入密码" |
| | | /> |
| | | <image |
| | | class="pass-word-icon" |
| | | :src="passwordTriggerIcon" |
| | | @click="showPassWord" |
| | | /> |
| | | </div> |
| | | <div class="remember-password"> |
| | |
| | | |
| | | <button class="login-btn" :style="[inputStyle]" @tap="submit">登录</button> |
| | | <image class="lowerRightCorner" :src="droneSvg" /> |
| | | |
| | | <!-- #ifdef MP-WEIXIN --> |
| | | <GetPrivacy |
| | | ref="privacyComponent" |
| | | position="center" |
| | | @allowPrivacy="allowPrivacy" |
| | | /> |
| | | <!-- #endif --> |
| | | </view> |
| | | </template> |
| | | |
| | |
| | | import md5 from "js-md5"; |
| | | import { loginByUsername } from "@/api/user/index.js"; |
| | | import { useUserStore } from "@/store/index.js"; |
| | | |
| | | // #ifdef MP-WEIXIN |
| | | import GetPrivacy from "@/components/GetPrivacy.vue"; |
| | | // #endif |
| | | import { HOME_PATH, LOGIN_PATH, removeQueryString } from "@/router"; |
| | | import { onMounted } from "vue"; |
| | | |
| | |
| | | const usernameSvg = getAssetsImage("/images/login/username.png"); |
| | | const passwordSvg = getAssetsImage("/images/login/password.png"); |
| | | const logoSvg = getAssetsImage("/images/login/logo.png"); |
| | | const passwordShow = getAssetsImage("/images/password-show.png"); |
| | | const passwordHide = getAssetsImage("/images/password-hide.png"); |
| | | |
| | | const userStore = useUserStore(); |
| | | const loginForm = ref({ |
| | |
| | | } |
| | | } |
| | | |
| | | const showPassword = ref(true); |
| | | |
| | | const showPassWord = () => { |
| | | showPassword.value = !showPassword.value; |
| | | }; |
| | | |
| | | const passwordTriggerIcon = computed(() => { |
| | | return showPassword.value ? passwordHide : passwordShow; |
| | | }); |
| | | |
| | | // 从本地存储加载记住的密码 |
| | | onMounted(() => { |
| | | const savedUserInfo = uni.getStorageSync("rememberedUser"); |
| | |
| | | redirect = decodeURIComponent(options.redirect); |
| | | } |
| | | }); |
| | | |
| | | // #ifdef MP-WEIXIN |
| | | const allowPrivacy = () => { |
| | | // 同意隐私协议触发事件,有些接口需要同意授权后才能执行,比如获取手机号授权接口,可以在同意隐私协议后,再执行授权获取手机号接口,如果不需要可以不添加该方法 |
| | | console.log("同意隐私授权"); |
| | | }; |
| | | const privacyComponent = ref(null); |
| | | // onShow(() =>{ |
| | | // wx.getPrivacySetting({ |
| | | // success: res => { |
| | | // console.log(res) |
| | | // if (!res.needAuthorization) { |
| | | // privacyComponent?.value?.closePrivacy() |
| | | // // 查询授权,针对有tab切换的页面,可以在onshow中查询隐私授权状态,判断在tab切换后是否需要关闭授权弹框 |
| | | // console.log('已经同意隐私授权,不需要再次授权') |
| | | // } |
| | | // }, |
| | | // fail: () => {}, |
| | | // complete: () => {} |
| | | // }) |
| | | // }) |
| | | // #endif |
| | | </script> |
| | | |
| | | <style lang="scss" scoped> |
| | |
| | | margin-right: 12rpx; |
| | | } |
| | | |
| | | .pass-word-icon { |
| | | margin-left: 12rpx; |
| | | margin-right: 0; |
| | | } |
| | | |
| | | :deep(uni-input) { |
| | | height: 40rpx; |
| | | line-height: 40rpx; |
| | | width: 80%; |
| | | width: 0; |
| | | flex: 1; |
| | | margin-top: 20rpx; |
| | | padding: 0 !important; |
| | | } |
| | |
| | | :deep(input) { |
| | | height: 40rpx; |
| | | line-height: 40rpx; |
| | | width: 80%; |
| | | width: 0; |
| | | flex: 1; |
| | | margin-top: 20rpx; |
| | | padding: 0 !important; |
| | | margin: 0 !important; |
| | |
| | | <!-- |
| | | * @Author : yuan |
| | | * @Date : 2025-12-03 14:20:57 |
| | | * @LastEditors : yuan |
| | | * @LastEditTime : 2025-12-20 16:49:02 |
| | | * @FilePath : \src\pages\map\index.vue |
| | | * @Description : |
| | | * Copyright 2025 OBKoro1, All Rights Reserved. |
| | | * 2025-12-03 14:20:57 |
| | | --> |
| | | |
| | | <template> |
| | | <view class="page-wrap"> |
| | | <WebViewPlus :src="`${viewUrl}`" @webMessage="onPostMessage" /> |
| | |
| | | import { getWebViewUrl } from "@/utils/index.js"; |
| | | import WebViewPlus from "@/components/WebViewPlus.vue"; |
| | | import { onHide, onShow } from "@dcloudio/uni-app"; |
| | | // const viewUrl = getWebViewUrl("/defaultMap"); |
| | | import {getUserInfo} from "@/api/user/index.js"; |
| | | |
| | | let envParam = ""; |
| | | // #ifdef WEB |
| | |
| | | //新建任务 |
| | | const encodedData = encodeURIComponent(JSON.stringify(data.rowItem)); |
| | | uni.setStorageSync("webview_params", encodedData); |
| | | uni.navigateTo({ |
| | | uni.switchTab({ |
| | | url: `/subPackages/taskDetail/addTask/index`, |
| | | }); |
| | | } else if (data.type === "jumpMapNav") { |
| | |
| | | }; |
| | | |
| | | onShow(() => { |
| | | // 验证一下有没有登录 |
| | | getUserInfo() |
| | | |
| | | // #ifndef MP-WEIXIN |
| | | uni.setTabBarItem({ |
| | | index: 2, // Tab 的索引(从0开始) |
| | |
| | | <script setup> |
| | | import { getAssetsImage } from "@/utils/index.js"; |
| | | import { getUserInfo } from "@/api/user/index.js"; |
| | | import { useClipboard } from "@/hooks"; |
| | | import { useUserStore } from "@/store/index.js"; |
| | | import { onShow } from "@dcloudio/uni-app"; |
| | | import { getDeviceRegionApi } from "@/api/map.js"; |
| | | |
| | | const { setClipboardData, getClipboardData } = useClipboard(); |
| | | |
| | | const rightImage = getAssetsImage("/images/user/rightBtn.png"); |
| | | const logoImage = getAssetsImage("/images/user/logo1.png"); |
| | |
| | | <!-- |
| | | * @Author : yuan |
| | | * @Date : 2025-12-18 10:06:30 |
| | | * @LastEditors : yuan |
| | | * @LastEditTime : 2025-12-20 14:18:42 |
| | | * @FilePath : \src\pages\work\index.vue |
| | | * @Description : |
| | | * Copyright 2025 OBKoro1, All Rights Reserved. |
| | | * 2025-12-18 10:06:30 |
| | | --> |
| | | <template> |
| | | <view class="eventTickets"> |
| | | <WebViewPlus |
| | |
| | | <script setup> |
| | | import { getWebViewUrl } from "@/utils/index.js"; |
| | | import WebViewPlus from "@/components/WebViewPlus.vue"; |
| | | import { useTabAddButton } from "@/hooks/index.js"; |
| | | import { onShow, onHide } from "@dcloudio/uni-app"; |
| | | |
| | | const sWebViewRef = ref(null); |
| | | // const viewUrl = getWebViewUrl('/work', {}) |
| | | const updateKey = ref(0); |
| | | const viewUrl = computed(() => { |
| | | // #ifdef MP-WEIXIN |
| | |
| | | } |
| | | // #endif |
| | | } |
| | | const isApp = ref(false); |
| | | onShow(() => { |
| | | const joinParams = uni.getStorageSync("joinParams"); |
| | | if (joinParams) { |
| | |
| | | }); |
| | | // #endif |
| | | |
| | | // isApp.value = true |
| | | }); |
| | | |
| | | onHide(() => { |
| | | // isApp.value = false |
| | | }); |
| | | </script> |
| | | |
| New file |
| | |
| | | <template> |
| | | <view>下载</view> |
| | | </template> |
| | | |
| | | <script setup> |
| | | |
| | | </script> |
| | | |
| | | |
| | | |
| | | <style scoped lang="scss"> |
| | | |
| | | </style> |
| | |
| | | import {onHide, onLoad, onShow} from "@dcloudio/uni-app"; |
| | | import WebViewPlus from "@/components/WebViewPlus.vue"; |
| | | import {getEnvObj, getWebViewUrl} from "@/utils/index.js"; |
| | | import Recorder from "js-audio-recorder"; |
| | | import dayjs from "dayjs"; |
| | | import {useUserStore} from "@/store/index.js"; |
| | | |
| | | const queryParams = ref({}) |
| | | |
| | | const viewUrl = computed(() => { |
| | | return getWebViewUrl('/DroneConsole', queryParams.value) |
| | | }) |
| | | |
| | | function onPostMessage(data) { |
| | | if (data.type === 'back'){ |
| | | // uni.navigateTo({ |
| | | // url: `/subPackages/inProgress/index?wayLineJobInfoId=${data.taskDetails.id}` |
| | | // }); |
| | | // #ifdef H5 |
| | | window.history.back() |
| | | // #endif |
| | |
| | | }) |
| | | } |
| | | |
| | | const viewUrl = ref(""); |
| | | onLoad((options) => { |
| | | queryParams.value = options |
| | | viewUrl.value = getWebViewUrl("/DroneConsole", { |
| | | wayLineJobInfoId: options.wayLineJobInfoId, |
| | | dockSn: options.dockSn, |
| | | }); |
| | | }) |
| | | |
| | | |
| | |
| | | |
| | | <script setup> |
| | | |
| | | import {onHide, onShow} from "@dcloudio/uni-app"; |
| | | import {useUserStore} from "@/store/index.js"; |
| | | const active = defineModel('active') |
| | | const sWebViewRef = ref(null) |
| | |
| | | |
| | | import {onLoad} from "@dcloudio/uni-app"; |
| | | |
| | | // const active = defineModel('active') |
| | | // console.log(active.value, '555') |
| | | function onPostMessage(event) { |
| | | if (event.detail.data[0].type === 'back'){ |
| | | active.value = null |
| | |
| | | <!-- |
| | | * @Author : yuan |
| | | * @Date : 2025-10-14 17:43:52 |
| | | * @LastEditors : yuan |
| | | * @LastEditTime : 2025-12-19 15:33:48 |
| | | * @FilePath : \src\subPackages\qrCode\index.vue |
| | | * @Description : |
| | | * Copyright 2025 OBKoro1, All Rights Reserved. |
| | | * 2025-10-14 17:43:52 |
| | | --> |
| | | <template> |
| | | <view class="page-wrap"> |
| | | <WebViewPlus :src="`${viewUrl}`" @webMessage="onPostMessage" /> |
| | |
| | | |
| | | const onPostMessage = (data) => { |
| | | if (data.type === "browser") { |
| | | // #ifdef MP-WEIXIN |
| | | |
| | | // #endif |
| | | |
| | | // #ifndef MP-WEIXIN |
| | | uni.navigateTo({ |
| | | url: |
| | |
| | | import { getWebViewUrl } from "@/utils/index.js"; |
| | | import { onHide, onLoad, onShow } from "@dcloudio/uni-app"; |
| | | |
| | | // const viewUrl = ref(getWebViewUrl('/addTask')) |
| | | const sWebViewRef = ref(null); |
| | | const viewUrl = ref(""); |
| | | |
| | | function onPostMessage(data) { |
| | |
| | | uni.setStorageSync("joinParams", { |
| | | type: "add", |
| | | }); |
| | | // console.log('打印新增成功') |
| | | uni.switchTab({ |
| | | url: "/pages/inspectionTask/index", |
| | | }); |
| | | // #endif |
| | | |
| | | // uni.redirectTo({ |
| | | // url: `/pages/inspectionTask/index?addLog=1111` |
| | | // }); |
| | | } |
| | | } |
| | | |
| | | // onLoad( (options) => { |
| | | // console.log(options, '8888') |
| | | // const sns = options.device_sn |
| | | // |
| | | // }); |
| | | const isApp = ref(false); |
| | | |
| | | // #ifdef MP-WEIXIN |
| | |
| | | |
| | | const wayLineJobInfoId = ref(null) |
| | | const viewUrl = ref('') |
| | | // const viewUrl = ref(getWebViewUrl('/execution')) |
| | | |
| | | // function onPostMessage(data) { |
| | | // console.log(data, '9999') |
| | | // if (data.type === 'taskDetails'){ |
| | | // console.log('4444') |
| | | // uni.switchTab({ |
| | | // url: '/subPackages/taskDetail/execution/index' |
| | | // }); |
| | | // } |
| | | // } |
| | | function onPostMessage(data) { |
| | | if (data.type === 'back') { |
| | | uni.switchTab({ |
| | |
| | | }); |
| | | |
| | | onHide(() => { |
| | | // 如果工单详情返回任务详情,那么tab栏对应的是关联事件一项 |
| | | // isApp.value = false |
| | | |
| | | }); |
| | | </script> |
| | | |
| | |
| | | const viewUrl = ref(""); |
| | | const showComponent = ref(false); |
| | | function onPostMessage(data) { |
| | | // #ifdef MP-WEIXIN |
| | | // #endif |
| | | |
| | | // #ifndef MP-WEIXIN |
| | | if (data.type === "back") { |
| | |
| | | <template> |
| | | <view class="container"> |
| | | <div class="avatarBox"> |
| | | <u-avatar @click="uploadAvatar" :src="userInfo.avatar" size="114" mode="aspectFill" /> |
| | | </div> |
| | | <view class="detailBox"> |
| | | <div class="detailCon"> |
| | | <div class="orderRow"> |
| | | <div class="rowTitle">姓名</div> |
| | | <div>{{userInfo.realName}}</div> |
| | | </div> |
| | | <div class="orderRow"> |
| | | <div class="rowTitle">所属单位</div> |
| | | <div>{{userInfo.deptName}}</div> |
| | | </div> |
| | | <div class="orderRow"> |
| | | <div class="rowTitle">手机号</div> |
| | | <u-input input-align="right" v-model="userInfo.phone" type="number" placeholder="请输入手机号" |
| | | class="input-item" /> |
| | | <view class="container"> |
| | | <div class="avatarBox"> |
| | | |
| | | </div> |
| | | <div class="orderRow"> |
| | | <div class="rowTitle">邮箱</div> |
| | | <u-input input-align="right" v-model="userInfo.email" type="email" placeholder="请输入邮箱" |
| | | class="input-item" /> |
| | | </div> |
| | | </div> |
| | | </view> |
| | | <view class="btngroup"> |
| | | <u-button color="#AEAEAE" class="custom-style" shape="circle" @click="reset">重置</u-button> |
| | | <u-button color="#1D6FE9" class="custom-style" shape="circle" @click="submit">提交</u-button> |
| | | </view> |
| | | </view> |
| | | <u-avatar @click="uploadAvatar" :src="userInfo.avatar" size="114" mode="aspectFill"/> |
| | | </div> |
| | | <view class="detailBox"> |
| | | <div class="detailCon"> |
| | | <div class="orderRow"> |
| | | <div class="rowTitle">姓名</div> |
| | | <div>{{ userInfo.realName }}</div> |
| | | </div> |
| | | <div class="orderRow"> |
| | | <div class="rowTitle">所属单位</div> |
| | | <div>{{ userInfo.deptName }}</div> |
| | | </div> |
| | | <div class="orderRow"> |
| | | <div class="rowTitle">手机号</div> |
| | | <u-input input-align="right" v-model="userInfo.phone" type="number" placeholder="请输入手机号" |
| | | class="input-item"/> |
| | | |
| | | </div> |
| | | <div class="orderRow"> |
| | | <div class="rowTitle">邮箱</div> |
| | | <u-input input-align="right" v-model="userInfo.email" type="email" placeholder="请输入邮箱" |
| | | class="input-item"/> |
| | | </div> |
| | | </div> |
| | | </view> |
| | | <view class="btngroup"> |
| | | <u-button color="#AEAEAE" class="custom-style" shape="circle" @click="reset">重置</u-button> |
| | | <u-button |
| | | :color="submitLoading ? '#AEAEAE' : '#1D6FE9'" |
| | | class="custom-style" |
| | | shape="circle" |
| | | text="提交" |
| | | :loading="submitLoading" |
| | | loading-text="提交中" |
| | | loading-mode="circle" |
| | | :loading-size="13" |
| | | @click="submit" |
| | | /> |
| | | </view> |
| | | </view> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { |
| | | getEnvObj, |
| | | getWebViewUrl |
| | | } from "@/utils/index.js"; |
| | | import { |
| | | getUserInfo, |
| | | updateInfo, |
| | | updatePassword |
| | | } from '@/api/user/index.js'; |
| | | import { |
| | | useUserStore |
| | | } from "@/store/index.js"; |
| | | const userInfo = ref({ |
| | | id: '', |
| | | avatar: '', |
| | | realName: '', |
| | | name: '', |
| | | phone: '', |
| | | email: '', |
| | | deptName: '', |
| | | }); |
| | | // 校验手机号 |
| | | const validatePhone = () => { |
| | | const phone = userInfo.value.phone |
| | | if (!phone) return true |
| | | const phoneRegex = /^1[3-9]\d{9}$/ |
| | | if (!phoneRegex.test(phone)) { |
| | | import {getEnvObj} from "@/utils/index.js"; |
| | | import {getUserInfo, updateInfo} from '@/api/user/index.js'; |
| | | import {useUserStore} from "@/store/index.js"; |
| | | import {ref} from "vue"; |
| | | import {onShow} from "@dcloudio/uni-app"; |
| | | |
| | | uni.showToast({ |
| | | title: '请输入正确的手机号码', |
| | | icon: 'none', |
| | | duration: 2000 |
| | | }); |
| | | return false |
| | | } |
| | | return true |
| | | } |
| | | // 校验邮箱 |
| | | const validateEmail = () => { |
| | | if (!userInfo.value.email) return true |
| | | const emailRegex = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/ |
| | | if (!emailRegex.test(userInfo.value.email)) { |
| | | const userInfo = ref({ |
| | | id: '', |
| | | avatar: '', |
| | | realName: '', |
| | | name: '', |
| | | phone: '', |
| | | email: '', |
| | | deptName: '', |
| | | }); |
| | | const submitLoading = ref(false); |
| | | |
| | | uni.showToast({ |
| | | title: '请输入正确的邮箱地址', |
| | | icon: 'none', |
| | | duration: 2000 |
| | | }); |
| | | return false |
| | | } |
| | | return true |
| | | } |
| | | const getUserInfoData = () => { |
| | | getUserInfo().then(res => { |
| | | const user = res.data.data; |
| | | userInfo.value = { |
| | | id: user.id, |
| | | avatar: user.avatar, |
| | | name: user.name, |
| | | realName: user.realName, |
| | | phone: user.phone, |
| | | email: user.email, |
| | | deptName: user.deptName, |
| | | }; |
| | | // 校验手机号 |
| | | const validatePhone = () => { |
| | | const phone = userInfo.value.phone |
| | | if (!phone) return true |
| | | const phoneRegex = /^1[3-9]\d{9}$/ |
| | | if (!phoneRegex.test(phone)) { |
| | | uni.showToast({ |
| | | title: '请输入正确的手机号码', |
| | | icon: 'none', |
| | | duration: 2000 |
| | | }); |
| | | return false |
| | | } |
| | | return true |
| | | } |
| | | |
| | | }); |
| | | }; |
| | | const reset = () => { |
| | | getUserInfoData(); |
| | | }; |
| | | // 校验邮箱 |
| | | const validateEmail = () => { |
| | | if (!userInfo.value.email) return true |
| | | const emailRegex = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/ |
| | | if (!emailRegex.test(userInfo.value.email)) { |
| | | |
| | | const { |
| | | VITE_API_BASE_URL |
| | | } = getEnvObj() |
| | | uni.showToast({ |
| | | title: '请输入正确的邮箱地址', |
| | | icon: 'none', |
| | | duration: 2000 |
| | | }); |
| | | return false |
| | | } |
| | | return true |
| | | } |
| | | |
| | | function uploadUtil(options) { |
| | | const { |
| | | formData, |
| | | filePath, |
| | | url |
| | | } = options; |
| | | const getUserInfoData = () => { |
| | | getUserInfo().then(res => { |
| | | const user = res.data.data; |
| | | userInfo.value = { |
| | | id: user.id, |
| | | avatar: user.avatar, |
| | | name: user.name, |
| | | realName: user.realName, |
| | | phone: user.phone, |
| | | email: user.email, |
| | | deptName: user.deptName, |
| | | }; |
| | | |
| | | return new Promise((resolve, reject) => { |
| | | let accessToken = useUserStore()?.$state?.userInfo?.access_token; |
| | | }); |
| | | }; |
| | | const reset = () => { |
| | | getUserInfoData(); |
| | | }; |
| | | |
| | | uni.uploadFile({ |
| | | url: `${VITE_API_BASE_URL}${url}`, |
| | | name: 'file', |
| | | header: { |
| | | 'Blade-Auth': 'bearer ' + accessToken |
| | | }, |
| | | filePath: filePath, |
| | | formData, |
| | | success: (res) => { |
| | | const resData = JSON.parse(res.data) |
| | | if (resData.code === 200 || resData.code === 0) { |
| | | resolve(res) |
| | | } else { |
| | | showToast(resData.message) |
| | | const { |
| | | VITE_API_BASE_URL |
| | | } = getEnvObj() |
| | | |
| | | reject(res) |
| | | } |
| | | }, |
| | | fail: (err) => { |
| | | reject(err) |
| | | } |
| | | }); |
| | | }) |
| | | } |
| | | const uploadAvatar = () => { |
| | | uni.chooseImage({ |
| | | count: 1, |
| | | success: (res) => { |
| | | const tempFile = res.tempFiles[0]; // 获取文件对象 |
| | | const filePath = tempFile.path || tempFile.tempFilePath; |
| | | if (!filePath) { |
| | | uni.showToast({ |
| | | title: '获取文件路径失败', |
| | | icon: 'none' |
| | | }); |
| | | return; |
| | | } |
| | | let fileName = tempFile.name; |
| | | if (!fileName) { |
| | | const pathWithoutProtocol = filePath.replace(/^file:\/\//, ''); |
| | | fileName = pathWithoutProtocol.split('/').pop() || 'unknown.png'; |
| | | } |
| | | |
| | | // 显示加载中 |
| | | uni.showLoading({ |
| | | title: '上传中...' |
| | | }); |
| | | // 头像上传到服务器 |
| | | function uploadUtil(options) { |
| | | const {formData, filePath, url} = options; |
| | | uni.showLoading({title: '上传中...'}) |
| | | return new Promise((resolve, reject) => { |
| | | let accessToken = useUserStore()?.$state?.userInfo?.access_token; |
| | | uni.uploadFile({ |
| | | url: `${VITE_API_BASE_URL}${url}`, |
| | | name: 'file', |
| | | header: { |
| | | 'Blade-Auth': 'bearer ' + accessToken |
| | | }, |
| | | filePath: filePath, |
| | | formData, |
| | | success: (res) => { |
| | | const resData = JSON.parse(res.data) |
| | | if (resData.code === 200 || resData.code === 0) { |
| | | resolve(res) |
| | | } else { |
| | | uni.showToast(resData.message) |
| | | reject(res) |
| | | } |
| | | }, |
| | | fail: (err) => { |
| | | reject(err) |
| | | }, |
| | | complete: () => { |
| | | uni.hideLoading() |
| | | } |
| | | }); |
| | | }) |
| | | } |
| | | |
| | | // 上传文件 |
| | | uploadUtil({ |
| | | filePath: filePath, |
| | | formData: { |
| | | fileName: fileName, |
| | | sn: 'avatar_upload' |
| | | }, |
| | | url: '/blade-resource/oss/endpoint/put-file' |
| | | }).then(res => { |
| | | const resData = JSON.parse(res.data); |
| | | if (resData.code === 200 || resData.code === 0) { |
| | | // 更新头像显示 |
| | | userInfo.value.avatar = resData.data.link || resData.data.url; |
| | | uni.hideLoading(); |
| | | uni.showToast({ |
| | | title: '头像上传成功', |
| | | icon: 'success' |
| | | }); |
| | | } else { |
| | | throw new Error(resData.message || '上传失败'); |
| | | const handleUploadResult = (filePath, fileName) => { |
| | | uploadUtil({ |
| | | filePath: filePath, |
| | | formData: { |
| | | fileName: fileName, |
| | | sn: 'avatar_upload' |
| | | }, |
| | | url: '/blade-resource/oss/endpoint/put-file' |
| | | }).then(res => { |
| | | const resData = JSON.parse(res.data); |
| | | if (resData.code === 200 || resData.code === 0) { |
| | | // 更新头像显示 |
| | | userInfo.value.avatar = resData.data.link || resData.data.url; |
| | | uni.showToast({title: '头像上传成功', icon: 'success'}); |
| | | } else { |
| | | throw new Error(resData.message || '上传失败'); |
| | | } |
| | | }).catch(err => { |
| | | uni.showToast({title: err.message || '上传失败', icon: 'none'}); |
| | | }); |
| | | }; |
| | | |
| | | } |
| | | }).catch(err => { |
| | | uni.hideLoading(); |
| | | uni.showToast({ |
| | | title: err.message || '上传失败', |
| | | icon: 'none' |
| | | }); |
| | | }); |
| | | } |
| | | }); |
| | | } |
| | | const submit = () => { |
| | | if (!validatePhone() || !validateEmail()) return |
| | | userInfo.value.name = userInfo.value.realName; |
| | | updateInfo(userInfo.value).then(res => { |
| | | if (res.data.code === 200) { |
| | | uni.showToast({ |
| | | title: '修改信息成功', |
| | | icon: 'none', |
| | | duration: 2000 |
| | | }); |
| | | getUserInfoData() |
| | | // 上传头像功能 |
| | | const uploadAvatar = () => { |
| | | // #ifdef MP-WEIXIN |
| | | uni.chooseMedia({ |
| | | count: 1, |
| | | mediaType: ['image'], |
| | | sourceType: ['album', 'camera'], |
| | | maxDuration: 30, |
| | | camera: 'back', |
| | | success(res) { |
| | | const filePath = res.tempFiles[0].tempFilePath; |
| | | handleUploadResult(filePath, filePath); |
| | | } |
| | | }) |
| | | // #endif |
| | | |
| | | } else { |
| | | uni.showToast({ |
| | | title: res.msg, |
| | | icon: 'none', |
| | | duration: 2000 |
| | | }); |
| | | getUserInfoData() |
| | | } |
| | | // #ifndef MP-WEIXIN |
| | | uni.chooseImage({ |
| | | count: 1, |
| | | success: (res) => { |
| | | const tempFile = res.tempFiles[0]; // 获取文件对象 |
| | | const filePath = tempFile.path || tempFile.tempFilePath; |
| | | if (!filePath) { |
| | | uni.showToast({title: '获取文件路径失败', icon: 'none'}); |
| | | return; |
| | | } |
| | | let fileName = tempFile.name; |
| | | if (!fileName) { |
| | | const pathWithoutProtocol = filePath.replace(/^file:\/\//, ''); |
| | | fileName = pathWithoutProtocol.split('/').pop() || 'unknown.png'; |
| | | } |
| | | // 上传文件 |
| | | handleUploadResult(filePath, fileName); |
| | | } |
| | | }); |
| | | // #endif |
| | | } |
| | | const submit = () => { |
| | | if (submitLoading.value) return |
| | | if (!validatePhone() || !validateEmail()) return |
| | | submitLoading.value = true |
| | | userInfo.value.name = userInfo.value.realName; |
| | | updateInfo(userInfo.value).then(res => { |
| | | if (res.data.code === 200) { |
| | | uni.showToast({ |
| | | title: '修改信息成功', |
| | | icon: 'none', |
| | | duration: 1500 |
| | | }); |
| | | setTimeout(() => { |
| | | uni.switchTab({ |
| | | url: '/pages/user/index' |
| | | }); |
| | | }, 1500); |
| | | return |
| | | |
| | | }); |
| | | |
| | | }; |
| | | onShow(async () => { |
| | | getUserInfoData() |
| | | }); |
| | | } else { |
| | | uni.showToast({ |
| | | title: res.msg, |
| | | icon: 'none', |
| | | duration: 2000 |
| | | }); |
| | | getUserInfoData() |
| | | } |
| | | submitLoading.value = false |
| | | }).catch(() => { |
| | | getUserInfoData() |
| | | submitLoading.value = false |
| | | }); |
| | | }; |
| | | onShow(async () => { |
| | | getUserInfoData() |
| | | }); |
| | | </script> |
| | | |
| | | <style lang="scss" scoped> |
| | | .container { |
| | | width: 100%; |
| | | height: 100%; |
| | | display: flex; |
| | | flex-direction: column; |
| | | align-items: center; |
| | | } |
| | | .avatarBox { |
| | | width: 228rpx; |
| | | height: 228rpx; |
| | | margin: 76rpx 0; |
| | | } |
| | | .container { |
| | | width: 100%; |
| | | height: 100%; |
| | | display: flex; |
| | | flex-direction: column; |
| | | align-items: center; |
| | | } |
| | | |
| | | .detailBox { |
| | | width: 702rpx; |
| | | min-height: 430rpx; |
| | | background: #FFFFFF; |
| | | border-radius: 12rpx; |
| | | box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.05); |
| | | .avatarBox { |
| | | width: 228rpx; |
| | | height: 228rpx; |
| | | margin: 76rpx 0; |
| | | } |
| | | |
| | | .detailCon { |
| | | padding: 0 24rpx; |
| | | } |
| | | .detailBox { |
| | | width: 702rpx; |
| | | min-height: 430rpx; |
| | | background: #FFFFFF; |
| | | border-radius: 12rpx; |
| | | box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.05); |
| | | |
| | | .orderRow { |
| | | display: flex; |
| | | justify-content: space-between; |
| | | align-items: center; |
| | | height: 96rpx; |
| | | border-bottom: 2rpx solid #f5f5f5; |
| | | color: #7b7b7b; |
| | | .detailCon { |
| | | padding: 0 24rpx; |
| | | } |
| | | |
| | | .rowTitle { |
| | | font-family: Source Han Sans CN, Source Han Sans CN; |
| | | font-weight: 400; |
| | | font-size: 30rpx; |
| | | color: #222324; |
| | | white-space: nowrap; |
| | | } |
| | | .orderRow { |
| | | display: flex; |
| | | justify-content: space-between; |
| | | align-items: center; |
| | | height: 96rpx; |
| | | border-bottom: 2rpx solid #f5f5f5; |
| | | color: #7b7b7b; |
| | | |
| | | ::v-deep .u-input { |
| | | border: none !important; |
| | | background: transparent !important; |
| | | padding: 0 !important; |
| | | } |
| | | .rowTitle { |
| | | font-family: Source Han Sans CN, Source Han Sans CN; |
| | | font-weight: 400; |
| | | font-size: 30rpx; |
| | | color: #222324; |
| | | white-space: nowrap; |
| | | } |
| | | |
| | | ::v-deep .u-input__input { |
| | | border: none !important; |
| | | box-shadow: none !important; |
| | | background: transparent !important; |
| | | padding: 0 !important; |
| | | margin: 0 !important; |
| | | height: auto !important; |
| | | } |
| | | } |
| | | } |
| | | ::v-deep .u-input { |
| | | border: none !important; |
| | | background: transparent !important; |
| | | padding: 0 !important; |
| | | } |
| | | |
| | | .btngroup { |
| | | display: flex; |
| | | position: absolute; |
| | | bottom: 150rpx; |
| | | } |
| | | ::v-deep .u-input__input { |
| | | border: none !important; |
| | | box-shadow: none !important; |
| | | background: transparent !important; |
| | | padding: 0 !important; |
| | | margin: 0 !important; |
| | | height: auto !important; |
| | | } |
| | | } |
| | | } |
| | | |
| | | :deep(.u-button:first-child) { |
| | | margin-right: 30rpx !important; |
| | | } |
| | | .btngroup { |
| | | display: flex; |
| | | position: absolute; |
| | | bottom: 150rpx; |
| | | } |
| | | |
| | | .custom-style { |
| | | width: 276rpx; |
| | | height: 76rpx; |
| | | } |
| | | :deep(.u-button){ |
| | | width: 276rpx !important; |
| | | height: 76rpx !important; |
| | | } |
| | | </style> |
| | | :deep(.u-button:first-child) { |
| | | margin-right: 30rpx !important; |
| | | } |
| | | |
| | | .custom-style { |
| | | width: 276rpx; |
| | | height: 76rpx; |
| | | } |
| | | |
| | | :deep(.u-button) { |
| | | width: 276rpx !important; |
| | | height: 76rpx !important; |
| | | } |
| | | </style> |
| | |
| | | </view> |
| | | <view class="btngroup"> |
| | | <u-button color="#AEAEAE" class="custom-style" shape="circle" @click="reset">重置</u-button> |
| | | <u-button color="#1D6FE9" class="custom-style" shape="circle" @click="submit">提交</u-button> |
| | | <u-button |
| | | :color="submitLoading ? '#AEAEAE' : '#1D6FE9'" |
| | | class="custom-style" |
| | | shape="circle" |
| | | text="提交" |
| | | :loading="submitLoading" |
| | | loading-text="提交中" |
| | | loading-mode="circle" |
| | | :loading-size="13" |
| | | @click="submit" |
| | | /> |
| | | </view> |
| | | </view> |
| | | </template> |
| | |
| | | newPassword: '', |
| | | newPassword1: '', |
| | | }); |
| | | const submitLoading = ref(false); |
| | | // 校验密码不能包含中文 |
| | | const validatePasswordNoChinese = (password) => { |
| | | const chineseRegex = /[\u4e00-\u9fa5]/; |
| | |
| | | }); |
| | | return false; |
| | | } |
| | | // const hasLetter = /[a-zA-Z]/.test(password); |
| | | // const hasNumber = /\d/.test(password); |
| | | // if (!hasLetter || !hasNumber) { |
| | | // ElMessage.error('密码需同时包含字母和数字'); |
| | | // return false; |
| | | // } |
| | | return true; |
| | | }; |
| | | const clearForm = () => { |
| | |
| | | clearForm(); |
| | | }; |
| | | const submit = () => { |
| | | if (submitLoading.value) return; |
| | | // 原始密码校验 |
| | | if (!passwordForm.value.oldPassword) { |
| | | |
| | |
| | | |
| | | // 复杂度校验 |
| | | if (!validatePasswordStrength(passwordForm.value.newPassword)) return; |
| | | submitLoading.value = true; |
| | | updatePassword(md5(passwordForm.value.oldPassword), |
| | | md5(passwordForm.value.newPassword), |
| | | md5(passwordForm.value.newPassword1)).then(res => { |
| | |
| | | uni.showToast({ |
| | | title: '修改信息成功', |
| | | icon: 'none', |
| | | duration: 2000 |
| | | duration: 1500 |
| | | }); |
| | | clearForm(); |
| | | userStore.setUserInfo(null) |
| | | uni.removeStorageSync('rememberedUser'); |
| | | uni.reLaunch({ |
| | | url: '/pages/login/index' |
| | | }) |
| | | setTimeout(() => { |
| | | uni.reLaunch({ |
| | | url: '/pages/login/index' |
| | | }) |
| | | }, 1500); |
| | | return |
| | | |
| | | } else { |
| | | uni.showToast({ |
| | |
| | | duration: 2000 |
| | | }); |
| | | } |
| | | submitLoading.value = false; |
| | | |
| | | }).catch(() => { |
| | | submitLoading.value = false; |
| | | }); |
| | | |
| | | }; |
| | |
| | | <!-- |
| | | * @Author : yuan |
| | | * @Date : 2025-11-13 18:14:52 |
| | | * @LastEditors : yuan |
| | | * @LastEditTime : 2025-12-20 16:56:27 |
| | | * @FilePath : \src\subPackages\workDetail\addWork\index.vue |
| | | * @Description : |
| | | * Copyright 2025 OBKoro1, All Rights Reserved. |
| | | * 2025-11-13 18:14:52 |
| | | --> |
| | | |
| | | <template> |
| | | <view> |
| | | <WebViewPlus |
| | |
| | | uni.setStorageSync("joinParams", { |
| | | type: "add", |
| | | }); |
| | | // uni.switchTab({ |
| | | // url: '/pages/work/index' |
| | | // }); |
| | | uni.switchTab({ |
| | | url: `/pages/work/index?addLog=111`, |
| | | }); |
| | |
| | | <!-- |
| | | * @Author : yuan |
| | | * @Date : 2025-10-22 14:59:10 |
| | | * @LastEditors : yuan |
| | | * @LastEditTime : 2025-12-19 14:52:54 |
| | | * @FilePath : \src\subPackages\workDetail\mapWork\index.vue |
| | | * @Description : |
| | | * Copyright 2025 OBKoro1, All Rights Reserved. |
| | | * 2025-10-22 14:59:10 |
| | | --> |
| | | |
| | | <!-- 地图展示 --> |
| | | <template> |
| | | <WebViewPlus |
| | |
| | | viewUrl.value = getWebViewUrl("/mapWork", { currentItem: currentItem }); |
| | | }); |
| | | function onPostMessage(data) { |
| | | // #ifdef MP-WEIXIN |
| | | // #endif |
| | | |
| | | // #ifndef MP-WEIXIN |
| | | if (data.type === "workDetailback") { |
| | | // uni.navigateTo({ |
| | | // url: '/subPackages/workDetail/index' |
| | | // }); |
| | | uni.navigateBack({ |
| | | delta: 1, |
| | | }); |