Compare commits

..

4 Commits

Author SHA1 Message Date
lnljyang
fca37014fa 微信一键登录增加appKey参数写死gjt 2026-01-23 11:21:35 +08:00
lnljyang
7eb5bbc012 Merge branch 'main' of https://gitea.lnh2e.com/yanglijie/gjt_mini into dev-ljyang 2026-01-20 16:35:40 +08:00
lnljyang
47d456433e gjt适配版地图 2026-01-20 16:35:30 +08:00
lnljyang
812170fbf6 ln徐版本新UI 2026-01-16 10:36:49 +08:00
7 changed files with 826 additions and 366 deletions

View File

@@ -1,74 +1,155 @@
<template>
<view class="content">
<u-loading-page bg-color="#a7a7a7" :loading="loading"></u-loading-page>
<!-- <view class="bt1 door" @tap="showBtn = true"></view>
<view class="bt2 door" v-if="showBtn" @tap="showUser = true"></view> -->
<image class="logo" src="/static/logo.png"></image>
<view class="helloTip"> Hello! </view>
<view class="helloText"> 欢迎使用广交投氢能车辆运营监控 </view>
<view class="remarkText"> 此小程序仅限氢能车辆运营方内部人员使用 </view>
<view style="width: 80%; margin-top: 80rpx">
<!-- <u-subsection
mode="subsection"
:list="list"
:current="current"
@change="sectionChange"
:fontSize="30"
style="margin-bottom: 20rpx"
></u-subsection> -->
<!-- <view v-if="current == 0">
<login-user></login-user>
</view>
-->
<u-loading-page bg-color="#f0f5ff" :loading="loading"></u-loading-page>
<!-- 顶部Logo区域 -->
<view class="header">
<image class="logo" src="/static/logo.png" mode="aspectFit"></image>
<view class="company-name">广州开发区交通投资集团有限公司</view>
<view class="company-text">广州交通投资集团 氢能车辆运营监控系统</view>
</view>
<view class="loginBlock">
<view class="helloText"> </view>
<view>
<!-- 登录卡片 -->
<view class="login-card">
<view class="form-container">
<login-user></login-user>
</view>
</view>
<view class="agreement-section">
<checkbox-group @change="changeCheck">
<checkbox class="checkbox" :checked="showAgreement">
<view class="label">
阅读并同意<view class="text_link" @tap.stop="privatyShow = true"
>用户服务协议隐私政策</view
>
</view>
</checkbox>
</checkbox-group>
</view>
<!-- <u-popup :show="privatyShow" mode="bottom" @close="privatyShow = false">
<scroll-view scroll-y="true" style="height: 95vh"> -->
<view class="warning-tip">此小程序仅限氢能车辆运营方内部人员使用</view>
<u-popup
:show="privatyShow"
mode="bottom"
@close="privatyShow = false"
round="24"
>
<scroll-view scroll-y="true" style="height: 90vh" class="popup-content">
<view class="content">
<view class="popup-header">
<view class="popup-title">用户服务协议和隐私政策</view>
<view class="close-btn" @tap="privatyShow = false"></view>
</view>
<view class="policy-content">
<view class="section-title">概述</view>
<view class="section-text">
本小程序是由羚牛氢能科技上海有限公司代为开发运营的一款产品以下简称我们帮助解决用户开通搭建小程序公众号网站方面遇到的问题可以达到快速上线的目的我们深知个人信息对您而言的重要性也感谢您对我们的信任我们将通过本政策向您说明互助文档会如何收集存储保护使用及对外提供您的信息并说明您享有的权利其中要点如下
</view>
<view class="point"
>1.
为了便于您了解您在使用我们的服务时我们需要收集的信息类型与用途我们将结合具体服务向您逐一说明</view
>
<view class="point"
>2.
为了向您提供服务所需我们会按照合法正当必要的原则收集您的信息</view
>
<view class="point"
>3.
如果为了向您提供服务而需要将您的信息共享至第三方我们将评估该第三方收集信息的合法性正当性必要性我们将要求第三方对您的信息采取保护措施并严格遵守相关法律法规与监管要求另外我们会按照法律法规及国家标准的要求以确认协议具体场景下的文案确认弹窗提示等形式征得您的同意或确认第三方已经征得您的同意</view
>
<view class="section-title">我们如何收集信息</view>
<view class="section-text">
在您使用互助文档以下各项业务功能以下简称"服务"的过程中我们需要收集您的一些信息用以向您提供服务提升我们的服务质量保障您的账户和资金安全以及符合国家法律法规及监管规定
</view>
<view class="point"
>1.
依据法律法规及监管规定进行实名制管理在您注册互助文档账户或使用互助文档服务时您需提供手机号码或者第三方账号登陆信息作为账户登录名</view
>
<view class="point">2. 身份验证</view>
<view class="sub-point"
>1登录验证为了让您更安全便捷地登录互助文档我们提供自动登陆服务您也可以选择密码登录短信验证码登录等其他方式</view
>
<view class="sub-point"
>2重要操作行为验证为了保障您的账户安全在您进行一些重要的账户操作时例如查看收藏下载应用内资料内容时我们需要验证您的身份为此您可能需向第三方安全服务提供商提交身份验证信息如您不同意提供前述信息您将无法完成特定操作但不影响您使用我们提供的其他服务</view
>
<view class="point">3. 获取外部存储权限获取设备ID, MAC地址</view>
<view class="section-text"
>获取外部存储权限用于记录登录同意的信息下次登录不用重新选择获取设备IDMAC地址设备ID用于记录用户的唯一性MAC地址获取是用于确定用户是属于真实用户</view
>
<view class="section-text"
>本程序嵌入了百度插移动统计分析sdk百度移动SDK隐私政策说明具体隐私政策准则按百度移动SDK隐私为准</view
>
<view class="point">4. 其他</view>
<view class="section-text"
>请您理解我们向您提供的服务是不断更新和发展的如您选择使用了前述说明当中尚未涵盖的其他服务基于该服务我们需要收集您的信息的我们会通过页面提示交互流程协议约定的方式另行向您说明信息收集的范围与目的并征得您的同意我们会按照本政策以及相应的用户协议约定使用存储对外提供及保护您的信息如您选择不提供前述信息您可能无法使用某项或某部分服务但不影响您使用我们提供的其他服务此外第三方主体可能会通过互助文档APP向您提供服务当您进入第三方主体运营的服务页面时请注意相关服务由第三方主体向您提供涉及到第三方主体向您收集个人信息的建议您仔细查看第三方主体的隐私政策或协议约定</view
>
<view class="section-title">我们如何存储和保护信息</view>
<view class="point"
>1.
我们在中华人民共和国境内收集和产生的个人信息将存储在中华人民共和国境内如部分服务涉及跨境业务我们需要向境外机构传输境内收集的相关个人信息的我们会按照法律法规和相关监管部门的规定执行向您说明个人信息出境的目的以及涉及的个人信息类型征得您的同意并通过签订协议现场核查等有效措施要求境外机构为所获得的您的个人信息保密我们仅在本政策所述目的所必需期间和法律法规及监管规定的时限内保存您的个人信息</view
>
<view class="point"
>2.
为了保障您的信息安全我们在收集您的信息后将采取各种合理必要的措施保护您的信息例如在技术开发环境当中我们仅使用经过去标识化处理的信息进行统计分析对外提供研究报告时我们将对报告中所包含的信息进行去标识化处理我们会将去标识化后的信息与可用于恢复识别个人的信息分开存储确保在针对去标识化信息的后续处理中不重新识别个人</view
>
<view class="point"
>3.
我们承诺我们将使信息安全保护达到业界领先的安全水平为保障您的信息安全我们致力于使用各种安全技术及配套的管理体系来尽量降低您的信息被泄露毁损误用非授权访问非授权披露和更改的风险例如通过网络安全层软件SSL进行加密传输信息加密存储严格限制数据中心的访问传输和存储个人敏感信息时我们将采用加密权限控制去标识化等安全措施</view
>
<view class="point"
>4.
请您务必妥善保管好您的互助文档登录名及其他身份要素您在使用互助文档服务时我们会通过您的登录名及其他身份要素来识别您的身份一旦您泄漏了前述信息您可能会蒙受损失并可能对您产生不利如您发现互助文档登录名及/或其他身份要素可能或已经泄露时请您立即和我们取得联系以便我们及时采取相应措施以避免或降低相关损失</view
>
<view class="point"
>5.
在您终止使用互助文档服务后我们会停止对您的信息的收集和使用法律法规或监管部门另有规定的除外如我们停止运营我们将及时停止收集您个人信息的活动将停止运营的通知以逐一送达或公告的形式通知您并对所持有的您的个人信息进行删除或匿名化处理</view
>
</view>
</view>
</scroll-view>
</u-popup>
</view>
</template>
<script>
import loginUser from "./user-login/index.vue";
// import loginDriver from "./driver-login/index.vue";
export default {
options: {
styleIsolation: "shared", // 解除样式隔离
styleIsolation: "shared",
},
components: {
loginUser,
// loginDriver,
},
data() {
return {
loading: false,
current: 0,
list: ["广交投员工", "司机"],
showUser: false,
showBtn: false,
privatyShow: false,
showAgreement: false,
};
},
methods: {
changeCheck(e) {
this.showAgreement = e.detail.value.length > 0;
},
},
onReady() {
// this.getToDo();
const tempIds = ["7NTdeu2Sft31k4wtCGVEjvfvvG3MDxAtUW3g17vv48E"];
wx.getSetting({
withSubscriptions: true,
success(res) {
// console.log(res.authSetting);
// console.log(res.subscriptionsSetting);
if (res.subscriptionsSetting[tempIds[0]] !== "accept") {
uni.showModal({
title: "授权提示",
content: "同意订阅通知消息吗?",
success: (res) => {
console.log(res);
if (res.confirm) {
uni.requestSubscribeMessage({
tmplIds: tempIds, // 需要下发的订阅消息模板id数组
tmplIds: tempIds,
success(res) {
console.log(res);
if (res[tempIds[0]] === "accept") {
console.log("用户同意订阅");
}
@@ -78,23 +159,9 @@ export default {
},
});
}
// res.subscriptionsSetting = {
// mainSwitch: true, // 订阅消息总开关
// itemSettings: { // 每一项开关
// SYS_MSG_TYPE_INTERACTIVE: 'accept', // 小游戏系统订阅消息
// SYS_MSG_TYPE_RANK: 'accept'
// zun-LzcQyW-edafCVvzPkK4de2Rllr1fFpw2A_x0oXE: 'reject', // 普通一次性订阅消息
// ke_OZC_66gZxALLcsuI7ilCJSP2OJ2vWo2ooUPpkWrw: 'ban',
// }
// }
},
});
},
methods: {
sectionChange(index) {
this.current = index;
},
},
};
</script>
@@ -102,86 +169,177 @@ export default {
.content {
display: flex;
flex-direction: column;
height: 100vh;
padding: 40rpx;
background: linear-gradient(0deg, #b6e2fb, #2890e5);
justify-content: center;
min-height: 100vh;
background: #ebefed;
padding: 0;
// background: linear-gradient(0deg, #b6e2fb, #2890e5);
position: relative;
font-family: MiSans-Semibold, MiSans-Demibold, "Segoe UI", Tahoma, Geneva,
Verdana, sans-serif;
}
.helloTip {
font-size: 100rpx;
color: #fff;
font-weight: bold;
margin-top: -200rpx;
}
.helloText {
margin-top: 20rpx;
margin-bottom: 20rpx;
font-size: 46rpx;
color: #fff;
font-weight: 400;
}
.remarkText {
margin-top: 10rpx;
margin-bottom: 20rpx;
font-size: 36rpx;
color: #b54b45;
font-weight: 400;
}
.loginBlock {
display: flex;
flex-direction: column;
justify-content: center;
width: 685rpx;
height: 664rpx;
padding: 0 30rpx;
box-sizing: border-box;
// background-image: url("../../static/login_bg.png");
background-size: cover;
background-color: #fff;
// background: #ffffff;
border-radius: 20rpx;
.helloText {
color: #017043;
text-align: center;
font-weight: bold;
}
}
.logo {
position: absolute;
height: 76rpx;
/* width: 568rpx ; */
top: 40rpx;
right: 40rpx;
// margin-left: auto;
// margin-right: auto;
// margin-bottom: 50rpx;
}
// .door {
// width: 20px;
// height: 20px;
// background: green;
// }
// .bt1 {
// position: absolute;
// top: 10px;
// left: 10px;
// opacity: 0;
// }
// .bt2 {
// position: absolute;
// bottom: 10px;
// left: 10px;
// opacity: 0;
// }
.title {
font-size: 36rpx;
color: #8f8f94;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
"Helvetica Neue", Arial, sans-serif;
}
.login-btn {
margin: 30rpx 0rpx;
.header {
padding: 80rpx 40rpx 60rpx;
text-align: center;
}
.logo {
width: 240rpx;
height: 240rpx;
margin-bottom: 40rpx;
}
.company-name {
margin-bottom: 20rpx;
font-weight: 600;
font-size: 32rpx;
color: #327c4e;
text-align: center;
font-style: normal;
text-transform: none;
}
.company-text {
font-weight: 400;
font-size: 24rpx;
color: rgba(50, 124, 78, 0.4);
text-align: center;
font-style: normal;
text-transform: none;
}
.app-name {
font-size: 28rpx;
color: rgba(255, 255, 255, 0.95);
font-weight: 400;
}
.warning-tip {
font-weight: 400;
font-size: 28rpx;
color: rgba(50, 124, 78, 0.75);
text-align: left;
font-style: normal;
text-align: center;
text-transform: none;
position: absolute;
width: 100%;
bottom: 120rpx;
}
.login-card {
margin: 0 40rpx;
background: #ffffff;
box-shadow: 0rpx 8rpx 4rpx 0rpx rgba(50, 124, 78, 0.05);
border-radius: 20rpx 20rpx 20rpx 20rpx;
padding: 60rpx 50rpx;
backdrop-filter: blur(10rpx);
}
.form-container {
width: 100%;
}
.agreement-section {
margin: 124rpx 40rpx 20rpx;
}
.checkbox {
display: flex;
align-items: flex-start;
font-size: 26rpx;
/deep/ .wx-checkbox-input {
width: 36rpx !important;
height: 36rpx !important;
border-radius: 50% !important;
}
}
.label {
display: flex;
align-items: center;
padding-left: 16rpx;
padding-top: 4rpx;
color: #000;
white-space: nowrap;
}
.text_link {
color: #327c4e;
margin: 0 4rpx;
text-decoration: underline;
display: inline-block;
position: relative;
z-index: 10;
}
.content {
padding: 10px;
}
.popup-header {
display: flex;
align-items: center;
justify-content: center;
position: relative;
padding: 40rpx 0;
border-bottom: 1px solid #e2e8f0;
}
.popup-title {
font-size: 36rpx;
font-weight: 600;
color: #2d3748;
}
.close-btn {
position: absolute;
right: 40rpx;
font-size: 48rpx;
color: #a0aec0;
width: 80rpx;
height: 80rpx;
display: flex;
align-items: center;
justify-content: center;
}
.policy-content {
padding: 40rpx;
max-width: 100%;
box-sizing: border-box;
}
.section-title {
font-size: 32rpx;
font-weight: 600;
color: #2d3748;
margin-top: 40rpx;
margin-bottom: 20rpx;
}
.section-text {
font-size: 28rpx;
color: #4a5568;
line-height: 1.8;
margin-bottom: 20rpx;
text-align: justify;
}
.point {
font-size: 28rpx;
color: #4a5568;
line-height: 1.8;
margin-bottom: 16rpx;
padding-left: 24rpx;
text-align: justify;
}
.sub-point {
font-size: 26rpx;
color: #718096;
line-height: 1.8;
margin-bottom: 12rpx;
padding-left: 48rpx;
text-align: justify;
}
</style>

View File

@@ -8,172 +8,89 @@
:rules="rules"
class="loginForm"
>
<u-form-item prop="loginName">
<u--input
border="surround"
placeholder="账号"
shape="circle"
v-model="formData.loginName"
fontSize="30"
></u--input>
</u-form-item>
<u-form-item prop="pwd">
<u--input
border="surround"
placeholder="密码"
type="password"
shape="circle"
v-model="formData.pwd"
fontSize="30"
></u--input>
</u-form-item>
<view>
<checkbox-group @change="changeCheck">
<checkbox class="checkbox">
<view slot="label">
<view class="label">
阅读并同意
<view class="text_link" @tap="privatyShow = true"
>用户服务协议隐私政策</view
>
</view>
</view>
</checkbox>
</checkbox-group>
<!-- 账号密码输入框 -->
<view v-if="showAccountLogin">
<view class="input-group">
<u-form-item borderBottom>
<u-input
placeholder="请输入账号"
v-model="formData.loginName"
fontSize="30"
border="none"
:customStyle="{
padding: '10rpx 30rpx',
borderRadius: '16rpx',
}"
>
<template #prefix>
<image
src="/static/user.png"
style="width: 20px; height: 20px; margin-right: 8px"
/>
</template>
</u-input>
</u-form-item>
</view>
<view class="input-group">
<u-form-item borderBottom>
<u-input
placeholder="请输入密码"
type="password"
v-model="formData.pwd"
fontSize="30"
border="bottom"
:customStyle="{
padding: '10rpx 30rpx',
borderRadius: '16rpx',
}"
>
<template #prefix>
<image
src="/static/pwd.png"
style="width: 20px; height: 20px; margin-right: 8px"
/>
</template>
</u-input>
</u-form-item>
</view>
</view>
<!-- <view v-if="showAgreement" class="index-privaty">
<van-checkbox checked-color="#4A47E0" value="{{ hasAgreement }}" bind:change="onCheckboxChanged"/>
</view> -->
<view class="login-btn">
<!-- 微信一键登录按钮 -->
<button
v-if="!showAccountLogin"
open-type="getPhoneNumber"
@getphonenumber="getPhoneNumber"
class="u-button u-reset-button u-button--success u-button--square u-button--normal wexin-but"
class="wexin-but"
>
授权登录
微信一键登录
</button>
<!-- 账号密码登录按钮 -->
<u-button
v-if="showAccountLogin"
@click="submit"
plain
color="#017043"
:hairline="false"
color="#327C4E"
:loading="loading"
:disabled="loading"
>{{ `登 录` }}</u-button
shape="circle"
size="large"
:customStyle="{
height: '78rpx',
fontSize: '32rpx',
fontWeight: '500',
}"
>
{{ `登 录` }}
</u-button>
<!-- 切换登录方式文字 -->
<view class="switch-login" @tap="toggleLoginMethod">
{{ showAccountLogin ? "微信快捷登录" : "切换账号登录" }}
</view>
</view>
</u--form>
<u-popup :show="privatyShow" mode="bottom" @close="privatyShow = false">
<scroll-view scroll-y="true" style="height: 95vh">
<view class="content">
<text style="text-align: center">隐私协议</text>
<view>
<text>概述</text>
<text
>本小程序是由羚牛氢能科技上海有限公司开发运营的一款产品以下简称我们帮助解决用户开通搭建小程序公众号网站方面遇到的问题可以达到快速上线的目的我们深知个人信息对您而言的重要性也感谢您对我们的信任我们将通过本政策向您说明互助文档会如何收集存储保护使用及对外提供您的信息并说明您享有的权利其中要点如下</text
>
<view>
<text
>1.
为了便于您了解您在使用我们的服务时我们需要收集的信息类型与用途我们将结合具体服务向您逐一说明</text
>
</view>
<view>
<text
>2.
为了向您提供服务所需我们会按照合法正当必要的原则收集您的信息</text
>
</view>
<view>
<text
>3.
如果为了向您提供服务而需要将您的信息共享至第三方我们将评估该第三方收集信息的合法性正当性必要性我们将要求第三方对您的信息采取保护措施并严格遵守相关法律法规与监管要求另外我们会按照法律法规及国家标准的要求以确认协议具体场景下的文案确认弹窗提示等形式征得您的同意或确认第三方已经征得您的同意</text
>
</view>
<!-- 省略其他条款内容以类似方式嵌入 -->
<view>
<text>我们如何收集信息</text>
<text
>在您使用互助文档以下各项业务功能以下简称服务的过程中我们需要收集您的一些信息用以向您提供服务提升我们的服务质量保障您的账户和资金安全以及符合国家法律法规及监管规定</text
>
<view>
<text
>1.
依据法律法规及监管规定进行实名制管理在您注册互助文档账户或使用互助文档服务时您需提供手机号码或者第三方账号登陆信息作为账户登录名</text
>
</view>
<view>
<text>2. 身份验证</text>
<view>
<text>1登录验证</text>
<text
>为了让您更安全便捷地登录互助文档我们提供自动登陆服务您也可以选择密码登录短信验证码登录等其他方式</text
>
</view>
<view>
<text>2重要操作行为验证</text>
<text
>为了保障您的账户安全在您进行一些重要的账户操作时例如查看收藏下载应用内资料内容时我们需要验证您的身份为此您可能需向第三方安全服务提供商提交身份验证信息如您不同意提供前述信息您将无法完成特定操作但不影响您使用我们提供的其他服务</text
>
</view>
<!-- 省略其他子条款内容以类似方式嵌入 -->
</view>
<!-- 省略其他条款内容以类似方式嵌入 -->
<view>
<text>3. 获取外部存储权限获取设备ID, MAC地址</text>
<text
>获取外部存储权限用于记录登录同意的信息下次登录不用重新选择获取设备IDMAC地址设备ID用于记录用户的唯一性MAC地址获取是用于确定用户是属于真实用户</text
>
<text
>本程序嵌入了百度插移动统计分析sdk百度移动SDK隐私政策说明具体隐私政策准则按百度移动SDK隐私为准</text
>
</view>
<view>
<text>4. 其他</text>
<text
>请您理解我们向您提供的服务是不断更新和发展的如您选择使用了前述说明当中尚未涵盖的其他服务基于该服务我们需要收集您的信息的我们会通过页面提示交互流程协议约定的方式另行向您说明信息收集的范围与目的并征得您的同意我们会按照本政策以及相应的用户协议约定使用存储对外提供及保护您的信息如您选择不提供前述信息您可能无法使用某项或某部分服务但不影响您使用我们提供的其他服务此外第三方主体可能会通过互助文档APP向您提供服务当您进入第三方主体运营的服务页面时请注意相关服务由第三方主体向您提供涉及到第三方主体向您收集个人信息的建议您仔细查看第三方主体的隐私政策或协议约定</text
>
</view>
</view>
<view>
<text>我们如何存储和保护信息</text>
<view>
<text
>1.
我们在中华人民共和国境内收集和产生的个人信息将存储在中华人民共和国境内如部分服务涉及跨境业务我们需要向境外机构传输境内收集的相关个人信息的我们会按照法律法规和相关监管部门的规定执行向您说明个人信息出境的目的以及涉及的个人信息类型征得您的同意并通过签订协议现场核查等有效措施要求境外机构为所获得的您的个人信息保密我们仅在本政策所述目的所必需期间和法律法规及监管规定的时限内保存您的个人信息</text
>
</view>
<view>
<text
>2.
为了保障您的信息安全我们在收集您的信息后将采取各种合理必要的措施保护您的信息例如在技术开发环境当中我们仅使用经过去标识化处理的信息进行统计分析对外提供研究报告时我们将对报告中所包含的信息进行去标识化处理我们会将去标识化后的信息与可用于恢复识别个人的信息分开存储确保在针对去标识化信息的后续处理中不重新识别个人</text
>
</view>
<view>
<text
>3.
我们承诺我们将使信息安全保护达到业界领先的安全水平为保障您的信息安全我们致力于使用各种安全技术及配套的管理体系来尽量降低您的信息被泄露毁损误用非授权访问非授权披露和更改的风险例如通过网络安全层软件SSL进行加密传输信息加密存储严格限制数据中心的访问传输和存储个人敏感信息时我们将采用加密权限控制去标识化等安全措施</text
>
</view>
<view>
<text
>4.
请您务必妥善保管好您的互助文档登录名及其他身份要素您在使用互助文档服务时我们会通过您的登录名及其他身份要素来识别您的身份一旦您泄漏了前述信息您可能会蒙受损失并可能对您产生不利如您发现互助文档登录名及/或其他身份要素可能或已经泄露时请您立即和我们取得联系以便我们及时采取相应措施以避免或降低相关损失</text
>
</view>
<view>
<text
>5.
在您终止使用互助文档服务后我们会停止对您的信息的收集和使用法律法规或监管部门另有规定的除外如我们停止运营我们将及时停止收集您个人信息的活动将停止运营的通知以逐一送达或公告的形式通知您并对所持有的您的个人信息进行删除或匿名化处理</text
>
</view>
</view>
</view>
</view>
</scroll-view>
</u-popup>
</view>
</template>
@@ -182,13 +99,12 @@ import { setToken, setUser } from "@/utils/auth.js";
import en from "@/utils/key.js";
export default {
options: {
styleIsolation: "shared", // 解除样式隔离
styleIsolation: "shared",
},
data() {
return {
loading: false,
privatyShow: false,
showAgreement: false,
showAccountLogin: false, // 默认显示微信登录
formData: {
loginName: "",
pwd: "",
@@ -212,17 +128,12 @@ export default {
};
},
methods: {
changeCheck(e) {
if (e.detail.value.length > 0) {
this.showAgreement = true;
} else {
this.showAgreement = false;
}
// 切换登录方式
toggleLoginMethod() {
this.showAccountLogin = !this.showAccountLogin;
},
getPhoneNumber(data) {
// 获取手机号
//debugger;
if (!this.showAgreement) {
if (!this.$parent.showAgreement) {
uni.showToast({
title: "请先勾选用户协议",
icon: "none",
@@ -235,12 +146,11 @@ export default {
this.loading = true;
wx.login({
success: function (resp) {
console.log(resp);
//var userInfo = res.userInfo;
_this.$api.login
.loginByPhoneForDriver({
phoneCode: data.detail.code,
sessionCode: resp.code,
appKey: "gjt",
})
.then((res) => {
const result = res;
@@ -249,7 +159,7 @@ export default {
_this.getUserMenu();
setUser(result.userInfo);
uni.switchTab({
url: "/pages/index/index",
url: "/pages/map/index",
});
})
.catch((errors) => {
@@ -263,7 +173,6 @@ export default {
await this.$api.login
.getUserMenu()
.then((res) => {
console.log(res);
this.$store.dispatch("setResources", res);
})
.catch((err) => {
@@ -271,7 +180,7 @@ export default {
});
},
submit() {
if (!this.showAgreement) {
if (!this.$parent.showAgreement) {
uni.showToast({
title: "请先勾选用户协议",
icon: "none",
@@ -285,8 +194,6 @@ export default {
const _this = this;
wx.login({
success: function (resp) {
console.log(resp);
//var userInfo = res.userInfo;
_this.$api.login
.loginUser({
loginName: _this.formData.loginName,
@@ -300,7 +207,7 @@ export default {
_this.getUserMenu();
setTimeout(() => {
uni.switchTab({
url: "/pages/index/index",
url: "/pages/map/index",
});
}, 500);
})
@@ -314,7 +221,6 @@ export default {
},
onReady() {
try {
//如果需要兼容微信小程序并且校验规则中含有方法等只能通过setRules方法设置规则。
this.$refs.uForm.setRules(this.rules);
} catch (e) {}
},
@@ -322,51 +228,45 @@ export default {
</script>
<style lang="less" scoped>
/deep/ .u-input--circle {
background-color: #f5f6fa !important;
padding-left: 20px !important;
}
/deep/ .u-button {
border: none !important;
color: #017043;
margin-top: 10rpx;
width: auto;
}
.content {
padding: 10px;
}
.checkbox {
display: flex;
font-size: 28rpx;
.label {
display: flex;
padding-top: 5rpx;
flex-wrap: wrap;
}
.text_link {
color: #4a47e0;
}
.loginForm {
width: 100%;
}
/deep/ .wx-checkbox-input {
width: 36rpx !important;
height: 36rpx !important;
.input-group {
margin-bottom: 30rpx;
}
.login-btn {
margin-top: 40rpx;
}
.wexin-but {
width: 100%;
height: 78rpx;
// background: linear-gradient(135deg, #2890e5 0%, #667eea 100%);
color: white;
font-size: 32rpx;
//border-radius: 48rpx;
//border: none;
font-weight: 500;
//box-shadow: 0 8rpx 24rpx rgba(40, 144, 229, 0.4);
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
background: #327c4e;
border-radius: 198rpx 198rpx 198rpx 198rpx;
border: 2rpx solid rgba(255, 255, 255, 0.2);
}
.switch-login {
margin-top: 30rpx;
text-align: center;
padding: 0 80rpx;
.wexin-but {
// width: 80%;
margin-top: 40rpx;
padding: 0rpx 122rpx;
border-radius: 50rpx;
box-sizing: border-box;
background-color: #017043;
color: white;
font-size: 38rpx;
}
font-size: 28rpx;
color: #327c4e;
text-decoration: underline;
}
/deep/ .u-form-item {
margin-bottom: 0;
}
</style>

View File

@@ -63,7 +63,7 @@
</view>
<ba-tree-picker
ref="treePicker"
:isShowOrgPicker="_showOrgPicker"
:isShowOrgPicker="false"
@select-change="selectChange"
@emitOrgId="emitOrgId"
:title="` `"
@@ -80,7 +80,7 @@
@beforeleave="onBeforeLeave"
>
<!-- @afterShow="onAfterShow"
@afterHide="onAfterHide" -->
@afterHide="onAfterHide" -->
<view class="right-panel" @tap.native.stop="banIosChuanTou">
<view class="panel-header">
<view class="panel-title"
@@ -89,13 +89,14 @@
<view v-if="current === 0"
>当前数量:{{ _clusterSelList.length || 0 }}()</view
>
<view v-else>当前数量:{{ _clusterSelList.length || 0 }}()</view>
<view class="close-btn" @tap="checkListShow = false">
<u-icon name="close" color="#333" size="22"></u-icon>
</view>
</view>
<view v-if="current === 0" class="tableOption">
<view class="optionItem">
<view
<!-- <view
class="item right-u-popup u-border"
style="border-radius: 4px"
>
@@ -127,7 +128,7 @@
</view>
</template>
</u-input>
</view>
</view> -->
<view
class="item right-u-popup u-border"
style="border-radius: 4px"
@@ -150,8 +151,41 @@
</template>
</u-input>
</view>
<view
class="item right-u-popup u-border"
style="border-radius: 4px; flex: 1"
>
<u-picker
:show="showTruckTypePicker"
:columns="[_truckTypeList]"
keyName="nameAndCount"
@confirm="confirmTruckType"
:immediateChange="true"
@cancel="showTruckTypePicker = false"
>
</u-picker>
<u-input
v-model="truckTypeName"
border="surround"
:disabledColor="'#ffffff'"
style="font-size: 13px"
disabled
placeholder="请选择车辆型号"
@tap="showTruckTypePicker = true"
>
<template slot="suffix">
<view
class="close-btn"
v-if="truckTypeName"
@tap.stop="clearClickTruckType"
>
<u-icon name="close" color="#333" size="20"></u-icon>
</view>
</template>
</u-input>
</view>
</view>
<view class="optionItem">
<!-- <view class="optionItem">
<view
class="item right-u-popup u-border"
style="border-radius: 4px"
@@ -218,9 +252,38 @@
</template>
</u-input>
</view>
</view> -->
<view class="optionItem">
<!-- 占位的空div保持布局一致性 -->
<view
v-if="
current === 0 &&
isMapResetForTruck &&
hasClickedBackRightForTruck
"
class="item"
style="flex: 1"
></view>
<view
v-if="
current === 0 &&
!isMapResetForTruck &&
!hasClickedBackRightForTruck
"
class="item"
style="display: flex; align-items: center"
>
全部车辆:
<u-switch
size="58"
activeColor="#2F6D47"
v-model="allTruckSwitch"
@change="changeSwitch"
></u-switch>
</view>
</view>
</view>
<view v-else class="tableOption">
<view v-else class="tableOption" style="padding-top: 10px">
<view class="optionItem">
<view
class="item right-u-popup u-border"
@@ -255,9 +318,33 @@
</template>
</u-input>
</view>
<view
v-if="
current === 1 &&
!isMapResetForHydrogen &&
!hasClickedBackRightForHydrogen
"
class="item"
style="display: flex; align-items: center"
>
全部加氢站:
<u-switch
size="58"
activeColor="#2F6D47"
v-model="allHydrogenSwitch"
@change="changeSwitchHydrogen"
></u-switch>
</view>
</view>
</view>
<scroll-view scroll-y="true" style="height: calc(100vh - 200px)">
<scroll-view
ref="scrollView"
scroll-y="true"
:scroll-top="scrollTop"
style="height: calc(100vh - 200px)"
@scrolltolower="loadMoreData"
@scroll="onScroll"
>
<view class="rightPop">
<view
v-if="current === 0"
@@ -303,11 +390,11 @@
<view class="demo-layout">仪表盘</view>
</u-col>
<u-col span="3">
<view class="demo-layout">部门</view>
<view class="demo-layout">车型</view>
</u-col>
</u-row>
<view
v-for="(item, index) in _clusterSelList"
v-for="(item, index) in virtualClusterList"
class="clusterItem"
:key="index"
>
@@ -346,10 +433,39 @@
</view>
</view>
<view class="item" v-if="current === 0">{{
item.shortDepName || "--"
item.noticeModel || "--"
}}</view>
</view>
</view>
<!-- 虚拟滚动加载控制 -->
<view
v-if="
virtualClusterList.length > 0 &&
_clusterSelList.length > virtualScrollPageSize
"
class="load-more-controls"
>
<view class="load-more-info">
已加载 {{ virtualClusterList.length }} /
{{ _clusterSelList.length }} 条
</view>
<view v-if="virtualScrollHasMore" class="load-more-button">
<view
class="load-more-btn"
:class="{ loading: virtualScrollLoading }"
@tap="loadMoreData"
>
<text v-if="!virtualScrollLoading">加载更多</text>
<view v-else class="loading-content">
<text class="loading-text">加载中</text>
<text class="loading-dot">.</text>
<text class="loading-dot">.</text>
<text class="loading-dot">.</text>
</view>
</view>
</view>
<view v-else class="no-more-data"> 已加载全部数据 </view>
</view>
<!-- <view>查看详细分布</view> -->
</view>
</scroll-view>
@@ -368,7 +484,6 @@
@tap="resetMap"
></image>
<image
v-if="clusterSelList && clusterSelList.length > 0"
src="/static/expand-left-line.png"
style="
position: absolute;
@@ -403,14 +518,14 @@
<cover-view class="popup" v-if="showPopup">
<cover-view class="popup-header">
<!-- <cover-view style="display: flex" :show-location="true"
><cover-image
:src="
current === 0 ? '/static/kachetou.png' : '/static/jiaqingzhan.png'
"
style="width: 40rpx; height: 40rpx; margin: 5px"
></cover-image
>1111</cover-view
> -->
><cover-image
:src="
current === 0 ? '/static/kachetou.png' : '/static/jiaqingzhan.png'
"
style="width: 40rpx; height: 40rpx; margin: 5px"
></cover-image
>1111</cover-view
> -->
<cover-view style="display: flex; padding: 5px; flex: 1">
<cover-image
:src="
@@ -576,8 +691,27 @@ export default {
plateNumberInput: "", //车牌号输入框
departList: [], //业务部门
departName: "", //业务部门
truckTypeList: [], //车辆类型
showDepartPicker: false, //是否业务部门选择器
showTruckTypePicker: false, //是否车辆型号选择器
truckTypeName: "", //车辆型号名称
showAllVehicles: false, //是否显示全部车辆
originalClusterList: [], //保存切换前的clusterSelList
mileageSortOrder: "desc", // 行驶里程排序方向desc-从大到小asc-从小到大
backRightTimer: null, // backRight方法的防抖定时器
allTruckSwitch: false, //是否显示全部车辆
allHydrogenSwitch: false, //是否显示全部加氢站
originalHydrogenList: [], //保存切换前的加氢站列表
virtualScrollPageSize: 150, // 虚拟滚动每页显示数量
virtualScrollCurrentPage: 1, // 虚拟滚动当前页码
virtualScrollTotalPages: 1, // 虚拟滚动总页数
virtualScrollLoading: false, // 是否正在加载下一页
virtualScrollHasMore: true, // 是否还有更多数据
scrollTop: 0, // 滚动位置
isMapResetForTruck: true, // 车辆是否为重置地图状态
isMapResetForHydrogen: true, // 加氢站是否为重置地图状态
hasClickedBackRightForTruck: false, // 车辆是否已经点击过backRight
hasClickedBackRightForHydrogen: false, // 加氢站是否已经点击过backRight
};
},
computed: {
@@ -587,6 +721,22 @@ export default {
"vehicle" //按钮在基础信息菜单的车辆信息下面
);
},
// 虚拟滚动显示的数据
virtualClusterList() {
const endIndex =
this.virtualScrollCurrentPage * this.virtualScrollPageSize;
return this._clusterSelList.slice(0, endIndex);
},
// 虚拟滚动总页数
virtualScrollTotalPages() {
return Math.ceil(
this._clusterSelList.length / this.virtualScrollPageSize
);
},
// 是否还有更多数据
virtualScrollHasMore() {
return this.virtualClusterList.length < this._clusterSelList.length;
},
_showOrgPicker() {
return this.chooseCompany && this.current === 0;
},
@@ -617,6 +767,18 @@ export default {
});
return arr.filter((item) => item.carNumber) || [];
},
_truckTypeList() {
const arr = this.truckTypeList.map((item) => {
const carNumber =
this.clusterSelList.filter((t) => {
return t.noticeModel === item.dicName;
})?.length || 0;
item.carNumber = carNumber;
item.nameAndCount = item.dicName + " (" + carNumber + ")";
return item;
});
return arr.filter((item) => item.carNumber) || [];
},
_areaList() {
const arr = this.areaList.map((item) => {
const carNumber =
@@ -641,6 +803,8 @@ export default {
item.plateNumber?.toString().indexOf(this.areaName) > -1) &&
(this.departName === "" ||
this.departName?.toString().indexOf(item.shortDepName) > 0) &&
(this.truckTypeName === "" ||
item.noticeModel === this.truckTypeName) &&
(this.plateNumberInput === "" ||
item.plateNumber?.toString().indexOf(this.plateNumberInput) >
-1)
@@ -674,6 +838,7 @@ export default {
this.getOrgList();
this.getAreaList();
this.getDepartList();
this.getTruckType();
this.getCoopList();
// this.getVehicleMarkers();
//this.gotoMap();
@@ -684,6 +849,11 @@ export default {
clearTimeout(this.popTimer);
this.popTimer = null;
}
// 清理backRight防抖定时器
if (this.backRightTimer) {
clearTimeout(this.backRightTimer);
this.backRightTimer = null;
}
// 清理地图事件监听器
if (this._mapContext) {
// 直接移除所有监听器,不需要传递回调函数
@@ -698,6 +868,76 @@ export default {
},
methods: {
changeSwitch(e) {
console.log("change", e);
if (e) {
// 开启开关,保存当前数据并显示全部
this.originalClusterList = [...this.clusterSelList];
this.clusterSelList = [...this.covers];
this.virtualScrollCurrentPage = 1; // 重置到第一页
this.$nextTick(() => {
this.resetScrollPosition();
});
} else {
// 关闭开关,恢复原始数据
this.clusterSelList = [...this.originalClusterList];
this.virtualScrollCurrentPage = 1; // 重置到第一页
this.$nextTick(() => {
this.resetScrollPosition();
});
}
},
changeSwitchHydrogen(e) {
console.log("changeSwitchHydrogen", e);
if (e) {
// 开启开关,保存当前数据并显示全部
this.originalHydrogenList = [...this.clusterSelList];
this.clusterSelList = [...this.covers];
this.virtualScrollCurrentPage = 1; // 重置到第一页
this.$nextTick(() => {
this.resetScrollPosition();
});
} else {
// 关闭开关,恢复原始数据
this.clusterSelList = [...this.originalHydrogenList];
this.virtualScrollCurrentPage = 1; // 重置到第一页
this.$nextTick(() => {
this.resetScrollPosition();
});
}
},
// 滚动事件处理
onScroll(e) {
if (this.virtualScrollLoading || !this.virtualScrollHasMore) return;
const { scrollTop, scrollHeight, clientHeight } = e.detail;
// 当滚动到三分之二位置时触发加载
const threshold = scrollHeight * (2 / 3);
if (scrollTop + clientHeight >= threshold) {
this.loadMoreData();
}
},
// 加载更多数据
loadMoreData() {
if (this.virtualScrollLoading || !this.virtualScrollHasMore) return;
this.virtualScrollLoading = true;
// 模拟网络延迟,实际项目中可以移除
setTimeout(() => {
this.virtualScrollCurrentPage++;
this.virtualScrollLoading = false;
}, 300);
},
// 重置滚动位置到顶部
resetScrollPosition() {
// 先设置为非0值再设置为0确保触发滚动
this.scrollTop = 1;
this.$nextTick(() => {
this.scrollTop = 0;
});
},
banIosChuanTou() {
// 阻止iOS事件穿透到地图
console.log("阻止事件穿透");
@@ -728,6 +968,9 @@ export default {
clearClickDepart() {
this.departName = ""; // 重置业务部门
},
clearClickTruckType() {
this.truckTypeName = ""; // 重置车辆型号
},
clearClick() {
this.orgName = ""; // 重置组织名称
},
@@ -765,6 +1008,12 @@ export default {
this.areaList = res || [];
});
},
getTruckType() {
this.truckTypeName = "";
this.$api.standbyVehicle.getTruckType().then((res) => {
this.truckTypeList = res || [];
});
},
getDepartList() {
this.departName = ""; //
this.$api.map.getOwnDepartDic().then((res) => {
@@ -784,6 +1033,12 @@ export default {
this.departName = e.value[0].dicName;
console.log(this.areaName);
},
confirmTruckType(e) {
console.log("confirmTruckType:\n", e.value[0]);
this.showTruckTypePicker = false;
this.truckTypeName = e.value[0].dicName;
},
clearClickCoop() {
this.CoopName = "";
this.CoopCode = "";
@@ -802,18 +1057,57 @@ export default {
this.showCoopPicker = false;
},
resetMap() {
this.isMapResetForTruck = true;
this.isMapResetForHydrogen = true;
this.hasClickedBackRightForTruck = false;
this.hasClickedBackRightForHydrogen = false;
this.sectionChange(this.current, {});
},
backRight() {
if (this.clusterSelList && this.clusterSelList.length > 0) {
//this.includePoints = this.clusterSelList; //返回聚合点视图
this.checkListShow = true;
this._mapContext.includePoints({
points: this.clusterSelList,
padding: [50, 50, 50, 50],
});
this.showPopup = false; //关闭底部弹窗
// 防抖处理
if (this.backRightTimer) {
clearTimeout(this.backRightTimer);
}
this.backRightTimer = setTimeout(() => {
this.executeBackRight();
}, 300);
},
executeBackRight() {
if (!this.clusterSelList || this.clusterSelList.length === 0) {
this.clusterSelList = this.covers;
}
// 如果是重置地图后第一次点击backRight隐藏对应的switch
if (
this.current === 0 &&
this.isMapResetForTruck &&
!this.hasClickedBackRightForTruck
) {
this.hasClickedBackRightForTruck = true;
} else if (
this.current === 1 &&
this.isMapResetForHydrogen &&
!this.hasClickedBackRightForHydrogen
) {
this.hasClickedBackRightForHydrogen = true;
}
this.checkListShow = true;
this._mapContext.includePoints({
points: this.clusterSelList,
padding: [50, 50, 50, 50],
});
this.showPopup = false; //关闭底部弹窗
this.resetScrollPosition(); // 重置滚动位置
// if (this.clusterSelList && this.clusterSelList.length > 0) {
// //this.includePoints = this.clusterSelList; //返回聚合点视图
// this.checkListShow = true;
// this._mapContext.includePoints({
// points: this.clusterSelList,
// padding: [50, 50, 50, 50],
// });
// this.showPopup = false; //关闭底部弹窗
// }
},
// 显示选择器
async showPicker() {
@@ -1157,6 +1451,19 @@ export default {
hydrogenStationName: "",
hydrogenStationId: "",
};
// 重置switch状态
this.allTruckSwitch = false;
this.allHydrogenSwitch = false;
// 重置对应视图的首次点击状态
if (index === 0) {
this.isMapResetForTruck = true;
this.hasClickedBackRightForTruck = false;
} else {
this.isMapResetForHydrogen = true;
this.hasClickedBackRightForHydrogen = false;
}
let obj = params || undefined;
if (index === 0) {
await this.getVehicleMarkers(obj);
@@ -1250,15 +1557,34 @@ export default {
//点击聚合簇时,清除筛选条件
this.orgName = "";
this.areaName = "";
this.truckTypeName = "";
this.allTruckSwitch = false; // 重置显示全部开关
} else {
this.CoopName = "";
this.CoopCode = "";
this.allHydrogenSwitch = false; // 重置显示全部加氢站开关
}
const numCluster = res.cluster.markerIds.map((item) => Number(item));
this.clusterSelList =
this.covers.filter((item) => numCluster.includes(item.hashCode)) ||
[];
// 重置switch状态因为现在有具体的clusterSelList了
this.allTruckSwitch = false;
this.allHydrogenSwitch = false;
// 设置为非重置地图状态,只重置当前视图的状态
if (this.current === 0) {
this.isMapResetForTruck = false;
this.hasClickedBackRightForTruck = false;
} else {
this.isMapResetForHydrogen = false;
this.hasClickedBackRightForHydrogen = false;
}
this.virtualScrollCurrentPage = 1; // 重置到第一页
this.resetScrollPosition(); // 重置滚动位置
console.log("聚合簇点击", this.clusterSelList);
});
},
@@ -1654,5 +1980,81 @@ export default {
}
}
}
// 虚拟滚动加载样式
.load-more-controls {
display: flex;
flex-direction: column;
align-items: center;
padding: 12px 0;
background-color: #f8f9fa;
border-top: 1px solid #e9ecef;
.load-more-info {
font-size: 12px;
color: #999;
margin-bottom: 8px;
}
.load-more-button {
.load-more-btn {
padding: 6px 20px;
font-size: 12px;
background-color: #f0f0f0;
color: #666;
border-radius: 15px;
border: none;
transition: all 0.3s ease;
&.loading {
background-color: #f0f0f0;
color: #999;
.loading-content {
display: flex;
align-items: center;
.loading-text {
margin-right: 2px;
}
.loading-dot {
animation: loadingDot 1.4s infinite ease-in-out both;
&:nth-child(2) {
animation-delay: -0.32s;
}
&:nth-child(3) {
animation-delay: -0.16s;
}
}
}
}
&:active {
background-color: #e0e0e0;
transform: scale(0.98);
}
}
}
.no-more-data {
font-size: 12px;
color: #bbb;
padding: 6px 0;
}
}
@keyframes loadingDot {
0%,
80%,
100% {
opacity: 0.3;
}
40% {
opacity: 1;
}
}
}
</style>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 41 KiB

After

Width:  |  Height:  |  Size: 17 KiB

BIN
static/logo22.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

BIN
static/pwd.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 626 B

BIN
static/user.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 691 B