refactor: 重构多个组件以支持 Vue 3 语法和功能

- 将多个组件转换为 `<script setup>` 语法,提升可读性和性能
- 优化状态管理和事件处理逻辑,简化代码结构
- 更新样式和布局以适应新组件结构
- 添加新功能和修复已知问题,提升用户体验
This commit is contained in:
Yer11214
2026-07-08 18:37:11 +08:00
parent 4d0b0fb5e4
commit 349ffa4f34
189 changed files with 18278 additions and 20758 deletions

View File

@@ -16,7 +16,7 @@
<u-cell-group class="cell-group" :border="false">
<!-- #ifdef APP-PLUS -->
<u-cell v-if="IosWhether" is-link title="去评分" @click="checkStar"></u-cell>
<u-cell v-if="showIosRating" is-link title="去评分" @click="openAppStoreRating"></u-cell>
<u-cell is-link title="功能介绍" @click="navigateTo('/pages/mine/set/versionFunctionList')"></u-cell>
<u-cell is-link title="检查更新" @click="checkUpdate"></u-cell>
<!-- #endif -->
@@ -40,93 +40,72 @@
</view>
</template>
<script>
import APPUpdate from "@/plugins/APPUpdate";
import config from "@/config/config";
import { getAppVersion } from "@/api/message.js";
export default {
data() {
return {
config,
IosWhether: false,
editionHistory: [],
versionData: {},
localVersion: "",
params: {
pageNumber: 1,
pageSize: 5,
},
};
},
onLoad() {
// #ifdef APP-PLUS
const platform = uni.getSystemInfoSync().platform;
if (platform === "android") {
this.params.type = 0;
} else {
this.IosWhether = true;
this.params.type = 1;
<script setup lang="ts">
import { ref } from 'vue'
import { onLoad } from '@dcloudio/uni-app'
import APPUpdate from '@/plugins/APPUpdate'
import config from '@/config/config'
import { getAppVersion } from '@/api/message.js'
const showIosRating = ref(false)
const versionData = ref<Record<string, any>>({})
const localVersion = ref<Record<string, any>>({})
const params = ref<Record<string, any>>({ pageNumber: 1, pageSize: 5 })
onLoad(() => {
// #ifdef APP-PLUS
const platform = uni.getSystemInfoSync().platform
if (platform === 'android') {
params.value.type = 0
} else {
showIosRating.value = true
params.value.type = 1
}
fetchRemoteVersion(platform)
plus.runtime.getProperty(plus.runtime.appid, (inf) => {
localVersion.value = {
versionCode: inf.version.replace(/\./g, ''),
version: inf.version,
}
this.getVersion(platform);
})
// #endif
plus.runtime.getProperty(plus.runtime.appid, (inf) => {
this.localVersion = {
versionCode: inf.version.replace(/\./g, ""),
version: inf.version,
};
});
// #endif
// #ifdef MP-WEIXIN
const accountInfo = wx.getAccountInfoSync()
localVersion.value = {
versionCode: accountInfo.miniProgram.version.replace(/\./g, ''),
version: accountInfo.miniProgram.version,
envVersion: accountInfo.miniProgram.envVersion,
}
// #endif
})
// #ifdef MP-WEIXIN
const accountInfo = wx.getAccountInfoSync();
this.version_number = accountInfo.miniProgram.version;
this.localVersion = {
versionCode: accountInfo.miniProgram.version.replace(/\./g, ""),
version: accountInfo.miniProgram.version,
envVersion: accountInfo.miniProgram.envVersion,
};
// #endif
},
async function fetchRemoteVersion(platform: string) {
const type = platform === 'android' ? 'ANDROID' : 'IOS'
const res = await getAppVersion(type)
if (res.data.success) {
versionData.value = res.data.result
}
}
methods: {
async getVersion(platform) {
let type;
platform == "android" ? (type = "ANDROID") : (type = "IOS");
function navigateTo(url: string) {
uni.navigateTo({ url })
}
let res = await getAppVersion(type);
if (res.data.success) {
this.versionData = res.data.result;
}
},
function openAppStoreRating() {
plus.runtime.launchApplication({
action: `itms-apps://itunes.apple.com/app/${config.iosAppId}?action=write-review`,
})
}
navigateTo(url) {
uni.navigateTo({
url,
});
},
checkStar() {
plus.runtime.launchApplication({
action: `itms-apps://itunes.apple.com/app/${config.iosAppId}?action=write-review`,
});
},
checkUpdate() {
if (
this.versionData.version.replace(/\./g, "") <
this.localVersion.versionCode
) {
APPUpdate();
} else {
uni.showToast({
title: "当前版本已是最新版",
duration: 2000,
icon: "none",
});
}
},
},
};
function checkUpdate() {
if (versionData.value.version?.replace(/\./g, '') < localVersion.value.versionCode) {
APPUpdate()
} else {
uni.showToast({ title: '当前版本已是最新版', duration: 2000, icon: 'none' })
}
}
</script>
<style lang="scss" scoped>

View File

@@ -4,9 +4,9 @@
<view class="box-title">猜你想问</view>
<view
class="feedBack-item"
:class="{ active: feedBack.type == item.value }"
@click="handleClick(index)"
v-for="(item, index) in list"
:class="{ active: feedbackForm.type == item.value }"
@click="selectFeedbackType(index)"
v-for="(item, index) in feedbackTypeList"
:key="index"
>
{{ item.text }}
@@ -15,11 +15,11 @@
<view class="feedBack-box">
<view class="box-title">问题反馈
<text class="box-tag" v-if="feedBack.type">@{{ list.find(item => item.value == feedBack.type).text }}</text>
<text class="box-tag" v-if="feedbackForm.type">@{{ feedbackTypeList.find(item => item.value == feedbackForm.type)?.text }}</text>
</view>
<u-textarea
class="field-textarea"
v-model="feedBack.context"
v-model="feedbackForm.context"
placeholder="请输入反馈信息"
border="none"
height="240"
@@ -39,7 +39,7 @@
<view class="box-title">手机号</view>
<u-input
class="field-input"
v-model="feedBack.mobile"
v-model="feedbackForm.mobile"
type="number"
maxlength="11"
border="none"
@@ -48,98 +48,69 @@
></u-input>
</view>
<view class="submit" @click="submit()">提交</view>
<view class="submit" @click="submitFeedback">提交</view>
</view>
</template>
<script>
import storage from "@/utils/storage.js";
import config from "@/config/config";
import { feedBack } from "@/api/members.js";
import { handleUploadAfterRead } from "@/utils/uploadHelper.js";
export default {
data() {
return {
storage,
config,
feedBack: {
type: "FUNCTION",
context: "",
mobile: "",
},
inputStyle: {
background: "#fafafa",
borderRadius: "12rpx",
padding: "0 24rpx",
height: "80rpx",
},
uploadFileList: [],
list: [
{ text: "功能相关", value: "FUNCTION" },
{ text: "优化反馈", value: "OPTIMIZE" },
{ text: "其他", value: "OTHER" },
],
};
},
methods: {
// 点击反馈内容
handleClick(index) {
this.feedBack["type"] = this.list[index].value;
},
<script setup lang="ts">
import { ref, reactive, getCurrentInstance } from 'vue'
import { feedBack as submitFeedBackApi } from '@/api/members.js'
import { handleUploadAfterRead } from '@/utils/uploadHelper.js'
onUploadAfterRead(event) {
handleUploadAfterRead(event, this.uploadFileList, (urls) => {
this.feedBack.images = urls.join(",");
});
},
const { proxy } = getCurrentInstance()!
/**
* 提交意见反馈
*/
submit() {
if (!this.feedBack.type) {
uni.showToast({
title: "请填写反馈类型",
duration: 2000,
icon: "none",
});
return false;
}
if (!this.feedBack.context) {
uni.showToast({
title: "请填写反馈信息",
duration: 2000,
icon: "none",
});
return false;
}
if (this.feedBack.mobile && !this.$u.test.mobile(this.feedBack.mobile)) {
uni.showToast({
title: "请填写您的正确手机号",
duration: 2000,
icon: "none",
});
return false;
}
/** 提交 */
feedBack(this.feedBack).then((res) => {
if (res.data.success) {
uni.showToast({
title: "提交成功!",
duration: 2000,
icon: "none",
});
setTimeout(() => {
uni.navigateBack({
delta: 1,
});
}, 500);
}
});
},
},
};
const feedbackForm = reactive({
type: 'FUNCTION',
context: '',
mobile: '',
images: '',
})
const inputStyle = {
background: '#fafafa',
borderRadius: '12rpx',
padding: '0 24rpx',
height: '80rpx',
}
const uploadFileList = ref<any[]>([])
const feedbackTypeList = [
{ text: '功能相关', value: 'FUNCTION' },
{ text: '优化反馈', value: 'OPTIMIZE' },
{ text: '其他', value: 'OTHER' },
]
function selectFeedbackType(index: number) {
feedbackForm.type = feedbackTypeList[index].value
}
function onUploadAfterRead(event: any) {
handleUploadAfterRead(event, uploadFileList.value, (urls) => {
feedbackForm.images = urls.join(',')
})
}
function submitFeedback() {
if (!feedbackForm.type) {
uni.showToast({ title: '请填写反馈类型', duration: 2000, icon: 'none' })
return
}
if (!feedbackForm.context) {
uni.showToast({ title: '请填写反馈信息', duration: 2000, icon: 'none' })
return
}
if (feedbackForm.mobile && !proxy.$u.test.mobile(feedbackForm.mobile)) {
uni.showToast({ title: '请填写您的正确手机号', duration: 2000, icon: 'none' })
return
}
submitFeedBackApi(feedbackForm).then((res) => {
if (res.data.success) {
uni.showToast({ title: '提交成功!', duration: 2000, icon: 'none' })
setTimeout(() => {
uni.navigateBack({ delta: 1 })
}, 500)
}
})
}
</script>
<style lang="scss" scoped>

View File

@@ -5,48 +5,54 @@
<view>点击修改头像</view>
</view>
<u-form :model="form" ref="uForm" class="form">
<u-form-item label="昵称" label-width="150" :border-bottom="true">
<up-form
:model="form"
ref="uForm"
class="form"
label-position="left"
label-width="180rpx"
>
<up-form-item label="昵称" label-width="180rpx" :border-bottom="true">
<u-input
v-model="form.nickName"
border="none"
input-align="right"
placeholder="请输入昵称"
/>
</u-form-item>
</up-form-item>
<u-form-item label="性别" label-width="150" :border-bottom="true">
<up-form-item label="性别" label-width="180rpx" :border-bottom="true">
<view class="sex-row">
<u-radio-group v-model="form.sex" :active-color="lightColor" :gap="40">
<u-radio name="1" label="男" shape="circle"></u-radio>
<u-radio name="0" label="女" shape="circle"></u-radio>
</u-radio-group>
</view>
</u-form-item>
</up-form-item>
<u-form-item label="生日" label-width="150" :border-bottom="true">
<up-form-item label="生日" label-width="180rpx" :border-bottom="true">
<view class="form-value" @click="showBirthday = true">
{{ birthday || '请选择出生日期' }}
</view>
<template #right>
<u-icon name="arrow-right" color="#ccc" size="16"></u-icon>
</template>
</u-form-item>
</up-form-item>
<u-form-item label="城市" label-width="150" :border-bottom="true">
<up-form-item label="城市" label-width="180rpx" :border-bottom="true">
<view class="form-value" @click="clickRegion">
{{ form.___path || '请选择城市' }}
{{ form.regionPath || '请选择城市' }}
</view>
<template #right>
<u-icon name="arrow-right" color="#ccc" size="16"></u-icon>
</template>
</u-form-item>
</up-form-item>
<u-form-item label="手机号" label-width="150" :border-bottom="false">
<up-form-item label="手机号" label-width="180rpx" :border-bottom="false">
<view v-if="form.mobile" class="form-value">{{ form.mobile }}</view>
<view v-else class="bind-mobile" @click="navigateTo(form.username)">绑定手机号码</view>
</u-form-item>
</u-form>
<view v-else class="bind-mobile" @click="navigateToBindMobile(form.username)">绑定手机号码</view>
</up-form-item>
</up-form>
<view class="bottom">
<view class="submit" @click="submit">保存</view>
@@ -74,152 +80,135 @@
</view>
</template>
<script>
import { saveUserInfo } from "@/api/members.js";
import { upload } from "@/api/common.js";
import storage from "@/utils/storage.js";
import city from "@/components/m-city/m-city.vue";
<script setup lang="ts">
import { ref, reactive, computed } from 'vue'
import { onShow } from '@dcloudio/uni-app'
import { useStore } from '@/store'
import { quiteLoginOut } from '@/utils/filters.js'
import { saveUserInfo } from '@/api/members.js'
import { upload } from '@/api/common.js'
import storage from '@/utils/storage.js'
import MCity from '@/components/m-city/m-city.vue'
function parseBirthdayTimestamp(str) {
if (!str) {
return Date.now();
}
const timestamp = Date.parse(String(str).replace(/-/g, "/"));
return Number.isFinite(timestamp) ? timestamp : Date.now();
function parseBirthdayTimestamp(str?: string) {
if (!str) return Date.now()
const timestamp = Date.parse(String(str).replace(/-/g, '/'))
return Number.isFinite(timestamp) ? timestamp : Date.now()
}
function formatBirthday(timestamp) {
const date = new Date(timestamp);
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, "0");
const day = String(date.getDate()).padStart(2, "0");
return `${year}-${month}-${day}`;
function formatBirthday(timestamp: number) {
const date = new Date(timestamp)
const year = date.getFullYear()
const month = String(date.getMonth() + 1).padStart(2, '0')
const day = String(date.getDate()).padStart(2, '0')
return `${year}-${month}-${day}`
}
export default {
components: { "m-city": city },
data() {
const userInfo = storage.getUserInfo() || {};
return {
lightColor: this.$lightColor,
form: {
nickName: userInfo.nickName || "",
birthday: userInfo.birthday || "",
face: userInfo.face || "/static/missing-face.png",
regionId: [],
region: userInfo.region || [],
sex: userInfo.sex != null ? String(userInfo.sex) : "1",
___path: userInfo.region,
mobile: userInfo.mobile,
username: userInfo.username,
},
birthday: userInfo.birthday || "",
birthdayValue: parseBirthdayTimestamp(userInfo.birthday),
minBirthdayDate: new Date("1950-01-01").getTime(),
maxBirthdayDate: Date.now(),
region: [
{
id: "",
localName: "请选择",
children: [],
},
],
showBirthday: false,
};
},
methods: {
getPickerParentValue(e) {
this.form.region = [];
this.form.regionId = [];
let name = "";
const store = useStore()
const lightColor = computed(() => store.getters.lightColor)
e.forEach((item, index) => {
if (item.id) {
this.form.region.push(item.localName);
this.form.regionId.push(item.id);
if (index == e.length - 1) {
name += item.localName;
} else {
name += item.localName + ",";
}
this.form.___path = name;
}
});
},
const userInfo = storage.getUserInfo() || {}
const form = reactive<Record<string, any>>({
nickName: userInfo.nickName || '',
birthday: userInfo.birthday || '',
face: userInfo.face || '/static/missing-face.png',
regionId: [],
region: userInfo.region || [],
sex: userInfo.sex != null ? String(userInfo.sex) : '1',
regionPath: userInfo.region,
mobile: userInfo.mobile,
username: userInfo.username,
})
const birthday = ref(userInfo.birthday || '')
const birthdayValue = ref(parseBirthdayTimestamp(userInfo.birthday))
const minBirthdayDate = new Date('1950-01-01').getTime()
const maxBirthdayDate = Date.now()
const region = ref([{ id: '', localName: '请选择', children: [] }])
const showBirthday = ref(false)
const cityPicker = ref<any>(null)
clickRegion() {
this.$refs.cityPicker.show();
},
function getPickerParentValue(selected: any[]) {
form.region = []
form.regionId = []
let name = ''
selected.forEach((item, index) => {
if (item.id) {
form.region.push(item.localName)
form.regionId.push(item.id)
name += index === selected.length - 1 ? item.localName : `${item.localName},`
form.regionPath = name
}
})
}
submit() {
delete this.form.___path;
const params = JSON.parse(JSON.stringify(this.form));
saveUserInfo(params).then((res) => {
if (res.statusCode == 200) {
storage.setUserInfo(res.data.result);
uni.navigateBack();
}
});
},
function clickRegion() {
cityPicker.value?.show()
}
changeFace() {
uni.chooseImage({
success: (chooseImageRes) => {
const tempFilePaths = chooseImageRes.tempFilePaths;
uni.uploadFile({
url: upload,
filePath: tempFilePaths[0],
name: "file",
header: {
accessToken: storage.getAccessToken(),
},
success: (uploadFileRes) => {
const data = JSON.parse(uploadFileRes.data);
this.form.face = data.result;
},
});
},
});
},
function submit() {
const params = JSON.parse(JSON.stringify(form))
delete params.regionPath
saveUserInfo(params).then((res) => {
if (res.statusCode === 200) {
storage.setUserInfo(res.data.result)
uni.navigateBack()
}
})
}
selectTime(e) {
const timestamp = typeof e?.value === "number" ? e.value : this.birthdayValue;
const formatted = formatBirthday(timestamp);
this.birthdayValue = timestamp;
this.form.birthday = formatted;
this.birthday = formatted;
this.showBirthday = false;
},
function changeFace() {
uni.chooseImage({
success: (chooseImageRes) => {
uni.uploadFile({
url: upload,
filePath: chooseImageRes.tempFilePaths[0],
name: 'file',
header: { accessToken: storage.getAccessToken() },
success: (uploadFileRes) => {
const data = JSON.parse(uploadFileRes.data)
form.face = data.result
},
})
},
})
}
closeBirthdayPicker() {
this.showBirthday = false;
},
function selectTime(e: any) {
const timestamp = typeof e?.value === 'number' ? e.value : birthdayValue.value
const formatted = formatBirthday(timestamp)
birthdayValue.value = timestamp
form.birthday = formatted
birthday.value = formatted
showBirthday.value = false
}
navigateTo(username) {
uni.navigateTo({
url: "/pages/mine/set/securityCenter/bindMobile?username=" + username,
});
},
function closeBirthdayPicker() {
showBirthday.value = false
}
syncUserInfo() {
const userInfo = storage.getUserInfo() || {};
this.form.nickName = userInfo.nickName || "";
this.form.birthday = userInfo.birthday || "";
this.form.face = userInfo.face || "/static/missing-face.png";
this.form.region = userInfo.region || [];
this.form.sex = userInfo.sex != null ? String(userInfo.sex) : "1";
this.form.___path = userInfo.region;
this.form.mobile = userInfo.mobile;
this.form.username = userInfo.username;
this.birthday = userInfo.birthday || "";
this.birthdayValue = parseBirthdayTimestamp(userInfo.birthday);
},
},
function navigateToBindMobile(username: string) {
uni.navigateTo({
url: `/pages/mine/set/securityCenter/bindMobile?username=${username}`,
})
}
onShow() {
this.syncUserInfo();
},
};
function syncUserInfo() {
const latest = storage.getUserInfo() || {}
form.nickName = latest.nickName || ''
form.birthday = latest.birthday || ''
form.face = latest.face || '/static/missing-face.png'
form.region = latest.region || []
form.sex = latest.sex != null ? String(latest.sex) : '1'
form.regionPath = latest.region
form.mobile = latest.mobile
form.username = latest.username
birthday.value = latest.birthday || ''
birthdayValue.value = parseBirthdayTimestamp(latest.birthday)
}
onShow(() => {
syncUserInfo()
})
</script>
<style lang="scss" scoped>

View File

@@ -1,227 +1,211 @@
<template>
<view class="box">
<view class="box-tips">
<h2 class='h2'>
绑定手机号码
</h2>
<h2 class="h2">绑定手机号码</h2>
<view class="verification"></view>
</view>
<view class="form">
<u-form :model="codeForm" ref="validateCodeForm">
<view v-if="!validateFlage">
<u-form-item label-width="120" label="手机号" prop="mobile">
<up-form
:model="codeForm"
ref="validateCodeForm"
label-position="left"
label-width="180rpx"
>
<view v-if="!phoneVerified">
<up-form-item label-width="180rpx" label="手机号" prop="mobile">
<u-input maxlength="11" v-model="codeForm.mobile" placeholder="请输入您的手机号" />
</u-form-item>
<u-form-item class="sendCode" label-width="120" prop="code" label="验证码">
<u-input v-model="codeForm.code" placeholder="请输入验证码" />
<u-code unique-key="page-edit" :seconds="seconds" @end="end" @start="start"
ref="uCode" @change="codeChange"></u-code>
<view @tap="getCode" class="text-tips">{{ tips }}</view>
</u-form-item>
</up-form-item>
<view class="submit" @click="validatePhone">绑定</view>
<myVerification keep-running @send="verification" class="verification" ref="verification"
business="BIND_MOBILE" />
<up-form-item class="sendCode" label-width="180rpx" prop="code" label="验证码">
<u-input v-model="codeForm.code" placeholder="请输入验证码" />
<u-code
unique-key="page-edit"
:seconds="seconds"
@end="onCodeCountdownEnd"
@start="onCodeCountdownStart"
ref="uCodeRef"
@change="onCodeTextChange"
></u-code>
<view @tap="requestSmsCode" class="text-tips">{{ codeTips }}</view>
</up-form-item>
<view class="submit" @click="submitBindMobile">绑定</view>
<myVerification
keep-running
@send="onVerificationPassed"
class="verification"
ref="verificationRef"
business="BIND_MOBILE"
/>
</view>
</u-form>
</up-form>
</view>
</view>
</template>
<script>
import {
sendMobile,
bindMobile
} from "@/api/login";
import { getUserInfo } from "@/api/members.js";
import storage from "@/utils/storage.js";
<script setup lang="ts">
import { ref, reactive, watch, getCurrentInstance } from 'vue'
import { onLoad, onReady } from '@dcloudio/uni-app'
import { useStore } from '@/store'
import { sendMobile, bindMobile } from '@/api/login'
import { getUserInfo } from '@/api/members.js'
import storage from '@/utils/storage.js'
import MyVerification from '@/components/verification/verification.vue'
import myVerification from "@/components/verification/verification.vue"; //验证
import uuid from "@/utils/uuid.modified.js";
export default {
components: {
myVerification,
const store = useStore()
const { proxy } = getCurrentInstance()!
const phoneVerified = ref(false)
const verificationPassed = ref(false)
const codeForm = reactive({
mobile: '',
code: '',
username: '',
})
const codeTips = ref('')
const seconds = 69
const validateCodeForm = ref<any>(null)
const uCodeRef = ref<any>(null)
const verificationRef = ref<any>(null)
const codeRules = {
mobile: [
{
validator: (_rule: any, value: string) => proxy.$u.test.mobile(value),
message: '手机号码不正确',
trigger: ['blur'],
},
data() {
return {
uuid,
validateFlage: false, //是否进行了手机号验证
step: 0, //当前验证步骤
flage: false, //是否验证码验证
codeForm: {
mobile: "", //手机号
code: "", //验证码
username: "", //用户名
},
tips: "", //提示
seconds: 69, // 60s等待时间
// 验证码登录校验
codeRules: {
mobile: [{
validator: (rule, value, callback) => {
return this.$u.test.mobile(value);
},
message: "手机号码不正确",
trigger: ["blur"],
}, ],
code: [{
min: 4,
max: 6,
required: true,
message: "请输入验证码",
trigger: ["blur"],
}, ],
},
};
},
onLoad(options) {
this.codeForm.username = options.username;
},
onReady() {
// 必须要在onReady生命周期因为onLoad生命周期组件可能尚未创建完毕
this.$refs.validateCodeForm.setRules(this.codeRules);
},
watch: {
flage(val) {
if (val) {
if (this.$refs.uCode.canGetCode) {
uni.showLoading({
title: "正在获取验证码",
});
sendMobile(this.codeForm.mobile, "BIND_MOBILE").then((res) => {
if (this.$store.state.isShowToast){ uni.hideLoading() };
// 这里此提示会被this.start()方法中的提示覆盖
if (res.data.success) {
this.$refs.uCode.start();
} else {
uni.showToast({
title: res.data.message,
duration: 2000,
icon: "none",
});
this.flage = false;
this.$refs.verification.getCode();
}
})
} else {
this.$u.toast("请倒计时结束后再发送");
}
}
},
],
code: [
{
min: 4,
max: 6,
required: true,
message: '请输入验证码',
trigger: ['blur'],
},
],
}
methods: {
// 验证码验证
verification(val) {
this.flage = val == this.$store.state.verificationKey ? true : false;
},
onLoad((options) => {
codeForm.username = options?.username || ''
})
// 验证手机号
validatePhone() {
this.$refs.validateCodeForm.validate((valid) => {
if (valid) {
bindMobile(this.codeForm).then((res) => {
if (res.data.success) {
this.validateFlage = !this.validateFlage;
// 获取最新的用户信息并更新缓存
getUserInfo().then(userRes => {
if (userRes.data.success) {
storage.setUserInfo(userRes.data.result);
}
// 显示成功提示
uni.showToast({
title: "绑定成功!",
duration: 2000,
icon: "none",
});
// 返回上一页
setTimeout(() => {
uni.navigateBack({
delta: 1,
});
}, 1000);
});
}
});
}
});
},
onReady(() => {
validateCodeForm.value?.setRules(codeRules)
})
codeChange(text) {
this.tips = text;
},
end() {
this.flage = false;
this.$refs.verification.getCode()
},
/**获取验证码 */
getCode() {
if (this.tips == "重新获取") {
this.$refs.verification.error(); //发送
}
if (!this.$u.test.mobile(this.codeForm.mobile)) {
uni.showToast({
title: "请输入正确手机号",
icon: "none",
});
return false;
}
if (!this.flage) {
this.$refs.verification.error(); //发送
return false;
}
},
start() {
this.$u.toast("验证码已发送");
this.flage = true;
this.$refs.verification.hide();
},
},
};
</script>
<style lang="scss" scoped>
@import url("@/pages/passport/login.scss");
::v-deep .u-form-item {
margin: 40rpx 0;
watch(verificationPassed, (val) => {
if (!val) return
if (!uCodeRef.value?.canGetCode) {
proxy.$u.toast('请倒计时结束后再发送')
return
}
.sendCode {
::v-deep .u-form-item--right__content__slot {
display: flex;
uni.showLoading({ title: '正在获取验证码' })
sendMobile(codeForm.mobile, 'BIND_MOBILE').then((res) => {
if (store.state.isShowToast) uni.hideLoading()
if (res.data.success) {
uCodeRef.value?.start()
} else {
uni.showToast({ title: res.data.message, duration: 2000, icon: 'none' })
verificationPassed.value = false
verificationRef.value?.getCode()
}
}
})
})
.h2 {
font-size: 40rpx;
font-weight: bold;
}
function onVerificationPassed(val: string) {
verificationPassed.value = val === store.state.verificationKey
}
page {
background: #fff;
}
function submitBindMobile() {
validateCodeForm.value?.validate((valid: boolean) => {
if (!valid) return
bindMobile(codeForm).then((res) => {
if (res.data.success) {
phoneVerified.value = true
getUserInfo().then((userRes) => {
if (userRes.data.success) {
storage.setUserInfo(userRes.data.result)
}
uni.showToast({ title: '绑定成功!', duration: 2000, icon: 'none' })
setTimeout(() => {
uni.navigateBack({ delta: 1 })
}, 1000)
})
}
})
})
}
.box {
padding: 80rpx 0;
border-radius: 20rpx;
}
function onCodeTextChange(text: string) {
codeTips.value = text
}
.submit {
background: $light-color;
}
function onCodeCountdownEnd() {
verificationPassed.value = false
verificationRef.value?.getCode()
}
.box-tips {
margin: 0 72rpx;
function requestSmsCode() {
if (codeTips.value === '重新获取') {
verificationRef.value?.error()
}
if (!proxy.$u.test.mobile(codeForm.mobile)) {
uni.showToast({ title: '请输入正确手机号', icon: 'none' })
return
}
if (!verificationPassed.value) {
verificationRef.value?.error()
}
}
.verification {
font-size: 24rpx;
color: #999;
margin-top: 10rpx;
function onCodeCountdownStart() {
proxy.$u.toast('验证码已发送')
verificationPassed.value = true
verificationRef.value?.hide()
}
</script>
<style lang="scss" scoped>
@import url("@/pages/passport/login.scss");
::v-deep .u-form-item {
margin: 40rpx 0;
}
.sendCode {
::v-deep .u-form-item__body__right__content__slot {
display: flex;
}
}
.h2 {
font-size: 40rpx;
font-weight: bold;
}
page {
background: #fff;
}
.box {
padding: 80rpx 0;
border-radius: 20rpx;
}
.submit {
background: $light-color;
}
.box-tips {
margin: 0 72rpx;
}
.verification {
font-size: 24rpx;
color: #999;
margin-top: 10rpx;
}
</style>

View File

@@ -1,160 +1,99 @@
<template>
<view class="box">
<view class="box-tips">
<h2 class='h2'>
{{verificationTitle.title}}
</h2>
<view class="verification">{{verificationTitle.desc}}</view>
<h2 class="h2">{{ verificationTitle.title }}</h2>
<view class="verification">{{ verificationTitle.desc }}</view>
</view>
<view class="form">
<u-form :model="codeForm" ref="validateCodeForm">
<u-form-item label-width="120" label="旧密码">
<u-input type="password" v-model="oldPassword" placeholder="请输入您的旧密码" />
</u-form-item>
<up-form
:model="codeForm"
ref="validateCodeForm"
label-position="left"
label-width="180rpx"
>
<up-form-item label-width="180rpx" label="旧密码">
<u-input type="password" v-model="oldPassword" placeholder="请输入您的旧密码" />
</up-form-item>
<u-form-item label-width="120" label="密码">
<u-input type="password" v-model="password" placeholder="请输入您的密码" />
</u-form-item>
<up-form-item label-width="180rpx" label="密码">
<u-input type="password" v-model="password" placeholder="请输入您的密码" />
</up-form-item>
<u-form-item label-width="120" label="确认密码">
<u-input type="password" v-model="newPassword" placeholder="请再次输入您的密码" />
</u-form-item>
<up-form-item label-width="180rpx" label="确认密码">
<u-input type="password" v-model="confirmPassword" placeholder="请再次输入您的密码" />
</up-form-item>
<view class="submit" @click="updatePassword">修改密码</view>
</u-form>
<view class="submit" @click="updatePassword">修改密码</view>
</up-form>
</view>
</view>
</template>
<script>
import {
resetByMobile,
modifyPass
} from "@/api/login";
<script setup lang="ts">
import { ref, reactive } from 'vue'
import { modifyPass } from '@/api/login'
import { md5 } from '@/utils/md5.js'
import {
md5
} from "@/utils/md5.js"; // md5
import myVerification from "@/components/verification/verification.vue"; //验证
import uuid from "@/utils/uuid.modified.js";
export default {
components: {
myVerification,
},
data() {
return {
uuid,
validateFlage: false, //是否进行了手机号验证
verificationTitle: {
title: "修改密码",
desc: "请验证并输入密码",
},
step: 0, //当前验证步骤
flage: false, //是否验证码验证
const verificationTitle = {
title: '修改密码',
desc: '请验证并输入密码',
}
const codeForm = reactive({ mobile: '', code: '' })
const oldPassword = ref('')
const password = ref('')
const confirmPassword = ref('')
codeForm: {
mobile: "", //手机号
code: "", //验证码
},
newPassword: "", //新密码
password: "", //密码
oldPassword: '', //旧密码
tips: "", //提示
seconds: 69, // 60s等待时间
// 验证码登录校验
codeRules: {
mobile: [{
validator: (rule, value, callback) => {
return this.$u.test.mobile(value);
},
message: "手机号码不正确",
trigger: ["blur"],
}, ],
code: [{
min: 4,
max: 6,
required: true,
message: "请输入验证码",
trigger: ["blur"],
}, ],
},
};
},
onReady() {
// 必须要在onReady生命周期因为onLoad生命周期组件可能尚未创建完毕
this.$refs.validateCodeForm.setRules(this.codeRules);
},
methods: {
// 修改密码
updatePassword() {
if(this.password !== this.newPassword){
uni.showToast({
title: "两次输入密码不一致!",
icon: "none",
});
return;
}
modifyPass({
password: md5(this.oldPassword),
newPassword: md5(this.newPassword),
}).then((res) => {
if (res.data.success) {
uni.showToast({
title: "修改成功!",
duration: 2000,
icon: "none",
});
setTimeout(() => {
uni.navigateBack({
delta: 1,
});
}, 1000);
}
});
},
},
};
</script>
<style lang="scss" scoped>
@import url("@/pages/passport/login.scss");
::v-deep .u-form-item {
margin: 40rpx 0;
function updatePassword() {
if (password.value !== confirmPassword.value) {
uni.showToast({ title: '两次输入密码不一致!', icon: 'none' })
return
}
.sendCode {
::v-deep .u-form-item--right__content__slot {
display: flex;
modifyPass({
password: md5(oldPassword.value),
newPassword: md5(password.value),
}).then((res) => {
if (res.data.success) {
uni.showToast({ title: '修改成功!', duration: 2000, icon: 'none' })
setTimeout(() => {
uni.navigateBack({ delta: 1 })
}, 1000)
}
}
})
}
</script>
.h2 {
font-size: 40rpx;
font-weight: bold;
}
<style lang="scss" scoped>
@import url("@/pages/passport/login.scss");
page {
background: #fff;
}
::v-deep .u-form-item {
margin: 40rpx 0;
}
.box {
padding: 80rpx 0;
border-radius: 20rpx;
}
.h2 {
font-size: 40rpx;
font-weight: bold;
}
.submit {
background: $light-color;
}
page {
background: #fff;
}
.box-tips {
margin: 0 72rpx;
}
.box {
padding: 80rpx 0;
border-radius: 20rpx;
}
.verification {
font-size: 24rpx;
color: #999;
margin-top: 10rpx;
}
.submit {
background: $light-color;
}
.box-tips {
margin: 0 72rpx;
}
.verification {
font-size: 24rpx;
color: #999;
margin-top: 10rpx;
}
</style>

View File

@@ -1,281 +1,238 @@
<template>
<view class="box">
<view class="box-tips">
<h2 class='h2'>
{{verificationTitle[validateFlage==false ? 0 : 1].title}}
</h2>
<view class="verification">{{verificationTitle[step].desc}}</view>
<h2 class="h2">{{ verificationTitle[phoneVerified ? 1 : 0].title }}</h2>
<view class="verification">{{ verificationTitle[step].desc }}</view>
</view>
<view class="form">
<u-form :model="codeForm" ref="validateCodeForm">
<view v-if="!validateFlage">
<u-form-item label-width="120" label="手机号" prop="mobile">
<up-form
:model="codeForm"
ref="validateCodeForm"
label-position="left"
label-width="180rpx"
>
<view v-if="!phoneVerified">
<up-form-item label-width="180rpx" label="手机号" prop="mobile">
<u-input maxlength="11" v-model="codeForm.mobile" placeholder="请输入您的手机号" />
</u-form-item>
</up-form-item>
<u-form-item class="sendCode" label-width="120" prop="code" label="验证码">
<up-form-item class="sendCode" label-width="180rpx" prop="code" label="验证码">
<u-input v-model="codeForm.code" placeholder="请输入验证码" />
<u-code unique-key="page-edit" :seconds="seconds" @end="end" @start="start"
ref="uCode" @change="codeChange"></u-code>
<view @tap="getCode" class="text-tips">{{ tips }}</view>
</u-form-item>
<u-code
unique-key="page-edit"
:seconds="seconds"
@end="onCodeCountdownEnd"
@start="onCodeCountdownStart"
ref="uCodeRef"
@change="onCodeTextChange"
></u-code>
<view @tap="requestSmsCode" class="text-tips">{{ codeTips }}</view>
</up-form-item>
<view class="submit" @click="validatePhone">验证</view>
<myVerification keep-running @send="verification" class="verification" ref="verification"
business="FIND_USER" />
<view class="submit" @click="verifyMobile">验证</view>
<myVerification
keep-running
@send="onVerificationPassed"
class="verification"
ref="verificationRef"
business="FIND_USER"
/>
</view>
<view v-if="validateFlage">
<u-form-item label-width="120" label="密码">
<view v-if="phoneVerified">
<up-form-item label-width="180rpx" label="密码">
<u-input type="password" v-model="password" placeholder="请输入您的密码" />
</u-form-item>
</up-form-item>
<u-form-item label-width="120" label="确认密码">
<u-input type="password" v-model="newPassword" placeholder="请再次输入您的密码" />
</u-form-item>
<up-form-item label-width="180rpx" label="确认密码">
<u-input type="password" v-model="confirmPassword" placeholder="请再次输入您的密码" />
</up-form-item>
<view class="submit" @click="updatePassword">修改密码</view>
</view>
</u-form>
</up-form>
</view>
</view>
</template>
<script>
import {
sendMobile,
resetByMobile,
resetPassword
} from "@/api/login";
<script setup lang="ts">
import { ref, reactive, watch, getCurrentInstance } from 'vue'
import { onReady } from '@dcloudio/uni-app'
import { useStore } from '@/store'
import { isLogin } from '@/utils/filters.js'
import { sendMobile, resetByMobile, resetPassword } from '@/api/login'
import { md5 } from '@/utils/md5.js'
import MyVerification from '@/components/verification/verification.vue'
import {
md5
} from "@/utils/md5.js"; // md5
import myVerification from "@/components/verification/verification.vue"; //验证
import uuid from "@/utils/uuid.modified.js";
export default {
components: {
myVerification,
const store = useStore()
const { proxy } = getCurrentInstance()!
const phoneVerified = ref(false)
const verificationPassed = ref(false)
const verificationTitle = [
{ title: '安全验证', desc: '请输入当前手机号进行安全验证' },
{ title: '修改密码', desc: '请输入新密码' },
]
const step = ref(0)
const codeForm = reactive({ mobile: '', code: '' })
const password = ref('')
const confirmPassword = ref('')
const codeTips = ref('')
const seconds = 69
const validateCodeForm = ref<any>(null)
const uCodeRef = ref<any>(null)
const verificationRef = ref<any>(null)
const codeRules = {
mobile: [
{
validator: (_rule: any, value: string) => proxy.$u.test.mobile(value),
message: '手机号码不正确',
trigger: ['blur'],
},
data() {
return {
uuid,
validateFlage: false, //是否进行了手机号验证
verificationTitle: [{
title: "安全验证",
desc: "请输入当前手机号进行安全验证",
},
{
title: "修改密码",
desc: "请输入新密码",
},
],
step: 0, //当前验证步骤
flage: false, //是否验证码验证
codeForm: {
mobile: "", //手机号
code: "", //验证码
},
newPassword: "", //新密码
password: "", //密码
tips: "", //提示
seconds: 69, // 60s等待时间
// 验证码登录校验
codeRules: {
mobile: [{
validator: (rule, value, callback) => {
return this.$u.test.mobile(value);
},
message: "手机号码不正确",
trigger: ["blur"],
}, ],
code: [{
min: 4,
max: 6,
required: true,
message: "请输入验证码",
trigger: ["blur"],
}, ],
},
};
],
code: [
{
min: 4,
max: 6,
required: true,
message: '请输入验证码',
trigger: ['blur'],
},
onReady() {
// 必须要在onReady生命周期因为onLoad生命周期组件可能尚未创建完毕
this.$refs.validateCodeForm.setRules(this.codeRules);
},
watch: {
flage(val) {
if (val) {
],
}
if (this.$refs.uCode.canGetCode) {
uni.showLoading({
title: "正在获取验证码",
});
sendMobile(this.codeForm.mobile, "FIND_USER").then((res) => {
if (this.$store.state.isShowToast){ uni.hideLoading() };
// 这里此提示会被this.start()方法中的提示覆盖
if (res.data.success) {
this.$refs.uCode.start();
} else {
uni.showToast({
title: res.data.message,
duration: 2000,
icon: "none",
});
this.flage = false;
this.$refs.verification.getCode();
}
})
} else {
this.$u.toast("请倒计时结束后再发送");
}
}
},
},
onReady(() => {
validateCodeForm.value?.setRules(codeRules)
})
methods: {
// 修改密码
updatePassword() {
if(this.password !== this.newPassword){
uni.showToast({
title: "两次输入密码不一致!",
icon: "none",
});
return;
}
resetPassword({
password: md5(this.password),
}).then((res) => {
if (res.data.success) {
uni.showToast({
title: "修改成功!",
duration: 2000,
icon: "none",
});
setTimeout(() => {
uni.navigateBack({
delta: 1,
});
}, 1000);
}
});
},
// 验证码验证
verification(val) {
this.flage = val == this.$store.state.verificationKey ? true : false;
},
// 验证手机号
validatePhone() {
this.$refs.validateCodeForm.validate((valid) => {
if (valid) {
resetByMobile(this.codeForm).then((res) => {
if (res.data.success) {
this.validateFlage = !this.validateFlage;
// 登录成功
uni.showToast({
title: "验证成功!",
icon: "none",
});
}
});
}
});
},
codeChange(text) {
this.tips = text;
},
end() {
this.flage = false;
this.$refs.verification.getCode()
},
/**判断是否是当前用户的手机号 */
isUserPhone() {
let flage = false;
let user = this.isLogin();
if (user.mobile != this.codeForm.mobile) {
uni.showToast({
title: "请输入当前绑定手机号",
icon: "none",
});
flage = false;
} else {
flage = true;
}
return flage;
},
/**获取验证码 */
getCode() {
if (this.isUserPhone()) {
if (this.tips == "重新获取") {
this.$refs.verification.error(); //发送
}
if (!this.$u.test.mobile(this.codeForm.mobile)) {
uni.showToast({
title: "请输入正确手机号",
icon: "none",
});
return false;
}
if (!this.flage) {
this.$refs.verification.error(); //发送
return false;
}
}
},
start() {
this.$u.toast("验证码已发送");
this.flage = true;
this.$refs.verification.hide();
},
},
};
</script>
<style lang="scss" scoped>
@import url("@/pages/passport/login.scss");
::v-deep .u-form-item {
margin: 40rpx 0;
watch(verificationPassed, (val) => {
if (!val) return
if (!uCodeRef.value?.canGetCode) {
proxy.$u.toast('请倒计时结束后再发送')
return
}
.sendCode {
::v-deep .u-form-item--right__content__slot {
display: flex;
uni.showLoading({ title: '正在获取验证码' })
sendMobile(codeForm.mobile, 'FIND_USER').then((res) => {
if (store.state.isShowToast) uni.hideLoading()
if (res.data.success) {
uCodeRef.value?.start()
} else {
uni.showToast({ title: res.data.message, duration: 2000, icon: 'none' })
verificationPassed.value = false
verificationRef.value?.getCode()
}
}
})
})
.h2 {
font-size: 40rpx;
font-weight: bold;
}
function onVerificationPassed(val: string) {
verificationPassed.value = val === store.state.verificationKey
}
page {
background: #fff;
function updatePassword() {
if (password.value !== confirmPassword.value) {
uni.showToast({ title: '两次输入密码不一致!', icon: 'none' })
return
}
resetPassword({ password: md5(password.value) }).then((res) => {
if (res.data.success) {
uni.showToast({ title: '修改成功!', duration: 2000, icon: 'none' })
setTimeout(() => {
uni.navigateBack({ delta: 1 })
}, 1000)
}
})
}
.box {
padding: 80rpx 0;
border-radius: 20rpx;
}
function verifyMobile() {
validateCodeForm.value?.validate((valid: boolean) => {
if (!valid) return
resetByMobile(codeForm).then((res) => {
if (res.data.success) {
phoneVerified.value = true
uni.showToast({ title: '验证成功!', icon: 'none' })
}
})
})
}
.submit {
background: $light-color;
}
function onCodeTextChange(text: string) {
codeTips.value = text
}
.box-tips {
margin: 0 72rpx;
}
function onCodeCountdownEnd() {
verificationPassed.value = false
verificationRef.value?.getCode()
}
.verification {
font-size: 24rpx;
color: #999;
margin-top: 10rpx;
function isCurrentUserPhone() {
const user = isLogin()
if (user?.mobile !== codeForm.mobile) {
uni.showToast({ title: '请输入当前绑定手机号', icon: 'none' })
return false
}
return true
}
function requestSmsCode() {
if (!isCurrentUserPhone()) return
if (codeTips.value === '重新获取') {
verificationRef.value?.error()
}
if (!proxy.$u.test.mobile(codeForm.mobile)) {
uni.showToast({ title: '请输入正确手机号', icon: 'none' })
return
}
if (!verificationPassed.value) {
verificationRef.value?.error()
}
}
function onCodeCountdownStart() {
proxy.$u.toast('验证码已发送')
verificationPassed.value = true
verificationRef.value?.hide()
}
</script>
<style lang="scss" scoped>
@import url("@/pages/passport/login.scss");
::v-deep .u-form-item {
margin: 40rpx 0;
}
.sendCode {
::v-deep .u-form-item__body__right__content__slot {
display: flex;
}
}
.h2 {
font-size: 40rpx;
font-weight: bold;
}
page {
background: #fff;
}
.box {
padding: 80rpx 0;
border-radius: 20rpx;
}
.submit {
background: $light-color;
}
.box-tips {
margin: 0 72rpx;
}
.verification {
font-size: 24rpx;
color: #999;
margin-top: 10rpx;
}
</style>

View File

@@ -4,7 +4,7 @@
<u-cell-group>
<u-cell class="border-top" :isLink="false" title="面容登录">
<template #right-icon>
<u-switch @change="faceSwitchChange" active-color="#1abc9c" size="40" v-model="checked"></u-switch>
<u-switch @change="onFaceSwitchChange" active-color="#1abc9c" size="40" v-model="enabled"></u-switch>
</template>
</u-cell>
</u-cell-group>
@@ -12,74 +12,65 @@
</view>
</template>
<script>
import storage from "@/utils/storage.js";
import { setBiolofy } from "@/api/passport.js";
<script setup lang="ts">
import { ref } from 'vue'
import { onLoad } from '@dcloudio/uni-app'
import storage from '@/utils/storage.js'
import { setBiolofy } from '@/api/passport.js'
export default {
data() {
return {
lightColor: this.$lightColor,
checked: true,
};
},
methods: {
faceSwitchChange(value) {
if (value === true) {
const res = uni.getSystemInfoSync();
plus.device.getInfo({
success: function (e) {
let params = {
mobile_type: res.model,
secret_key: e.uuid,
};
setBiolofy(params).then((res) => {
if (res.statusCode === 200) {
storage.setFaceLogin(true);
}
});
},
fail: function (e) {
//plus.nativeUI.toast('获取设备信息错误:' + JSON.stringify(e));
console.error("getDeviceInfo failed: " + JSON.stringify(e));
},
});
} else {
storage.setFaceLogin(false);
const enabled = ref(false)
onLoad(() => {
// #ifdef APP-PLUS
uni.checkIsSupportSoterAuthentication({
success(res) {
if (!res.supportMode.find((e) => e === 'facial')) {
plus.nativeUI.toast('此设备不支持面部识别')
uni.navigateBack()
}
uni.checkIsSoterEnrolledInDevice({
checkAuthMode: 'facial',
success(_res) {
if (!_res.isEnrolled) {
plus.nativeUI.toast('此设备未录入面部信息')
uni.navigateBack()
}
},
fail() {
uni.navigateBack()
},
})
},
},
onLoad() {
// #ifdef APP-PLUS
uni.checkIsSupportSoterAuthentication({
success(res) {
if (!res.supportMode.find((e) => e === "facial")) {
plus.nativeUI.toast("此设备不支持面部识别");
uni.navigateBack();
}
uni.checkIsSoterEnrolledInDevice({
checkAuthMode: "facial",
success(_res) {
if (!_res.isEnrolled) {
plus.nativeUI.toast("此设备未录入面部信息");
uni.navigateBack();
}
},
fail(_err) {
// plus.nativeUI.toast(JSON.stringify(_err));
uni.navigateBack();
},
});
fail() {
uni.navigateBack()
},
})
enabled.value = storage.getFaceLogin() || false
// #endif
})
function onFaceSwitchChange(value: boolean) {
if (value) {
const systemInfo = uni.getSystemInfoSync()
plus.device.getInfo({
success(e) {
setBiolofy({
mobile_type: systemInfo.model,
secret_key: e.uuid,
}).then((res) => {
if (res.statusCode === 200) {
storage.setFaceLogin(true)
}
})
},
fail(err) {
// plus.nativeUI.toast(JSON.stringify(err));
uni.navigateBack();
console.error('getDeviceInfo failed: ' + JSON.stringify(err))
},
});
this.checked = storage.getFaceLogin() || false;
// #endif
},
};
})
} else {
storage.setFaceLogin(false)
}
}
</script>
<style lang="scss" scoped>

View File

@@ -4,7 +4,7 @@
<u-cell-group>
<u-cell class="border-top" :isLink="false" title="指纹登录">
<template #right-icon>
<u-switch @change="fingerSwitchChange" :active-color="lightColor" size="40" v-model="checked"></u-switch>
<u-switch @change="onFingerSwitchChange" :active-color="lightColor" size="40" v-model="enabled"></u-switch>
</template>
</u-cell>
</u-cell-group>
@@ -12,60 +12,57 @@
</view>
</template>
<script>
import storage from "@/utils/storage.js";
import { setBiolofy } from "@/api/passport.js";
<script setup lang="ts">
import { ref, computed } from 'vue'
import { onLoad } from '@dcloudio/uni-app'
import { useStore } from '@/store'
import storage from '@/utils/storage.js'
import { setBiolofy } from '@/api/passport.js'
export default {
data() {
return {
lightColor: this.$lightColor,
checked: false,
};
},
methods: {
fingerSwitchChange(value) {
if (value === true) {
const res = uni.getSystemInfoSync();
plus.device.getInfo({
success: function (e) {
let params = {
mobile_type: res.model,
secret_key: e.uuid,
};
setBiolofy(params).then((res) => {
if (res.statusCode === 200) {
storage.setFingerLogin(true);
}
});
},
fail: function (e) {
console.error("getDeviceInfo failed: " + JSON.stringify(e));
},
});
} else {
storage.setFingerLogin(false);
}
},
},
onLoad() {
// #ifdef APP-PLUS
if (!plus.fingerprint.isSupport()) {
plus.nativeUI.toast("此设备不支持指纹识别");
uni.navigateBack();
}
if (!plus.fingerprint.isKeyguardSecure()) {
plus.nativeUI.toast("此设备未设置密码锁屏");
uni.navigateBack();
}
if (!plus.fingerprint.isEnrolledFingerprints()) {
plus.nativeUI.toast("此设备未录入指纹");
uni.navigateBack();
}
this.checked = storage.getFingerLogin() || false;
// #endif
},
};
const store = useStore()
const lightColor = computed(() => store.getters.lightColor)
const enabled = ref(false)
onLoad(() => {
// #ifdef APP-PLUS
if (!plus.fingerprint.isSupport()) {
plus.nativeUI.toast('此设备不支持指纹识别')
uni.navigateBack()
}
if (!plus.fingerprint.isKeyguardSecure()) {
plus.nativeUI.toast('此设备未设置密码锁屏')
uni.navigateBack()
}
if (!plus.fingerprint.isEnrolledFingerprints()) {
plus.nativeUI.toast('此设备未录入指纹')
uni.navigateBack()
}
enabled.value = storage.getFingerLogin() || false
// #endif
})
function onFingerSwitchChange(value: boolean) {
if (value) {
const systemInfo = uni.getSystemInfoSync()
plus.device.getInfo({
success(e) {
setBiolofy({
mobile_type: systemInfo.model,
secret_key: e.uuid,
}).then((res) => {
if (res.statusCode === 200) {
storage.setFingerLogin(true)
}
})
},
fail(err) {
console.error('getDeviceInfo failed: ' + JSON.stringify(err))
},
})
} else {
storage.setFingerLogin(false)
}
}
</script>
<style scoped lang="scss">

View File

@@ -2,56 +2,44 @@
<view class="securityCenter">
<u-cell-group>
<u-cell title="修改密码" @click="navigateTo('/pages/mine/set/securityCenter/updatePwdTab')"></u-cell>
<u-cell title="注销账户" @click="zhuxiao"></u-cell>
<u-cell title="注销账户" @click="confirmAccountDeletion"></u-cell>
</u-cell-group>
</view>
</template>
<script>
export default {
data() {
return {
mobile: "", //存储手机号
};
},
<script setup lang="ts">
function navigateTo(url: string) {
uni.navigateTo({ url })
}
methods: {
zhuxiao(){
uni.showModal({
title: "警告",
content: "您确定要注销当前账号吗?",
confirmText: "确定注销",
confirmColor: "#FF0000",
cancelText: "取消",
success: (res) => {
if (res.confirm) {
uni.showModal({
title: "谨慎操作",
content: "再次向您确认,您确定要注销当前账号吗?",
confirmText: "坚持注销",
confirmColor: "#FF0000",
cancelText: "取消",
success: (res) => {
if (res.confirm) {
uni.showToast({
title: "您的注销申请已经提交,待管理员审核后。会自动注销当前账号",
duration: 10000,
});
}
},
});
}
},
});
function confirmAccountDeletion() {
uni.showModal({
title: '警告',
content: '您确定要注销当前账号吗?',
confirmText: '确定注销',
confirmColor: '#FF0000',
cancelText: '取消',
success: (res) => {
if (res.confirm) {
uni.showModal({
title: '谨慎操作',
content: '再次向您确认,您确定要注销当前账号吗?',
confirmText: '坚持注销',
confirmColor: '#FF0000',
cancelText: '取消',
success: (confirmRes) => {
if (confirmRes.confirm) {
uni.showToast({
title: '您的注销申请已经提交,待管理员审核后。会自动注销当前账号',
duration: 10000,
})
}
},
})
}
},
navigateTo(url) {
uni.navigateTo({
url: url,
});
},
},
};
})
}
</script>
<style lang="scss" scoped>

View File

@@ -7,22 +7,10 @@
</view>
</template>
<script>
export default {
data() {
return {
mobile: "", //存储手机号
};
},
methods: {
navigateTo(url) {
uni.navigateTo({
url: url,
});
},
},
};
<script setup lang="ts">
function navigateTo(url: string) {
uni.navigateTo({ url })
}
</script>
<style lang="scss" scoped>

View File

@@ -38,112 +38,95 @@
</view>
</template>
<script>
import config from "@/config/config";
export default {
data() {
return {
config,
userImage: config.defaultUserPhoto,
isCertificate: false,
userInfo: {},
fileSizeString: "0B",
};
},
<script setup lang="ts">
import { ref } from 'vue'
import { onShow } from '@dcloudio/uni-app'
import config from '@/config/config'
import { isLogin, tipsToLogin, quiteLoginOut, logoff } from '@/utils/filters.js'
methods: {
navigateTo(url) {
if (url == "/pages/set/securityCenter/securityCenter") {
url += `?mobile=${this.userInfo.mobile}`;
}
uni.navigateTo({
url: url,
});
},
const userImage = config.defaultUserPhoto
const userInfo = ref<Record<string, any>>({})
const fileSizeString = ref('0B')
getCacheSize() {
let that = this;
plus.cache.calculate(function (size) {
let sizeCache = parseInt(size);
if (sizeCache == 0) {
that.fileSizeString = "0B";
} else if (sizeCache < 1024) {
that.fileSizeString = sizeCache + "B";
} else if (sizeCache < 1048576) {
that.fileSizeString = (sizeCache / 1024).toFixed(2) + "KB";
} else if (sizeCache < 1073741824) {
that.fileSizeString = (sizeCache / 1048576).toFixed(2) + "MB";
} else {
that.fileSizeString = (sizeCache / 1073741824).toFixed(2) + "GB";
}
});
},
onShow(() => {
userInfo.value = isLogin() || {}
// #ifdef APP-PLUS
getCacheSize()
// #endif
})
checkUserInfo() {
if (this.isLogin("auth")) {
this.navigateTo("/pages/mine/set/personMsg");
} else {
this.tipsToLogin();
}
},
function navigateTo(url: string) {
if (url === '/pages/mine/set/securityCenter/securityCenter') {
url += `?mobile=${userInfo.value.mobile || ''}`
}
uni.navigateTo({ url })
}
clearCache() {
let that = this;
let os = plus.os.name;
if (os == "Android") {
let main = plus.android.runtimeMainActivity();
let sdRoot = main.getCacheDir();
let files = plus.android.invoke(sdRoot, "listFiles");
let len = files.length;
for (let i = 0; i < len; i++) {
let filePath = "" + files[i];
plus.io.resolveLocalFileSystemURL(
filePath,
function (entry) {
if (entry.isDirectory) {
entry.removeRecursively(
function () {
uni.showToast({
title: "缓存清理完成",
duration: 2000,
icon: "none",
});
that.getCacheSize();
},
function () {}
);
} else {
entry.remove();
}
},
function () {
uni.showToast({
title: "文件路径读取失败",
duration: 2000,
icon: "none",
});
}
);
}
} else {
plus.cache.clear(function () {
uni.showToast({
title: "缓存清理完成",
duration: 2000,
icon: "none",
});
that.getCacheSize();
});
}
},
},
onShow() {
this.userInfo = this.isLogin();
// #ifdef APP-PLUS
this.getCacheSize();
// #endif
},
};
function getCacheSize() {
// #ifdef APP-PLUS
plus.cache.calculate((size) => {
const sizeCache = parseInt(String(size))
if (sizeCache === 0) {
fileSizeString.value = '0B'
} else if (sizeCache < 1024) {
fileSizeString.value = `${sizeCache}B`
} else if (sizeCache < 1048576) {
fileSizeString.value = `${(sizeCache / 1024).toFixed(2)}KB`
} else if (sizeCache < 1073741824) {
fileSizeString.value = `${(sizeCache / 1048576).toFixed(2)}MB`
} else {
fileSizeString.value = `${(sizeCache / 1073741824).toFixed(2)}GB`
}
})
// #endif
}
function checkUserInfo() {
if (isLogin('auth')) {
navigateTo('/pages/mine/set/personMsg')
} else {
tipsToLogin()
}
}
function clearCache() {
// #ifdef APP-PLUS
const os = plus.os.name
if (os === 'Android') {
const main = plus.android.runtimeMainActivity()
const sdRoot = main.getCacheDir()
const files = plus.android.invoke(sdRoot, 'listFiles')
const len = files.length
for (let i = 0; i < len; i++) {
const filePath = `${files[i]}`
plus.io.resolveLocalFileSystemURL(
filePath,
(entry) => {
if (entry.isDirectory) {
entry.removeRecursively(
() => {
uni.showToast({ title: '缓存清理完成', duration: 2000, icon: 'none' })
getCacheSize()
},
() => {}
)
} else {
entry.remove()
}
},
() => {
uni.showToast({ title: '文件路径读取失败', duration: 2000, icon: 'none' })
}
)
}
} else {
plus.cache.clear(() => {
uni.showToast({ title: '缓存清理完成', duration: 2000, icon: 'none' })
getCacheSize()
})
}
// #endif
}
</script>
<style lang="scss" scoped>

View File

@@ -1,58 +1,45 @@
<template>
<div>
<u-collapse v-if="versionData.length !=0">
<u-collapse-item class="version-item" :title="item.versionName" v-for="(item, index) in versionData" :key="index">
<!-- {{item.body}} -->
{{item.content}}
<u-collapse v-if="versionList.length !== 0">
<u-collapse-item
class="version-item"
:title="item.versionName"
v-for="(item, index) in versionList"
:key="index"
>
{{ item.content }}
</u-collapse-item>
</u-collapse>
<u-empty class="empty" v-else text="暂无版本信息" mode="list"></u-empty>
</div>
</template>
<script>
import { getAppVersionList } from "@/api/message";
export default {
data() {
return {
versionData: [],
appType: "",
params: {
pageNumber: 1,
pageSize: 10,
},
};
},
mounted() {
const platform = uni.getSystemInfoSync().platform;
/**
* 获取是否是安卓
*/
if (platform === "android") {
this.appType = "ANDROID";
} else {
this.IosWhether = true;
this.appType = "IOS";
}
this.getVersionList();
},
methods: {
async getVersionList() {
let res = await getAppVersionList(this.appType, this.params);
if (res.data.success) {
this.versionData = res.data.result.records;
}
},
},
};
<script setup lang="ts">
import { ref } from 'vue'
import { onLoad } from '@dcloudio/uni-app'
import { getAppVersionList } from '@/api/message'
const versionList = ref<any[]>([])
const appType = ref('')
const params = { pageNumber: 1, pageSize: 10 }
onLoad(() => {
const platform = uni.getSystemInfoSync().platform
appType.value = platform === 'android' ? 'ANDROID' : 'IOS'
fetchVersionList()
})
async function fetchVersionList() {
const res = await getAppVersionList(appType.value, params)
if (res.data.success) {
versionList.value = res.data.result.records
}
}
</script>
<style scoped lang="scss">
.version-item{
padding: 10rpx;
background: #fff;
.version-item {
padding: 10rpx;
background: #fff;
}
</style>
</style>