提交 a36158fe 作者: 方治民

feat: 更新初始配置 + 接口配置 + 登录/退出 + 通用个人中心页面等相关内容

上级 333f6d07
# APP 名称
VITE_GLOB_APP_NAME = Basic APP
VITE_GLOB_APP_NAME = 数智农服
# APP 描述
VITE_GLOB_APP_DESCRIPTION = APP 基础工程
VITE_GLOB_APP_DESCRIPTION = 湖南省农业服务平台
# API 接口地址
VITE_GLOB_API_URL=http://192.168.0.110:8081
VITE_GLOB_API_URL=http://111.22.182.169:49600
# API 接口地址前缀
VITE_GLOB_API_URL_PREFIX=/api
VITE_GLOB_API_URL_PREFIX=/jeecgboot
{
"name": "agri-app",
"name": "湖南省农业服务平台",
"version": "1.0.2",
"description": "数智农服",
"keywords": [
......
......@@ -2,7 +2,6 @@
import { onExit } from '@dcloudio/uni-app'
import { isDevMode } from '@/utils/env'
import { usePermissions } from '@/hooks/app/usePermissions'
import { closeSplashscreenAndChechUpgrade } from '@/utils/upgrade'
// import * as Push from '@/utils/push'
......@@ -27,11 +26,6 @@
setTimeout(() => {
plus.navigator.closeSplashscreen()
}, 3000)
} else {
setTimeout(() => {
// 检查更新
closeSplashscreenAndChechUpgrade()
}, 1500)
}
// #endif
})
......
import { otherHttp } from '/@/utils/http/axios'
enum Api {
getUserInfo = '/sys/user/login/setting/getUserData', // 查询登录用户信息
logout = '/sys/logout', // 登出
sysLogin = '/sys/mLogin', // 登陆
}
/**
* @param params 请求参数
* @description: 查询登录用户信息
*/
export function getUserInfo(params = {}) {
return otherHttp.get({
url: Api.getUserInfo,
data: params,
})
}
/**
* @param params 请求参数
* @description: 登录
*/
export function sysLogin(params = {}) {
return otherHttp.post({
url: Api.sysLogin,
params,
})
}
/**
* @param params 请求参数
* @description: 退出登录
*/
export function logout(params = {}) {
return otherHttp.get({
url: Api.logout,
params,
})
}
......@@ -8,7 +8,7 @@
/* #ifndef APP-NVUE */
page {
/* 行为相关颜色 */
--fui-color-primary: #465CFF;
--fui-color-primary: #4da25b;
--fui-color-success: #09BE4F;
--fui-color-warning: #FFB703;
--fui-color-danger: #FF2B2B;
......
{
"pages": [
{
"path": "pages/login/login",
"style": {
"navigationStyle": "custom",
"transparentTitle": "auto",
"backgroundColor": "#FFFFFF",
"enablePullDownRefresh": false,
"app-plus": {
"titleNView": {}
}
}
},
{
"path": "pages/shouye/shouye",
"style": {
"navigationBarTitleText": "",
......@@ -70,6 +82,29 @@
}
}
},
{
"path": "pages/mine/index",
"style": {
"navigationBarTitleText": "我的",
"app-plus": {
"titleNView": false,
"bounce": false
}
}
},
{
"path": "pages/mine/components/myMessage",
"style": {
"navigationBarTitleText": "个人资料",
"enablePullDownRefresh": false,
"navigationBarBackgroundColor": "#F8F8F8",
"navigationBarTextStyle": "black",
"backgroundColorBottom": "#F2F2F2",
"app-plus": {
"titleNView": {}
}
}
},
// pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocation/pages
{
"path": "pages/index/index",
......@@ -215,7 +250,7 @@
"text": "农知"
},
{
"pagePath": "pages/wode/wode",
"pagePath": "pages/mine/index",
"iconPath": "static/images/codefun/me.png",
"selectedIconPath": "static/images/codefun/me.active.png",
"text": "我的"
......
<script setup lang="ts">
// import * as API from '/@/api/model/userInfo'
import { useUserStore } from '@/store/modules/user'
const model = reactive({
userId: '',
show: false,
descr: '',
state: '',
version: '',
loading: false,
msg: {
avatar: '/static/logo.png',
realname: '',
orgCodeTxt: '',
phone: '15688642241',
postText: '',
email: '',
sex: 1, // 1 男 2 女
},
})
const userStore = useUserStore()
onLoad(() => {
const { userId, realname, orgCodeTxt, postText, avatar, phone, sex, email } = userStore.getUserInfo
model.userId = userId
model.msg.realname = realname
model.msg.orgCodeTxt = orgCodeTxt
model.msg.postText = postText
model.msg.phone = phone
model.msg.email = email
model.msg.sex = sex
if (avatar) {
model.msg.avatar = avatar
}
})
onShow(async () => {
// await API.getUserInfo().then((res) => {
// model.msg = res
// })
// if (!model.msg.avatar) {
// if (uni.getStorageSync('AvatarUrl')) {
// model.msg.avatar = uni.getStorageSync('AvatarUrl')
// } else {
// model.msg.avatar = '/static/logo.png'
// }
// }
})
function previewImg() {
console.log(11)
const imgsArray = []
imgsArray[0] = model.msg.avatar
uni.previewImage({
current: 0,
urls: imgsArray,
})
}
</script>
<template>
<view class="pb-3 flex flex-col">
<view class="bg-#fff w-700/750 m-auto h-160 headBox">
<view class="h-full flex justify-between items-center avtar">
<text class="text-#999999">头像</text>
<image
:src="model.msg.avatar"
class="avtarImg"
background="transparent"
style="box-shadow: 0 0 20rpx #656565"
@click="previewImg"
/>
</view>
</view>
<view class="bg-#fff w-700/750 m-auto bodyBox">
<view class="msgBox flex justify-between items-center text-30">
<view class="text-#999999"> 姓名 </view>
<view class="text-#333333">
{{ model.msg.realname }}
</view>
</view>
<view class="msgBox flex justify-between items-center text-30">
<view class="text-#999999"> 性别 </view>
<view class="text-#333333">
{{ model.msg.sex === 1 ? '男' : model.msg.sex === 2 ? ' 女' : '- -' }}
</view>
</view>
<view class="msgBox flex justify-between items-center text-30">
<view class="text-#999999"> 手机号码 </view>
<view class="text-#333333">
{{ model.msg.phone }}
</view>
</view>
<view class="msgBox flex justify-between items-center text-30">
<view class="text-#999999"> 邮箱 </view>
<view class="text-#333333">
{{ model.msg.email }}
</view>
</view>
<view class="msgBox flex justify-between items-center text-30">
<view class="text-#999999"> 部门 </view>
<view class="text-#333333 w-8/10">
<fui-overflow-hidden
size="30"
align="right"
:text="model.msg.orgCodeTxt ? `${model.msg.orgCodeTxt}` : '- -'"
/>
<!-- {{ model.msg.orgCodeTxt ? model.msg.orgCodeTxt : '- -' }} -->
</view>
</view>
<view class="msgBox lastBox flex justify-between items-center text-30">
<view class="text-#999999"> 岗位 </view>
<view class="text-#333333">
{{ model.msg.postText ? model.msg.postText : '- -' }}
</view>
</view>
</view>
</view>
</template>
<style lang="scss" scoped>
.headBox {
margin-top: 24rpx;
border-radius: 16rpx;
.avtar {
padding: 0 24rpx;
}
.avtarImg {
width: 112rpx;
height: 112rpx;
border-radius: 50%;
}
}
.bodyBox {
margin-top: 20rpx;
border-radius: 16rpx;
// height: 100rpx;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
.msgBox {
width: 92.3%;
min-height: 100rpx;
// padding: 0 24rpx;
border-bottom: 1rpx solid #eeeeee;
// border: 1px solid #000;
}
.lastBox {
border: none;
}
}
</style>
export function getColor(val) {
const style = {} as any
if (val && val === 'DISTRIBUTE') {
style.background = 'rgba(255, 208, 0, 0.2)'
style.color = 'rgba(220, 170, 0, 1)'
} else if (val && val === 'ARRIVE') {
style.background = 'rgba(254, 164, 59, 0.2)'
style.color = 'rgba(255, 151, 30, 1)'
} else if (val && val === 'DISPATCH') {
style.background = 'rgba(255, 111, 111, 0.2)'
style.color = 'rgba(255, 83, 83, 1)'
} else if (val && val === 'FEEDBACK') {
style.background = 'rgba(80, 184, 255, 0.2)'
style.color = 'rgba(80, 184, 255, 1)'
} else if (val && val === 'OVER') {
style.background = 'rgba(91, 207, 83, 0.2)'
style.color = 'rgba(91, 207, 83, 1)'
} else if (val && val === 'CANCEL') {
style.background = 'rgba(204, 204, 204, 0.2)'
style.color = 'rgba(173, 173, 173, 1)'
}
return style
}
<script setup lang="ts">
import { reactive } from 'vue'
import { onPullDownRefresh } from '@dcloudio/uni-app'
import { closeSplashscreenAndChechUpgrade } from '@/utils/upgrade'
onLoad(() => {
// 关闭启动页并检查更新
closeSplashscreenAndChechUpgrade()
})
// 下拉刷新
onPullDownRefresh(() => {
......
......@@ -2,10 +2,15 @@ import { defineStore } from 'pinia'
import { store } from '/@/store'
import { Storage } from '@/utils/storage'
import { TOKEN_KEY, USER_INFO_KEY } from '@/enums/cacheEnum'
import type { defs } from '@/api/services'
import Navigate from '@/utils/page/navigate'
import * as API from '/@/api/model/userInfo'
export type UserInfo = Partial<defs.UserInfo>
export interface UserInfo {
id: string
phone: string
avatar: string
realname: string
}
interface UserState {
userInfo: Nullable<UserInfo>
......@@ -50,7 +55,7 @@ export const useUserStore = defineStore({
* @returns 是否为审核账号
*/
isAuditMode(): boolean {
return this.getUserInfo?.mobile === '10000000001'
return this.getUserInfo?.phone === '10000000001'
},
},
actions: {
......@@ -69,7 +74,7 @@ export const useUserStore = defineStore({
this.loading = true
try {
await API.auth.logout.request()
await API.logout()
} finally {
this.setToken(null)
this.setUserInfo(null)
......@@ -84,7 +89,7 @@ export const useUserStore = defineStore({
this.loading = true
try {
const userInfo = await API.userView.getUserInfo.request()
const userInfo = await API.getUserInfo()
this.setUserInfo(userInfo)
} finally {
this.loading = false
......
......@@ -15,7 +15,7 @@
/* 颜色变量 */
/* 行为相关颜色 */
$uni-color-primary: #007aff;
$uni-color-primary: #4da25b;
$uni-color-success: #4cd964;
$uni-color-warning: #f0ad4e;
$uni-color-error: #dd524d;
......
export default {
/**
* 公司官网
*/
company: 'https://yiring.com',
/**
* 服务协议地址
*/
services: 'https://app.yiring.com/agri/app/agreement.html',
/**
* 隐私政策地址
*/
privacy: 'https://app.yiring.com/agri/app/guide.html',
/**
* 从内部打开指定页面
* @param link 链接
* @param title 页面标题
*/
to(link: string, title: string) {
uni.navigateTo({
url: `/pages/common/webview/index?title=${encodeURIComponent(title)}&link=${encodeURIComponent(link)}`,
})
},
/**
* 从外部打开指定页面
* @param link 链接
*/
open(link: string) {
// #ifdef APP-PLUS
if (link?.startsWith('tel:')) {
uni.makePhoneCall({
phoneNumber: link.replace('tel:', ''),
})
} else {
plus.runtime.openURL(link)
}
// #endif
// #ifdef H5
window.open(link)
// #endif
},
}
......@@ -20,6 +20,8 @@ import { API_URL, API_URL_PREFIX } from '/@/utils/net'
import { handleResponseResource } from '/@/utils/proxy'
import { useUserStoreWithOut } from '@/store/modules/user'
// import { useUserStoreWithOut } from '@/store/modules/user'
const globSetting = useGlobSetting()
const urlPrefix = globSetting.urlPrefix
const { createMessage, createErrorModal } = useMessage()
......@@ -51,18 +53,18 @@ const transform: AxiosTransform = {
throw new Error(t('sys.api.apiRequestFailed'))
}
// 这里 status,body,message为 后台统一的字段,需要在 types.ts 内修改为项目自己的接口返回格式
const { status, body, message, details } = data
const { code, result, message, details } = data
// 这里逻辑可以根据项目进行修改
const hasSuccess = data && Reflect.has(data, 'status') && status === HTTP.Status.OK
const hasSuccess = (data && Reflect.has(data, 'code') && code === HTTP.Status.OK) || code === 0
if (hasSuccess) {
return handleResponseResource(body, options)
return handleResponseResource(result, options)
}
// 在此处根据自己项目的实际情况对不同的code执行不同的操作
// 如果不希望中断当前请求,请return数据,否则直接抛出异常即可
let timeoutMsg = ''
switch (status) {
switch (code) {
case HTTP.Status.UNAUTHORIZED: {
timeoutMsg = t('sys.api.unauthorizeMessage')
......@@ -155,12 +157,18 @@ const transform: AxiosTransform = {
// 请求之前处理config
const userStore = useUserStoreWithOut()
const token = userStore.getToken
if (token && (config as Recordable)?.requestOptions?.withToken !== false) {
// jwt token
;(config as Recordable).headers[options.authenticationHeader] = options.authenticationScheme
;(config as Recordable).headers['X-Access-Token'] = options.authenticationScheme
? `${options.authenticationScheme} ${token}`
: token
}
if (token) {
config.headers['X-Access-Token'] = token
}
return config
},
......@@ -202,7 +210,7 @@ const transform: AxiosTransform = {
throw new Error(error as unknown as string)
}
checkStatus(error?.response?.status, msg, errorMessageMode)
checkStatus(error?.response?.code, msg, errorMessageMode)
// 添加自动重试机制 保险起见 只针对GET请求
const retryRequest = new AxiosRetry()
......@@ -224,14 +232,14 @@ function createAxios(opt?: Partial<CreateAxiosOptions>) {
// authenticationScheme: 'Bearer',
authenticationScheme: '',
// authenticationHeader: 'Authorization',
authenticationHeader: 'App-Token',
authenticationHeader: 'X-Access-Token',
timeout: 10 * 1000,
// 基础接口地址
// baseURL: globSetting.apiUrl,
// headers: { 'Content-Type': ContentTypeEnum.JSON },
// 如果是form-data格式
headers: { 'Content-Type': ContentTypeEnum.FORM_URLENCODED },
headers: { 'Content-Type': ContentTypeEnum.JSON },
// 数据处理方式
transform: clone(transform),
// 配置项,下面的选项都可以在独立的接口请求中覆盖
......@@ -272,22 +280,29 @@ function createAxios(opt?: Partial<CreateAxiosOptions>) {
// TODO: 实际项目所需的请求配置,可自定义扩展
export const defHttp = createAxios({
headers: { 'Content-Type': ContentTypeEnum.FORM_URLENCODED },
requestOptions: {
apiUrl: API_URL,
urlPrefix: API_URL_PREFIX,
},
})
export const otherHttp = createAxios({
headers: { 'Content-Type': ContentTypeEnum.JSON },
requestOptions: {
apiUrl: API_URL,
urlPrefix: API_URL_PREFIX,
},
})
// other api url
// export const otherHttp = createAxios({
// transform: {
// inject: (config: AxiosRequestConfig<any>, options: http.RequestOptions) => {
// // TODO: 根据实际项目配置
// return { config, options }
// },
// },
// requestOptions: {
// apiUrl: 'xxx',
// urlPrefix: 'xxx',
// },
// })
/**
* 用于请求外部资源,不需要携带 token,返回原生 response
*/
export const externalHttp = createAxios({
requestOptions: {
apiUrl: '',
urlPrefix: '',
withToken: false,
isReturnNativeResponse: true,
},
})
......@@ -60,3 +60,18 @@ export function withInstall<T>(component: T, alias?: string) {
}
return component as T & Plugin
}
// 将 KB 转换为其他单位
export function convertKB(kb: number) {
const bytes = kb * 1024
const units = ['B', 'KB', 'MB', 'GB', 'TB']
let size = bytes
let unitIndex = 0
while (size >= 1024 && unitIndex < units.length - 1) {
size /= 1024
unitIndex++
}
return { size: size.toFixed(2), unit: units[unitIndex] }
}
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论