feat:新增功能
This commit is contained in:
parent
bc19c99ade
commit
8981806b90
5
env/.env
vendored
5
env/.env
vendored
@ -30,4 +30,7 @@ VITE_AUTH_MODE = 'single'
|
||||
VITE_COPY_NATIVE_RES_ENABLE = false
|
||||
|
||||
# sm2加密key
|
||||
VITE_SM2_KEY = '04f5084ee12767d932f293508e30e3b0100185042ec0f061dedaf92b793b93f79fd6179d5e47e25b7aec98e00cf90dd56df1f8191012537187e7bbfd2d1de299fc'
|
||||
VITE_SM2_KEY = '04f5084ee12767d932f293508e30e3b0100185042ec0f061dedaf92b793b93f79fd6179d5e47e25b7aec98e00cf90dd56df1f8191012537187e7bbfd2d1de299fc'
|
||||
|
||||
# 高德地图key
|
||||
VITE_AMAP_KEY = '1f8f159583f28dfba6eb06deb55e3b56'
|
||||
@ -18,6 +18,7 @@ onShow((options) => {
|
||||
else {
|
||||
navigateToInterceptor.invoke({ url: '/' })
|
||||
}
|
||||
|
||||
// appStore.autoLogin()
|
||||
})
|
||||
onHide(() => {
|
||||
|
||||
8
src/api/centerControl.ts
Normal file
8
src/api/centerControl.ts
Normal file
@ -0,0 +1,8 @@
|
||||
import { http } from '@/http/http'
|
||||
|
||||
/**
|
||||
* 校验SN或BikeCode
|
||||
*/
|
||||
export function checkSnOrBikeCodeAPI(query: { ecuSn: string, bikeCode: string }) {
|
||||
return http.get<any>('/operations/ebikeEcuInfo/checkSnOrBikeCode', query)
|
||||
}
|
||||
@ -1,4 +1,4 @@
|
||||
import type { IAuthLoginRes, ICaptcha, IDoubleTokenRes, IUpdateInfo, IUpdatePassword, IUserInfoRes } from './types/login'
|
||||
import type { IAuthLoginRes, ICaptcha, IDoubleTokenRes, IUpdateInfo, IUpdatePassword } from './types/login'
|
||||
import { http } from '@/http/http'
|
||||
|
||||
/**
|
||||
@ -34,17 +34,17 @@ export function refreshToken(refreshToken: string) {
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取用户信息
|
||||
* 获取当前登陆账号详情
|
||||
*/
|
||||
export function getUserInfo() {
|
||||
return http.get<IUserInfoRes>('/user/info')
|
||||
return http.get<any>('/staff/ebikeOperatorStaff/getStaffInfo')
|
||||
}
|
||||
|
||||
/**
|
||||
* 退出登录
|
||||
*/
|
||||
export function logout() {
|
||||
return http.get<void>('/auth/logout')
|
||||
return http.get<any>('/staff/ebikeOperatorStaff/logout')
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
0
src/api/types/centerControl.ts
Normal file
0
src/api/types/centerControl.ts
Normal file
@ -0,0 +1,162 @@
|
||||
<script lang="ts" setup>
|
||||
import { useCenterControlStore } from '@/store'
|
||||
|
||||
// 列表数据
|
||||
const props = defineProps(['code', 'type'])
|
||||
const centerStore = useCenterControlStore()
|
||||
const list_item_style = computed(() => {
|
||||
return {
|
||||
padding: '20rpx 0',
|
||||
borderBottom: '2rpx solid #cccccc',
|
||||
fontSize: '28rpx',
|
||||
color: '#6a6a6a',
|
||||
}
|
||||
})
|
||||
|
||||
const list_item_btn_style = computed(() => {
|
||||
return {
|
||||
height: '35px',
|
||||
fontSize: '24rpx',
|
||||
}
|
||||
})
|
||||
|
||||
const type = ref<'car' | 'sn' | ''>('')
|
||||
const code = ref<string>('')
|
||||
|
||||
const list = reactive({
|
||||
online: {
|
||||
msg: 'asdas',
|
||||
name: '在线测试',
|
||||
key: 'online',
|
||||
status: 'none', // none,loading,success,fail
|
||||
tip: '',
|
||||
btnText: '执行',
|
||||
btnLoadingText: '执行中',
|
||||
btnLoading: false,
|
||||
},
|
||||
findEbike: {
|
||||
msg: 'asdas',
|
||||
name: '在线测试',
|
||||
key: 'findEbike',
|
||||
status: 'none', // none,loading,success,fail
|
||||
tip: '',
|
||||
btnText: '执行',
|
||||
btnLoadingText: '执行中',
|
||||
btnLoading: false,
|
||||
},
|
||||
})
|
||||
|
||||
// 初始化单个列表数据
|
||||
function initListItem(key: string) {
|
||||
list[key].status = 'none'
|
||||
list[key].msg = ''
|
||||
}
|
||||
|
||||
function handleBtnClick(value: any, key: string, index: number) {
|
||||
initListItem(key)
|
||||
list[key].btnLoading = true
|
||||
list[key].status = 'loading'
|
||||
setTimeout(() => {
|
||||
list[key].btnLoading = false
|
||||
list[key].status = 'success'
|
||||
list[key].msg = '执行成功'
|
||||
}, 2000)
|
||||
}
|
||||
|
||||
watch(() => props.code, (newVal) => {
|
||||
code.value = newVal
|
||||
}, { immediate: true })
|
||||
|
||||
watch(() => props.type, (newVal) => {
|
||||
type.value = newVal
|
||||
}, { immediate: true })
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<view class="list-main">
|
||||
<uv-list>
|
||||
<uv-list-item
|
||||
v-for="(value, key, index) in list"
|
||||
:key="key"
|
||||
:custom-style="list_item_style"
|
||||
>
|
||||
<view class="list-item">
|
||||
<view class="text_bar">
|
||||
<view>{{ value.name }} </view>
|
||||
<view class="result">
|
||||
<uv-transition
|
||||
:custom-style="{
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
}"
|
||||
:duration="200"
|
||||
:show="value.status === 'fail'"
|
||||
>
|
||||
<uv-icon name="info-circle" color="red" />
|
||||
<text style="color: red;">{{ value.msg }}</text>
|
||||
</uv-transition>
|
||||
|
||||
<uv-transition
|
||||
:custom-style="{
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
}"
|
||||
:duration="200"
|
||||
:show="value.status === 'success'"
|
||||
>
|
||||
<uv-icon name="checkmark-circle" color="#07c160" />
|
||||
<text style="color: #07c160;">{{ value.msg }}</text>
|
||||
</uv-transition>
|
||||
</view>
|
||||
</view>
|
||||
<view class="btn_bar">
|
||||
<uv-button
|
||||
:loading="value.btnLoading"
|
||||
:loading-text="value.btnLoadingText"
|
||||
:disabled="centerStore.isOnline !== 1"
|
||||
type="primary" :text="value.btnText"
|
||||
:custom-style="list_item_btn_style"
|
||||
@click="handleBtnClick(value, key, index)"
|
||||
/>
|
||||
</view>
|
||||
</view>
|
||||
</uv-list-item>
|
||||
</uv-list>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.list-main {
|
||||
margin-top: 20rpx;
|
||||
width: calc(100% - 40rpx);
|
||||
padding: 20rpx;
|
||||
background-color: white;
|
||||
border-radius: 10rpx;
|
||||
box-shadow: 0 0 10rpx rgba(0, 0, 0, 0.1);
|
||||
|
||||
.list-item {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
|
||||
.text_bar {
|
||||
font-size: 28rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.result {
|
||||
margin-left: 30rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.btn_bar {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.transition {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
</style>
|
||||
@ -0,0 +1,124 @@
|
||||
<script lang="ts" setup>
|
||||
import { checkSnOrBikeCodeAPI } from '@/api/centerControl'
|
||||
import { useCenterControlStore } from '@/store'
|
||||
import { scanCode } from '@/utils/tools'
|
||||
|
||||
const props = defineProps(['code', 'type'])
|
||||
const emits = defineEmits(['change', 'update:code', 'update:type'])
|
||||
const store = useCenterControlStore()
|
||||
const code = ref('')
|
||||
const btnLoading = ref(false)
|
||||
|
||||
function handleType() {
|
||||
code.value = ''
|
||||
store.setCode(store.codeType === 'car' ? 'sn' : 'car', code.value)
|
||||
store.setOnline(-1)
|
||||
}
|
||||
|
||||
// 扫码
|
||||
function handleScan() {
|
||||
scanCode({
|
||||
isSN: store.codeType === 'sn',
|
||||
success: (res: any) => {
|
||||
|
||||
},
|
||||
fail: () => {
|
||||
uni.showToast({
|
||||
title: '扫码失败',
|
||||
icon: 'none',
|
||||
})
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
function handleInput(val: string) {
|
||||
store.setCode(store.codeType, val)
|
||||
store.setOnline(-1)
|
||||
}
|
||||
|
||||
// 连接
|
||||
async function handleConnect() {
|
||||
btnLoading.value = true
|
||||
try {
|
||||
const isOnline = await checkSnOrBikeCodeAPI(store.queryByBike)
|
||||
isOnline ? store.setOnline(1) : store.setOnline(0)
|
||||
btnLoading.value = false
|
||||
}
|
||||
catch (e) {
|
||||
console.error('连接----->', e)
|
||||
btnLoading.value = false
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<view class="main">
|
||||
<view class="search">
|
||||
<uv-button plain style="margin-right: 25rpx;" @click="handleType">
|
||||
<uv-icon
|
||||
name="jiantou_shangxiaqiehuan"
|
||||
custom-prefix="custom-icon"
|
||||
size="20"
|
||||
/>
|
||||
<text>{{ store.codeType === 'car' ? '车辆编号' : "中控SN" }}</text>
|
||||
</uv-button>
|
||||
<uv-input
|
||||
v-model="code"
|
||||
placeholder="请输入或扫码"
|
||||
style="width: 100%;"
|
||||
@input="handleInput"
|
||||
>
|
||||
<template #suffix>
|
||||
<uv-icon name="scan" size="22" @click="handleScan" />
|
||||
</template>
|
||||
</uv-input>
|
||||
</view>
|
||||
<view class="online">
|
||||
<view>
|
||||
<text style="color: #6a6a6a;">设备在线状态:{{ store.isOnline ? '' : '' }}</text>
|
||||
<text
|
||||
:style="{
|
||||
color: store.isOnline === 1 ? '#00c7c7' : store.isOnline === 0 ? '#ff0000' : '',
|
||||
}"
|
||||
>
|
||||
{{ store.isOnline === 1 ? '在线' : store.isOnline === 0 ? '离线' : '未连接' }}
|
||||
</text>
|
||||
</view>
|
||||
<uv-button
|
||||
type="primary"
|
||||
text="连接"
|
||||
:loading="btnLoading"
|
||||
loading-text="连接中"
|
||||
:custom-style="{
|
||||
height: '35px',
|
||||
fontSize: '24rpx',
|
||||
}"
|
||||
@click="handleConnect"
|
||||
/>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.main {
|
||||
width: calc(100% - 80rpx);
|
||||
padding: 20rpx 40rpx;
|
||||
background-color: white;
|
||||
border-radius: 10rpx;
|
||||
box-shadow: 0 0 10rpx rgba(0, 0, 0, 0.1);
|
||||
|
||||
.search {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.online {
|
||||
margin-top: 50rpx;
|
||||
font-size: 28rpx;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
40
src/pages-sub/centerControl/testControl/testControl.vue
Normal file
40
src/pages-sub/centerControl/testControl/testControl.vue
Normal file
@ -0,0 +1,40 @@
|
||||
<script lang="ts" setup>
|
||||
import executionList from './components/executionList.vue'
|
||||
import scanByTest from './components/scanByTest.vue'
|
||||
|
||||
definePage({
|
||||
style: {
|
||||
navigationBarTitleText: '测试中控',
|
||||
navigationBarBackgroundColor: '#1488f5',
|
||||
navigationBarTextStyle: 'white',
|
||||
},
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<z-paging
|
||||
ref="paging"
|
||||
bg-color="#f3f3f3"
|
||||
>
|
||||
<view class="container">
|
||||
<!-- 测试中控内容输入框 -->
|
||||
<scan-by-test />
|
||||
|
||||
<!-- 测试中控执行列表 -->
|
||||
<executionList />
|
||||
</view>
|
||||
|
||||
<template #bottom>
|
||||
<view class="bottom-button-zaping">
|
||||
<uv-button type="primary" text="自动化测试" />
|
||||
</view>
|
||||
</template>
|
||||
</z-paging>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.container {
|
||||
width: calc(100% - 40rpx);
|
||||
padding: 10rpx 20rpx;
|
||||
}
|
||||
</style>
|
||||
54
src/pages-sub/setting/index.vue
Normal file
54
src/pages-sub/setting/index.vue
Normal file
@ -0,0 +1,54 @@
|
||||
<script lang="ts" setup>
|
||||
import { useAppStore } from '@/store'
|
||||
|
||||
definePage({
|
||||
style: {
|
||||
navigationBarTitleText: '个人信息',
|
||||
navigationBarBackgroundColor: '#1488f5',
|
||||
navigationBarTextStyle: 'white',
|
||||
},
|
||||
})
|
||||
|
||||
const appStore = useAppStore()
|
||||
const userInfo = ref<any>({})
|
||||
|
||||
async function logout() {
|
||||
uni.showModal({
|
||||
title: '提示',
|
||||
content: '确定要退出登录吗?',
|
||||
success(res) {
|
||||
if (res.confirm) {
|
||||
logout()
|
||||
}
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
// 获取用户信息
|
||||
userInfo.value = appStore.getUserInfo()
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<z-paging
|
||||
ref="paging"
|
||||
:default-page-no="Number('1')"
|
||||
:default-page-size="Number('100')"
|
||||
:auto-show-back-to-top="Boolean(true)"
|
||||
>
|
||||
<uv-cell-group>
|
||||
<uv-cell title="账号" :value="userInfo.username" />
|
||||
</uv-cell-group>
|
||||
|
||||
<template #bottom>
|
||||
<view class="bottom-button-zaping">
|
||||
<uv-button type="error" text="退出登录" @click="logout()" />
|
||||
</view>
|
||||
</template>
|
||||
</z-paging>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
//
|
||||
</style>
|
||||
@ -69,7 +69,7 @@ const rules = {
|
||||
// 扫码获取车辆编号
|
||||
function codeScan(type: string) {
|
||||
scanCode({
|
||||
isBikeCode: type === 'ecuCode',
|
||||
isSN: type === 'ecuCode',
|
||||
success: (res: any) => {
|
||||
console.log(res)
|
||||
|
||||
|
||||
191
src/pages/home/home.vue
Normal file
191
src/pages/home/home.vue
Normal file
@ -0,0 +1,191 @@
|
||||
<script lang="ts" setup>
|
||||
import { getLoalcation, getMapContext } from '@/utils/map'
|
||||
import { systemInfo } from '@/utils/systemInfo'
|
||||
|
||||
const navBarHeight = systemInfo.statusBarHeight * 2 + 80 || 200// 导航栏高度
|
||||
const height = (systemInfo.screenHeight - navBarHeight)
|
||||
|
||||
definePage({
|
||||
style: {
|
||||
navigationStyle: 'custom',
|
||||
},
|
||||
})
|
||||
|
||||
const list = ref([
|
||||
{
|
||||
name: '关注',
|
||||
},
|
||||
{
|
||||
name: '推荐',
|
||||
},
|
||||
{
|
||||
name: '热榜',
|
||||
},
|
||||
])
|
||||
/**
|
||||
* 地图引用
|
||||
*/
|
||||
const mapContext = ref<any>(null)
|
||||
const mapRef = ref<any>()
|
||||
const mapConfig = reactive({
|
||||
scale: 14,
|
||||
latitude: 0,
|
||||
longitude: 0,
|
||||
})
|
||||
const visionCenter = reactive({
|
||||
latitude: 0,
|
||||
longitude: 0,
|
||||
})
|
||||
|
||||
// 定位
|
||||
function orientation() {
|
||||
if (!mapContext.value) {
|
||||
return console.error('地图未初始化')
|
||||
}
|
||||
getLoalcation(
|
||||
{
|
||||
mapContext: mapContext.value,
|
||||
moveCenter: true,
|
||||
success: (res: any) => {
|
||||
console.log('定位成功', res)
|
||||
const { latitude, longitude } = res
|
||||
mapConfig.latitude = latitude
|
||||
mapConfig.longitude = longitude
|
||||
},
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
function regionchange(e: any) {
|
||||
console.log('regionchange', e)
|
||||
const { centerLocation, type } = e.detail
|
||||
if (type !== 'end') {
|
||||
return
|
||||
}
|
||||
// TUDO: 更新视野中心点(有缺陷)
|
||||
// visionCenter.latitude = centerLocation.latitude
|
||||
// visionCenter.longitude = centerLocation.longitude
|
||||
}
|
||||
function initMap() {
|
||||
mapContext.value = getMapContext('mapRef', getCurrentInstance())
|
||||
orientation()
|
||||
}
|
||||
function onZoom(lx: 'in' | 'out') {
|
||||
mapConfig.latitude = visionCenter.latitude
|
||||
mapConfig.longitude = visionCenter.longitude
|
||||
switch (lx) {
|
||||
case 'out':
|
||||
mapConfig.scale += 1
|
||||
break
|
||||
case 'in':
|
||||
mapConfig.scale -= 1
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
initMap()
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<view class="container">
|
||||
<!-- 导航栏 -->
|
||||
<view class="nav" :style="{ height: `${navBarHeight}rpx` }">
|
||||
<view class="tabs">
|
||||
<uv-tabs
|
||||
line-color="#ffffff"
|
||||
:list="list" :active-style="{
|
||||
color: '#ffffff',
|
||||
fontWeight: 'bold',
|
||||
transform: 'scale(1.05)',
|
||||
}"
|
||||
:inactive-style="{
|
||||
color: '#cccccc',
|
||||
transform: 'scale(1)',
|
||||
}"
|
||||
/>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 地图 -->
|
||||
<map
|
||||
id="mapRef"
|
||||
ref="mapRef"
|
||||
:style="{ width: '100%', height: `${height}px` }"
|
||||
:show-location="true"
|
||||
:scale="mapConfig.scale"
|
||||
:latitude="mapConfig.latitude"
|
||||
:longitude="mapConfig.longitude"
|
||||
@regionchange="regionchange"
|
||||
/>
|
||||
|
||||
<!-- 左侧工具栏 -->
|
||||
<view class="left-toolbar">
|
||||
<!-- <uv-button
|
||||
icon="plus" class="m-b_10"
|
||||
:custom-style="{
|
||||
width: '70rpx',
|
||||
height: '70rpx',
|
||||
}"
|
||||
@click="onZoom('out')"
|
||||
/>
|
||||
<uv-button
|
||||
icon="minus"
|
||||
class="m-b_10"
|
||||
:custom-style="{
|
||||
width: '70rpx',
|
||||
height: '70rpx',
|
||||
}"
|
||||
@click="onZoom('in')"
|
||||
/> -->
|
||||
<uv-button
|
||||
:custom-style="{
|
||||
width: '70rpx',
|
||||
height: '70rpx',
|
||||
}"
|
||||
@click="orientation"
|
||||
>
|
||||
<template #suffix>
|
||||
<uv-icon
|
||||
name="ditu_dingwei"
|
||||
custom-prefix="custom-icon"
|
||||
size="28"
|
||||
/>
|
||||
</template>
|
||||
</uv-button>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.container {
|
||||
width: 100%;
|
||||
height: 100vh;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
|
||||
.nav {
|
||||
width: 100%;
|
||||
background-color: #1488f5;
|
||||
position: relative;
|
||||
|
||||
.tabs {
|
||||
width: 70%;
|
||||
position: absolute;
|
||||
bottom: 15rpx;
|
||||
left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.left-toolbar {
|
||||
position: fixed;
|
||||
left: 20rpx;
|
||||
top: 50%;
|
||||
background-color: #bcb9b966;
|
||||
z-index: 999;
|
||||
padding: 10rpx;
|
||||
border-radius: 10rpx;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@ -1,113 +0,0 @@
|
||||
<script lang="ts" setup>
|
||||
import { getBikecodeAPI } from '@/api/test'
|
||||
import { safeAreaInsets } from '@/utils/systemInfo'
|
||||
|
||||
defineOptions({
|
||||
name: 'Home',
|
||||
})
|
||||
definePage({
|
||||
style: {
|
||||
// 'custom' 表示开启自定义导航栏,默认 'default'
|
||||
navigationStyle: 'custom',
|
||||
navigationBarTitleText: '首页',
|
||||
},
|
||||
})
|
||||
|
||||
const description = ref(
|
||||
'unibest 是一个集成了多种工具和技术的 uniapp 开发模板,由 uniapp + Vue3 + Ts + Vite5 + UnoCss + VSCode 构建,模板具有代码提示、自动格式化、统一配置、代码片段等功能,并内置了许多常用的基本组件和基本功能,让你编写 uniapp 拥有 best 体验。',
|
||||
)
|
||||
console.log('index/index 首页打印了')
|
||||
|
||||
onLoad(() => {
|
||||
console.log('测试 uni API 自动引入: onLoad')
|
||||
getBikecodeAPI('060002').then((res) => {
|
||||
console.log('getBikecodeAPI res: ', res)
|
||||
})
|
||||
})
|
||||
|
||||
// #region gotoAbout
|
||||
function gotoAbout() {
|
||||
uni.navigateTo({
|
||||
url: '/pages-sub/about/about',
|
||||
})
|
||||
}
|
||||
// #endregion
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<view class="bg-white px-4 pt-2" :style="{ marginTop: `${safeAreaInsets?.top}px` }">
|
||||
<view class="mt-10">
|
||||
<image src="/static/logo.svg" alt="" class="mx-auto block h-28 w-28" />
|
||||
</view>
|
||||
<view class="main-title-color mt-4 text-center text-4xl">
|
||||
unibest
|
||||
</view>
|
||||
<view class="mb-8 mt-2 text-center text-2xl">
|
||||
最好用的 uniapp 开发模板
|
||||
</view>
|
||||
|
||||
<view class="m-auto mb-2 max-w-100 text-justify indent text-4">
|
||||
{{ description }}
|
||||
</view>
|
||||
<view class="mt-4 text-center">
|
||||
作者:
|
||||
<text class="text-green-500">
|
||||
菲鸽
|
||||
</text>
|
||||
</view>
|
||||
<view class="mt-4 text-center">
|
||||
官网地址:
|
||||
<text class="text-green-500">
|
||||
https://unibest.tech
|
||||
</text>
|
||||
</view>
|
||||
|
||||
<!-- #ifdef H5 -->
|
||||
<view class="mt-4 text-center">
|
||||
<a href="https://unibest.tech/base/3-plugin" target="_blank" class="text-green-500">
|
||||
新手请看必看章节1:
|
||||
</a>
|
||||
</view>
|
||||
<!-- #endif -->
|
||||
<!-- #ifdef MP-WEIXIN -->
|
||||
<view class="mt-4 text-center">
|
||||
新手请看必看章节1:
|
||||
<text class="text-green-500">
|
||||
https://unibest.tech/base/3-plugin
|
||||
</text>
|
||||
</view>
|
||||
<!-- #endif -->
|
||||
<!-- #ifdef H5 -->
|
||||
<view class="mt-4 text-center">
|
||||
<a href="https://unibest.tech/base/14-faq" target="_blank" class="text-green-500">
|
||||
新手请看必看章节2:
|
||||
</a>
|
||||
</view>
|
||||
<!-- #endif -->
|
||||
<!-- #ifdef MP-WEIXIN -->
|
||||
<view class="mt-4 text-center">
|
||||
新手请看必看章节2:
|
||||
<text class="text-green-500">
|
||||
https://unibest.tech/base/14-faq
|
||||
</text>
|
||||
</view>
|
||||
<!-- #endif -->
|
||||
|
||||
<view class="mt-4 text-center">
|
||||
<uv-button type="primary">
|
||||
UI组件按钮
|
||||
</uv-button>
|
||||
</view>
|
||||
<view class="mt-4 text-center">
|
||||
UI组件官网:<text class="text-green-500">
|
||||
https://www.uvui.cn
|
||||
</text>
|
||||
</view>
|
||||
<view class="mt-4 text-center">
|
||||
<wd-button type="primary" class="ml-2" @click="gotoAbout">
|
||||
前往示例页
|
||||
</wd-button>
|
||||
</view>
|
||||
<view class="h-6" />
|
||||
</view>
|
||||
</template>
|
||||
@ -1,5 +1,5 @@
|
||||
<script lang="ts" setup>
|
||||
import { loginAPI } from '@/api/login'
|
||||
import { getUserInfo, loginAPI } from '@/api/login'
|
||||
import { useAppStore } from '@/store'
|
||||
import CacheManager from '@/utils/CacheManager'
|
||||
|
||||
@ -35,6 +35,8 @@ async function login() {
|
||||
const token = await loginAPI(formData)
|
||||
CacheManager.set('token', token)
|
||||
isLogin.value = false
|
||||
const userInfo = await getUserInfo()
|
||||
appStore.setUserInfo(userInfo) // 获取字典数据
|
||||
appStore.setDictData() // 获取字典数据
|
||||
appStore.loginJump()
|
||||
}
|
||||
|
||||
@ -1,4 +1,6 @@
|
||||
<script lang="ts" setup>
|
||||
import { useAppStore } from '@/store'
|
||||
|
||||
interface IClass {
|
||||
key: string
|
||||
name: string
|
||||
@ -12,9 +14,10 @@ definePage({
|
||||
},
|
||||
})
|
||||
|
||||
const isSeleid = ref<string>('')
|
||||
const appStore = useAppStore()
|
||||
const userInfo = ref<any>({})
|
||||
|
||||
// 仓库板块图标
|
||||
const isSeleid = ref<string>('')
|
||||
const btnList = ref([
|
||||
{
|
||||
key: 'maintenance',
|
||||
@ -95,7 +98,7 @@ const btnList = ref([
|
||||
{
|
||||
key: 'detectionecu',
|
||||
name: '测试中控',
|
||||
path: '/pages/warehouse/detectionecu/detectionecu',
|
||||
path: '/pages-sub/centerControl/testControl/testControl',
|
||||
customsrc: 'ceshi',
|
||||
},
|
||||
{
|
||||
@ -148,7 +151,7 @@ const btnList = ref([
|
||||
},
|
||||
],
|
||||
},
|
||||
])
|
||||
])// 仓库板块图标
|
||||
|
||||
function onClikcList(icon: IClass, item: IClass) {
|
||||
const ikey = item.key
|
||||
@ -166,6 +169,18 @@ function onClikcList(icon: IClass, item: IClass) {
|
||||
isSeleid.value = ''
|
||||
}, 200) // 延迟100毫秒后执行
|
||||
}
|
||||
|
||||
function goSetting() {
|
||||
console.log('goSetting')
|
||||
uni.navigateTo({
|
||||
url: '/pages-sub/setting/index',
|
||||
})
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
// 获取用户信息
|
||||
userInfo.value = appStore.getUserInfo()
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@ -177,7 +192,7 @@ function onClikcList(icon: IClass, item: IClass) {
|
||||
<uv-avatar text="李" font-size="22" />
|
||||
<view class="info">
|
||||
<view class="classname">
|
||||
姓名
|
||||
{{ userInfo.username || '--' }}
|
||||
</view>
|
||||
<view class="tags">
|
||||
<uv-tags text="股东" size="mini" />
|
||||
@ -185,7 +200,7 @@ function onClikcList(icon: IClass, item: IClass) {
|
||||
</view>
|
||||
</view>
|
||||
<view class="setting">
|
||||
<uv-icon name="setting-fill" size="22" />
|
||||
<uv-icon name="setting-fill" size="22" @click="goSetting" />
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import { defineStore } from 'pinia'
|
||||
import { logout } from '@/api/login'
|
||||
import { getCode } from '@/api/system'
|
||||
import { tabbarStore } from '@/tabbar/store'
|
||||
import CacheManager from '../utils/CacheManager'
|
||||
|
||||
// 码表类型
|
||||
@ -25,9 +25,12 @@ export const useAppStore = defineStore(
|
||||
* 跳转首页
|
||||
*/
|
||||
const loginJump = () => {
|
||||
tabbarStore.setAutoCurIdx('/pages/index/index')
|
||||
// tabbarStore.setAutoCurIdx('/pages/index/index')
|
||||
// /pages/index/index
|
||||
uni.switchTab({ url: '/pages/me/me' })
|
||||
// /pages/me/me
|
||||
setTimeout(() => {
|
||||
uni.switchTab({ url: '/pages/home/home' })
|
||||
}, 100)
|
||||
}
|
||||
/**
|
||||
* 判断用户是否登录
|
||||
@ -50,6 +53,46 @@ export const useAppStore = defineStore(
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置用户信息
|
||||
*/
|
||||
const setUserInfo = async (userInfo: any) => {
|
||||
if (userInfo) {
|
||||
CacheManager.set('userInfo', userInfo)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 退出登录
|
||||
*/
|
||||
const Logout = async () => {
|
||||
try {
|
||||
await logout()
|
||||
CacheManager.remove('userInfo')
|
||||
CacheManager.remove('token')
|
||||
CacheManager.remove('dictData')
|
||||
|
||||
uni.reLaunch({
|
||||
url: '/pages/login/login',
|
||||
})
|
||||
}
|
||||
catch (e) {
|
||||
console.error(e)
|
||||
uni.showToast({
|
||||
title: '退出登录失败',
|
||||
icon: 'error',
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取用户信息
|
||||
*/
|
||||
const getUserInfo = () => {
|
||||
const user = CacheManager.get('userInfo')
|
||||
return user || {}
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据code查找字典数据
|
||||
*/
|
||||
@ -67,6 +110,9 @@ export const useAppStore = defineStore(
|
||||
loginJump,
|
||||
setDictData,
|
||||
getDictByCode,
|
||||
setUserInfo,
|
||||
getUserInfo,
|
||||
Logout,
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
48
src/store/centerControl.ts
Normal file
48
src/store/centerControl.ts
Normal file
@ -0,0 +1,48 @@
|
||||
import { defineStore } from 'pinia'
|
||||
|
||||
export const useCenterControlStore = defineStore(
|
||||
'centerControl',
|
||||
() => {
|
||||
const isOnline = ref(-1) // 是否在线 -1未连接 0离线 1在线
|
||||
const codeType = ref<'car' | 'sn'>('car')
|
||||
const queryByBike = reactive({
|
||||
ecuSn: '',
|
||||
bikeCode: '',
|
||||
})
|
||||
|
||||
// 设置code类型
|
||||
function setCode(type: 'car' | 'sn', code: string) {
|
||||
codeType.value = type
|
||||
queryByBike.bikeCode = ''
|
||||
queryByBike.ecuSn = ''
|
||||
if (type === 'car') {
|
||||
queryByBike.bikeCode = code
|
||||
}
|
||||
else {
|
||||
queryByBike.ecuSn = code
|
||||
}
|
||||
}
|
||||
|
||||
// 设置在线状态
|
||||
function setOnline(status: number) {
|
||||
isOnline.value = status
|
||||
}
|
||||
|
||||
// 初始化状态
|
||||
onMounted(() => {
|
||||
setOnline(-1)
|
||||
})
|
||||
|
||||
return {
|
||||
isOnline,
|
||||
queryByBike,
|
||||
codeType,
|
||||
|
||||
setOnline,
|
||||
setCode,
|
||||
}
|
||||
},
|
||||
{
|
||||
persist: true,
|
||||
},
|
||||
)
|
||||
@ -15,6 +15,7 @@ export default store
|
||||
|
||||
// 模块统一导出
|
||||
export * from './app'
|
||||
export * from './centerControl'
|
||||
export * from './operator'
|
||||
export * from './scan'
|
||||
export * from './token'
|
||||
|
||||
@ -280,7 +280,7 @@
|
||||
.m-b-5 {
|
||||
margin-bottom: 5rpx;
|
||||
}
|
||||
.m-b-10 {
|
||||
.m-b_10 {
|
||||
margin-bottom: 10rpx;
|
||||
}
|
||||
.m-b-15 {
|
||||
|
||||
File diff suppressed because one or more lines are too long
@ -57,7 +57,7 @@ export interface CustomTabBarItem {
|
||||
export const customTabbarList: CustomTabBarItem[] = [
|
||||
{
|
||||
text: '首页',
|
||||
pagePath: 'pages/index/index',
|
||||
pagePath: 'pages/home/home',
|
||||
// 注意 unocss 图标需要如下处理:(二选一)
|
||||
// 1)在fg-tabbar.vue页面上引入一下并注释掉(见tabbar/index.vue代码第2行)
|
||||
// 2)配置到 unocss.config.ts 的 safelist 中
|
||||
|
||||
@ -157,7 +157,7 @@ export const isDoubleTokenMode = import.meta.env.VITE_AUTH_MODE === 'double'
|
||||
* 通常为 /pages/index/index
|
||||
*/
|
||||
// export const HOME_PAGE = `/${(pages as PageMetaDatum[]).find(page => page.type === 'home')?.path || (pages as PageMetaDatum[])[0].path}`
|
||||
export const HOME_PAGE = `/pages/index/index`
|
||||
export const HOME_PAGE = `/pages/home/home`
|
||||
/**
|
||||
* 获取 url 的参数
|
||||
*/
|
||||
|
||||
43
src/utils/map.ts
Normal file
43
src/utils/map.ts
Normal file
@ -0,0 +1,43 @@
|
||||
// 高德地图key
|
||||
export const GAODE_MAP_KEY = import.meta.env.VITE_AMAP_KEY
|
||||
|
||||
// 获取地图实例
|
||||
export function getMapContext(mapid: string, instance: any) {
|
||||
return uni.createMapContext(mapid, {
|
||||
this: instance.proxy,
|
||||
})
|
||||
}
|
||||
|
||||
// 获取当前定位
|
||||
export function getLoalcation({
|
||||
mapContext,
|
||||
success = null,
|
||||
fail = null,
|
||||
moveCenter = false,
|
||||
}) {
|
||||
uni.getLocation({
|
||||
type: 'gcj02',
|
||||
geocode: true,
|
||||
success(res) {
|
||||
console.log('定位成功', res)
|
||||
const { latitude, longitude } = res
|
||||
if (moveCenter && mapContext) {
|
||||
moveToLocation(mapContext, longitude, latitude)
|
||||
}
|
||||
success && success({ latitude, longitude })
|
||||
},
|
||||
fail(err) {
|
||||
console.error('uni.getLocation-------', err)
|
||||
fail && fail(err)
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
// 移至中心点
|
||||
export function moveToLocation(mapContext: any, longitude: number, latitude: number) {
|
||||
const point = {
|
||||
latitude,
|
||||
longitude,
|
||||
}
|
||||
mapContext.moveToLocation(point)
|
||||
}
|
||||
@ -4,14 +4,14 @@
|
||||
* @param {Function} options.success - 成功回调函数
|
||||
* @param {Function} options.fail - 失败回调函数
|
||||
*/
|
||||
export function scanCode({ isBikeCode = false, success, fail }) {
|
||||
export function scanCode({ isSN = false, success, fail }) {
|
||||
uni.scanCode({
|
||||
success: (res) => {
|
||||
const codeStr = res.result
|
||||
console.log('扫码结果:', codeStr)
|
||||
|
||||
// 解析车牌编号
|
||||
if (isBikeCode) {
|
||||
if (isSN) {
|
||||
const codeObj = {
|
||||
IMEI: '',
|
||||
SN: '',
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user