Browse Source

Merge remote-tracking branch 'origin/lihuilin/feature-20251024095243-我的' into lihuilin/feature-20251024095243-我的

# Conflicts:
#	pages.json
#	pages/setting/account.vue
#	utils/http.js
zhaowenkang/feature-20251028181547-行情页面
lihui 4 weeks ago
parent
commit
10a8a0b96a
  1. 33
      api/member.js
  2. 6
      api/setting/general.js
  3. 44
      api/setting/password.js
  4. 2
      package-lock.json
  5. 6
      package.json
  6. 66
      pages.json
  7. 6
      pages/home/member.vue
  8. 83
      pages/setting/account.vue
  9. 245
      pages/setting/createPwd.vue
  10. 59
      pages/setting/email.vue
  11. 38
      pages/setting/font.vue
  12. 30
      pages/setting/general.vue
  13. 2
      pages/setting/introduce.vue
  14. 1
      pages/setting/market.vue
  15. 11
      pages/setting/message.vue
  16. 436
      pages/setting/password.vue
  17. 54
      pages/setting/phone.vue
  18. 50
      pages/setting/push.vue
  19. 23
      pages/setting/server.vue
  20. 21
      pages/setting/theme.vue
  21. 39
      utils/http.js
  22. 16
      vue.config.js

33
api/member.js

@ -15,7 +15,9 @@ import util from '../common/util.js'
}; };
*/ */
import { http } from '../utils/http'
import {
http
} from '../utils/http'
/** /**
@ -24,23 +26,12 @@ import { http } from '../utils/http'
* @returns {Promise<unknown>} * @returns {Promise<unknown>}
*/ */
export const getUserInfo = (data) => { export const getUserInfo = (data) => {
return http({
method: 'POST',
url: '/api/my/userInfo',
data:
data
,
})
}
return http({
method: 'POST',
url: '/api/my/userInfo',
data: data,
header:{
token:'014de5283d2930af6481ede591afd087'
}
})
}

6
api/setting/general.js

@ -1,4 +1,4 @@
import { http } from '../utils/http'
import { http } from '../../utils/http'
@ -6,8 +6,6 @@ export const getSetting = (data) => {
return http({ return http({
method: 'POST', method: 'POST',
url: '/api/my/getSetting', url: '/api/my/getSetting',
data:
data
,
data: data,
}) })
} }

44
api/setting/password.js

@ -1,4 +1,6 @@
import {http} from '../../utils/http'
import {
http
} from '../../utils/http'
/** /**
* 验证码发送 * 验证码发送
@ -6,13 +8,11 @@ import {http} from '../../utils/http'
* @returns {*} * @returns {*}
*/ */
export const sendEmail = (data) => { export const sendEmail = (data) => {
return http({
method: 'POST',
url: '/UserLogin/sendEmail',
data:
data
,
})
return http({
method: 'POST',
url: '/UserLogin/sendEmail',
data: data,
})
} }
/** /**
@ -21,11 +21,25 @@ export const sendEmail = (data) => {
* @returns {*} * @returns {*}
*/ */
export const validateCode = (data) => { export const validateCode = (data) => {
return http({
method: 'POST',
url: '/api/my/validateCode',
data:
data
,
})
return http({
method: 'POST',
url: '/api/my/validateCode',
data: data,
})
} }
export const sendPhone = (data) => {
return http({
method: 'POST',
url: '/UserLogin/sendPhone',
data: data,
})
}
export const changeBind = (data) => {
return http({
method: 'POST',
url: '/api/my/bindEmailOrPhone',
data: data,
})
}

2
package-lock.json

@ -598,6 +598,8 @@
}, },
"node_modules/pinia-plugin-persistedstate": { "node_modules/pinia-plugin-persistedstate": {
"version": "4.5.0", "version": "4.5.0",
"resolved": "https://registry.npmjs.org/pinia-plugin-persistedstate/-/pinia-plugin-persistedstate-4.5.0.tgz",
"integrity": "sha512-QTkP1xJVyCdr2I2p3AKUZM84/e+IS+HktRxKGAIuDzkyaKKV48mQcYkJFVVDuvTxlI5j6X3oZObpqoVB8JnWpw==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"deep-pick-omit": "^1.2.1", "deep-pick-omit": "^1.2.1",

6
package.json

@ -3,11 +3,9 @@
"@dcloudio/uni-ui": "^1.5.11", "@dcloudio/uni-ui": "^1.5.11",
"@element-plus/icons-vue": "^2.3.2", "@element-plus/icons-vue": "^2.3.2",
"element-plus": "^2.11.5", "element-plus": "^2.11.5",
"vue-i18n": "^9.14.5",
"marked": "^2.0.1", "marked": "^2.0.1",
"pinia": "^3.0.3", "pinia": "^3.0.3",
"pinia-plugin-persistedstate": "^4.5.0"
"pinia-plugin-persistedstate": "^4.5.0",
"vue-i18n": "^9.14.5"
} }
} }

66
pages.json

@ -29,6 +29,16 @@
} }
}, },
{ {
"path": "pages/start/index/index",
"style": {
"navigationStyle": "custom",
"navigationBarTitleText": "uni-app",
"disableSwipeBack": true,
"titleNView": false,
"bounce": false
}
},
{
"path": "pages/start/Registration/Registration", "path": "pages/start/Registration/Registration",
"style": { "style": {
"navigationBarTitleText": "", "navigationBarTitleText": "",
@ -88,33 +98,7 @@
} }
}, },
{ {
"path": "pages/marketSituation/marketSituation",
"style": {
"navigationStyle": "custom",
"disableSwipeBack": true,
"titleNView": false,
"bounce": false
}
},
{
"path": "pages/marketSituation/chartExample",
"style": {
"navigationBarTitleText": "图表示例",
"navigationBarBackgroundColor": "#ffffff",
"navigationBarTextStyle": "black"
}
},
{
"path": "pages/marketSituation/globalIndex",
"style": {
"navigationStyle": "custom",
"disableSwipeBack": true,
"titleNView": false,
"bounce": false
}
},
{
"path": "pages/marketSituation/marketDetail",
"path": "pages/home/marketSituation",
"style": { "style": {
"navigationStyle": "custom", "navigationStyle": "custom",
"disableSwipeBack": true, "disableSwipeBack": true,
@ -132,7 +116,7 @@
} }
}, },
{ {
"path": "pages/deepExploration/deepExploration",
"path": "pages/home/deepExploration",
"style": { "style": {
"navigationStyle": "custom", "navigationStyle": "custom",
"disableSwipeBack": true, "disableSwipeBack": true,
@ -150,17 +134,7 @@
} }
}, },
{ {
"path": "pages/blank/institutionalTrendsBriefing",
"style": {
"navigationBarTitleText": "",
"navigationStyle": "custom",
"disableSwipeBack": true,
"titleNView": false,
"bounce": false
}
},
{
"path": "pages/blank/notice",
"path": "pages/blank/blank",
"style": { "style": {
"navigationBarTitleText": "", "navigationBarTitleText": "",
"navigationStyle": "custom", "navigationStyle": "custom",
@ -286,26 +260,18 @@
} }
}, },
{ {
"path" : "pages/marketSituation/marketCondition",
"path" : "pages/home/marketCondition",
"style" : "style" :
{ {
"navigationBarTitleText" : "行情", "navigationBarTitleText" : "行情",
"navigationStyle": "custom" "navigationStyle": "custom"
} }
},{
"path": "pages/deepExploration/MainForceActions",
"style": {
"navigationStyle": "custom",
"disableSwipeBack": true,
"titleNView": false,
"bounce": false
}
}, },
{ {
"path" : "pages/deepExploration/stockSelectDetail",
"path" : "pages/setting/createPwd",
"style" : "style" :
{ {
"navigationBarTitleText": "选股策略"
"navigationBarTitleText" : "创建密码"
} }
} }
], ],

6
pages/home/member.vue

@ -79,19 +79,19 @@ import {
ArrowRight ArrowRight
} from '@element-plus/icons-vue' } from '@element-plus/icons-vue'
import footerBar from '../../components/footerBar.vue' import footerBar from '../../components/footerBar.vue'
import {getUserInfo} from "@/api/member";
import {getUserInfo} from "@/api/member"
const type = ref('member') const type = ref('member')
const iSMT = ref(0) const iSMT = ref(0)
const username = ref('') const username = ref('')
const dccode = ref('') const dccode = ref('')
const userInfoRes = ref()
const userInfoRes = ref()//
userInfoRes.value = getUserInfo() userInfoRes.value = getUserInfo()
userInfoRes.value.then(res => { userInfoRes.value.then(res => {
username.value = res.data.username username.value = res.data.username
dccode.value = res.data.dccode dccode.value = res.data.dccode
console.log('用户信息', res.data)
console.log('用户信息', userInfoRes.value)
}) })

83
pages/setting/account.vue

@ -9,41 +9,37 @@
<text class="item-label">头像</text> <text class="item-label">头像</text>
<view class="item-right"> <view class="item-right">
<image src="/static/avatar.png" class="avatar" mode="aspectFill"></image> <image src="/static/avatar.png" class="avatar" mode="aspectFill"></image>
<uni-icons type="arrowright" size="16" class="arrow"></uni-icons>
<uni-icons type="arrowright" size="16"></uni-icons>
</view> </view>
</view> </view>
<view class="setting-item"> <view class="setting-item">
<text class="item-label">昵称</text> <text class="item-label">昵称</text>
<view class="item-right"> <view class="item-right">
<text class="item-text">DeepChart</text>
<uni-icons type="arrowright" size="16" class="arrow"></uni-icons>
<text class="item-text">{{userInfoRes.dcname}}</text>
<uni-icons type="arrowright" size="16"></uni-icons>
</view> </view>
</view> </view>
<view class="setting-item"> <view class="setting-item">
<text class="item-label">ID</text> <text class="item-label">ID</text>
<view class="item-right"> <view class="item-right">
<text class="item-text">{{ jwcode }}</text>
<uni-icons type="arrowright" size="16" class="arrow"></uni-icons>
</view>
</view>
<view class="setting-item">
<text class="item-label">密码</text>
<view class="item-right">
<text class="item-text">qwertyuiop</text>
<uni-icons type="eye" size="16" class="eye-icon"></uni-icons>
<text class="item-text">{{ userInfoRes.dccode }}</text>
</view> </view>
</view> </view>
<view class="setting-item" @click="goToPassword"> <view class="setting-item" @click="goToPassword">
<text class="item-label">修改密码</text>
<uni-icons type="arrowright" size="16" class="arrow"></uni-icons>
<text class="item-label">
<template #default>
{{ userInfoRes.hasPwd === 0 ? '创建密码' : '修改密码' }}
</template>
</text>
<uni-icons type="arrowright" size="16"></uni-icons>
</view> </view>
<view class="setting-item"> <view class="setting-item">
<text class="item-label">注销账号</text> <text class="item-label">注销账号</text>
<uni-icons type="arrowright" size="16" class="arrow"></uni-icons>
<uni-icons type="arrowright" size="16"></uni-icons>
</view> </view>
<view class="setting-item" @click="goToBind"> <view class="setting-item" @click="goToBind">
<text class="item-label">绑定账号</text> <text class="item-label">绑定账号</text>
<uni-icons type="arrowright" size="16" class="arrow"></uni-icons>
<uni-icons type="arrowright" size="16"></uni-icons>
</view> </view>
</view> </view>
@ -71,37 +67,52 @@
ref, ref,
onMounted onMounted
} from 'vue' } from 'vue'
import {useUserStore} from "../../stores/modules/userInfo"
import {
getUserInfo
} from "@/api/member";
const iSMT = ref(0) const iSMT = ref(0)
const jwcode = ref('90047681')
// const dccode = ref('')
const userInfoRes = ref({})
const showLogout = ref(false) const showLogout = ref(false)
const userStore = useUserStore()
const handleConfirmLogout = () => {
userStore.clearUserInfo()
const userInfoPromise = getUserInfo()
userInfoPromise.then(res => {
if (res.code === 200) {
userInfoRes.value.dccode = res.data.dccode;
userInfoRes.value.dcname = res.data.dcname;
userInfoRes.value.hasPwd = res.data.hasPassword;
console.log('用户信息', userInfoRes.value)
} else {
uni.showToast({
title: '用户信息请求失败',
icon: 'none',
})
}
})
const handleConfirmLogout = () => {
showLogout.value = false showLogout.value = false
uni.showToast({ uni.showToast({
title: '退出登录成功', title: '退出登录成功',
icon: 'none', icon: 'none',
}) })
uni.navigateTo({
url: '/pages/start/login/login'
})
} }
const goToBind = () =>{
const goToBind = () => {
uni.navigateTo({ uni.navigateTo({
url:'../setting/bind'
url: '../setting/bind'
}) })
} }
const goToPassword = () =>{
uni.navigateTo({
url:'../setting/password'
})
const goToPassword = () => {
if (userInfoRes.value.hasPwd === 0) {
uni.navigateTo({
url: '../setting/createPwd'
})
} else {
uni.navigateTo({
url: '../setting/password'
})
}
} }
onMounted(() => { onMounted(() => {
@ -111,7 +122,7 @@
<style scoped> <style scoped>
.setting-list { .setting-list {
height: 49vh;
height: 42vh;
background-color: #fff; background-color: #fff;
} }

245
pages/setting/createPwd.vue

@ -0,0 +1,245 @@
<template>
<view class="main">
<view :style="{height:iSMT+'px'}"></view>
<view class="tab">
<view class="tab-item" :class="{active: activeTab === 'email'}" @click="activeTab = 'email'">邮箱</view>
<view class="tab-item" :class="{active: activeTab === 'phone'}" @click="activeTab = 'phone'">手机号</view>
</view>
<view class="switch-tab">
<view class="input-list" v-if="activeTab === 'email'">
<image src="/static/my/changeEmail.png" mode="aspectFit"></image>
<input type="text" placeholder="请输入邮箱" class="input" v-model="userEmail" />
<button class="code-btn" :class="{disabled: gettingCode}" @click="getCode" :disabled="gettingCode">
{{ gettingCode ? `重新发送 ${time}s` : '获取验证码' }}
</button>
</view>
<view class="input-list" v-else>
<image src="/static/my/changeBindPhone.png" mode="aspectFit"></image>
<input type="number" placeholder="请输入手机号" class="input" v-model="userPhone" />
<button class="code-btn" :class="{disabled: gettingCode}" @click="getCode" :disabled="gettingCode">
{{ gettingCode ? `重新发送 ${time}s` : '获取验证码' }}
</button>
</view>
<view class="input-list">
<image src="/static/my/verification.png" mode="aspectFit"></image>
<input type="text" placeholder="请输入验证码" class="input" v-model="verifyCode" />
</view>
</view>
<view class="btn-area">
<button class="next-btn" @click="goToPwdNext">下一步</button>
</view>
</view>
</template>
<script setup>
import {
ref,
onMounted
} from 'vue'
import {
sendEmail,
validateCode,
sendPhone
} from "@/api/setting/password";
const iSMT = ref(0)
const activeTab = ref('email')
const gettingCode = ref(false)
const time = ref(60)
const userEmail = ref('')
const userPhone = ref('')
const verifyCode = ref('')
const getCode = () => {
if (gettingCode.value) return
gettingCode.value = true
time.value = 2
const timer = setInterval(() => {
time.value--
if (time.value <= 0) {
clearInterval(timer)
gettingCode.value = false
time.value = 2
}
}, 1000)
if (activeTab.value === 'email') {
sendEmail({
email: userEmail.value
})
} else {
sendPhone({
phone: userPhone.value
})
}
}
const goToPwdNext = async () => {
if (!userEmail.value) {
uni.showToast({
title: '请输入邮箱',
icon: 'none'
})
return
}
if (!verifyCode.value) {
uni.showToast({
title: '请输入验证码',
icon: 'none'
})
return
}
try {
let param;
if (activeTab.value === 'email') {
param = {
loginType: 'EMAIL',
account: userEmail.value,
verifyCode: verifyCode.value
}
} else {
param = {
loginType: 'PHONE',
account: userPhone.value,
verifyCode: verifyCode.value
}
}
const res = await validateCode(param)
console.log('看看参数', param)
console.log('看看结果', res)
//
if (res.code === 200) {
uni.showToast({
title: '验证成功',
icon: 'success'
})
uni.navigateTo({
url: '../setting/nextPwd'
})
} else {
uni.showToast({
title: res.msg || '验证失败',
icon: 'none'
})
}
} catch (err) {
console.error(err)
uni.showToast({
title: '请求出错',
icon: 'none'
})
}
}
onMounted(() => {
//
iSMT.value = uni.getSystemInfoSync().statusBarHeight;
})
</script>
<style>
.tab {
display: flex;
height: 8vh;
background-color: #fff;
border-bottom: 1rpx solid #eee;
}
.tab-item {
flex: 1;
display: flex;
justify-content: center;
align-items: center;
font-size: 32rpx;
position: relative;
}
.tab-item.active {
color: #000;
font-weight: bold;
}
.tab-item.active::after {
content: '';
position: absolute;
bottom: 0;
left: 50%;
transform: translateX(-50%);
width: 40rpx;
height: 6rpx;
background-color: #000;
/* ????? */
}
.switch-tab {
background-color: #fff;
padding: 0 60rpx;
}
.input-list {
display: flex;
align-items: center;
justify-content: center;
height: 7vh;
border-bottom: 1rpx solid #eee;
}
.input-list image {
width: 40rpx;
height: 40rpx;
margin-right: 20rpx;
}
.input {
flex: 1;
height: 14vh;
font-size: 28rpx;
}
.code-btn {
width: 200rpx;
height: 60rpx;
font-size: 24rpx;
border-radius: 10rpx;
background-color: #eee;
color: #666;
display: flex;
align-items: center;
justify-content: center;
}
.code-btn.disabled {
background-color: #ccc;
color: #999;
}
.btn-area {
height: 8vh;
background-color: white;
padding-top: 120rpx;
}
.next-btn {
width: 610rpx;
height: 85rpx;
background-color: #000;
color: #fff;
font-size: 30rpx;
border-radius: 40rpx;
display: flex;
align-items: center;
justify-content: center;
}
</style>

59
pages/setting/email.vue

@ -15,11 +15,10 @@
<view class="top-list"> <view class="top-list">
<view class="left"> <view class="left">
<img src="/static/my/changeEmail.png" /> <img src="/static/my/changeEmail.png" />
<text class="label">+86</text>
<input type="number" placeholder="请输入您的换绑邮箱" class="input" />
<input v-model="userEmail" placeholder="请输入您的换绑邮箱" class="input" />
</view> </view>
<view class="right"> <view class="right">
<button class="verification" :class="{ 'disabled': gettingCode }" @click="getVerification"
<button class="verification" :class="{ 'disabled': gettingCode }" @click="getCode"
:disabled="gettingCode"> :disabled="gettingCode">
{{ gettingCode ? `重新发送 ${time}s` : '获取验证码' }} {{ gettingCode ? `重新发送 ${time}s` : '获取验证码' }}
</button> </button>
@ -35,7 +34,7 @@
</view> </view>
<view class="bottom"> <view class="bottom">
<button class="change-btn">换绑</button>
<button class="change-btn" @click="changeAccount">换绑</button>
</view> </view>
</view> </view>
</template> </template>
@ -45,23 +44,67 @@
ref, ref,
onMounted onMounted
} from 'vue' } from 'vue'
import {
getUserInfo
} from "@/api/member"
import {
sendEmail,
changeBind
} from "@/api/setting/password"
const iSMT = ref(0) const iSMT = ref(0)
const email = ref('analsak@16.com')
const email = ref('')
const gettingCode = ref(false) const gettingCode = ref(false)
const time = ref(60) const time = ref(60)
const userEmail = ref('')
const userInfoPromise = getUserInfo()
userInfoPromise.then(res => {
if (res.code === 200) {
console.log('个人信息', res.data)
email.value = res.data.email
} else {
uni.showToast({
title: '用户信息请求失败',
icon: 'none',
})
}
})
const getVerification = () => {
const changeAccount = () => {
const res = changeBind({
verificateType: 0,
account: userEmail.value
})
if(res.code === 200){
uni.showToast({
title: '绑定成功',
icon: 'none',
})
}else {
uni.showToast({
title: '用户绑定失败',
icon: 'none',
})
}
}
const getCode = () => {
if (gettingCode.value) return if (gettingCode.value) return
gettingCode.value = true gettingCode.value = true
time.value = 60
time.value = 2
const timer = setInterval(() => { const timer = setInterval(() => {
time.value-- time.value--
if (time.value <= 0) { if (time.value <= 0) {
clearInterval(timer) clearInterval(timer)
gettingCode.value = false gettingCode.value = false
time.value = 2
} }
}, 1000) }, 1000)
sendEmail({
email: userEmail.value
})
} }
onMounted(() => { onMounted(() => {
@ -131,7 +174,7 @@
.change-btn { .change-btn {
height: 85rpx; height: 85rpx;
width: 610rpx; width: 610rpx;
padding:0 20rpx;
padding: 0 20rpx;
background-color: black; background-color: black;
color: white; color: white;
border-radius: 40rpx; border-radius: 40rpx;

38
pages/setting/font.vue

@ -4,18 +4,18 @@
<view class="top"> <view class="top">
<view class="top-list"> <view class="top-list">
<text>标准</text> <text>标准</text>
<radio value="0" class="radio-btn" activeBackgroundColor="red"
:checked="selectedIndex === 0" @click="selectFont(0)" />
<radio value="0" class="radio-btn" activeBackgroundColor="red" :checked="selectedIndex === 0"
@click="selectFont(0)" />
</view> </view>
<view class="top-list"> <view class="top-list">
<text>中号</text> <text>中号</text>
<radio value="1" class="radio-btn" activeBackgroundColor="red"
:checked="selectedIndex === 1" @click="selectFont(1)" />
<radio value="1" class="radio-btn" activeBackgroundColor="red" :checked="selectedIndex === 1"
@click="selectFont(1)" />
</view> </view>
<view class="top-list"> <view class="top-list">
<text>大号</text> <text>大号</text>
<radio value="2" class="radio-btn" activeBackgroundColor="red"
:checked="selectedIndex === 2" @click="selectFont(2)" />
<radio value="2" class="radio-btn" activeBackgroundColor="red" :checked="selectedIndex === 2"
@click="selectFont(2)" />
</view> </view>
</view> </view>
</view> </view>
@ -26,17 +26,39 @@
ref, ref,
onMounted onMounted
} from 'vue' } from 'vue'
import {
getSetting
} from "@/api/setting/general"
const iSMT = ref(0) const iSMT = ref(0)
const selectedIndex = ref(0) const selectedIndex = ref(0)
const getFont = async () => {
try {
const res = await getSetting()
if (res.code === 200) {
const fontSize = res.data.fontSize
const sizeMap = {
small: 0,
medium: 1,
large: 2
}
console.log('看看字体', res.data.fontSize)
selectedIndex.value = sizeMap[fontSize] ?? 0;
}
} catch (err) {
console.error("获取字体设置失败:", err);
}
}
const selectFont = (index) => { const selectFont = (index) => {
selectedIndex.value = index selectedIndex.value = index
console.log('看看选中状态',selectedIndex.value)
console.log('看看选中状态', selectedIndex.value)
} }
onMounted(() => { onMounted(() => {
// //
iSMT.value = uni.getSystemInfoSync().statusBarHeight; iSMT.value = uni.getSystemInfoSync().statusBarHeight;
console.log('看看高度', iSMT.value) console.log('看看高度', iSMT.value)
getFont()
}) })
</script> </script>
@ -53,7 +75,7 @@
display: flex; display: flex;
align-items: center; align-items: center;
margin: 0 40rpx; margin: 0 40rpx;
padding:0 10rpx;
padding: 0 10rpx;
border-bottom: 1rpx solid #eee; border-bottom: 1rpx solid #eee;
} }

30
pages/setting/general.vue

@ -3,37 +3,37 @@
<view :style="{height:iSMT+'px'}"></view> <view :style="{height:iSMT+'px'}"></view>
<view class="top"> <view class="top">
<view class="top-list"> <view class="top-list">
<text>语言</text>
<text class="label">语言</text>
<text class="language">{{settingRes.language}}</text> <text class="language">{{settingRes.language}}</text>
<uni-icons type="arrowright" size="16" class="arrow" />
<uni-icons type="arrowright" size="16" />
</view> </view>
<view class="top-list" @click="goToFont"> <view class="top-list" @click="goToFont">
<text>字体大小</text>
<uni-icons type="arrowright" size="16" class="arrow" />
<text class="label">字体大小</text>
<uni-icons type="arrowright" size="16" />
</view> </view>
<view class="top-list" @click="goToTheme"> <view class="top-list" @click="goToTheme">
<text>主题切换</text>
<uni-icons type="arrowright" size="16" class="arrow" />
<text class="label">主题切换</text>
<uni-icons type="arrowright" size="16" />
</view> </view>
</view> </view>
<view class="center"> <view class="center">
<view class="center-list" @click="goToMessage"> <view class="center-list" @click="goToMessage">
<text>消息推送</text>
<uni-icons type="arrowright" size="16" class="arrow" />
<text class="label">消息推送</text>
<uni-icons type="arrowright" size="16" />
</view> </view>
</view> </view>
<view class="bottom"> <view class="bottom">
<view class="bottom-list" @click="goToServer"> <view class="bottom-list" @click="goToServer">
<text>切换服务器</text>
<uni-icons type="arrowright" size="16" class="arrow" />
<text class="label">切换服务器</text>
<uni-icons type="arrowright" size="16" />
</view> </view>
<view class="bottom-list" @click="clearCache"> <view class="bottom-list" @click="clearCache">
<text>清理缓存</text>
<text class="label">清理缓存</text>
<text class="cache">{{ cache }}M</text> <text class="cache">{{ cache }}M</text>
<uni-icons type="arrowright" size="16" class="arrow" />
<uni-icons type="arrowright" size="16" />
</view> </view>
</view> </view>
</view> </view>
@ -171,7 +171,6 @@ onMounted(() => {
} }
.cache { .cache {
margin-left: 55%;
font-size: 14px; font-size: 14px;
color: rgb(203, 203, 203); color: rgb(203, 203, 203);
} }
@ -179,4 +178,9 @@ onMounted(() => {
.bottom-list:last-child { .bottom-list:last-child {
border-bottom: none; border-bottom: none;
} }
.label{
flex:1;
font-size:28rpx;
}
</style> </style>

2
pages/setting/introduce.vue

@ -13,7 +13,7 @@
的品牌标签DeepChart=全球最懂机构行为的AI主打"深度解读机构行为"的APP</view> 的品牌标签DeepChart=全球最懂机构行为的AI主打"深度解读机构行为"的APP</view>
<view class="title">2.产品介绍</view> <view class="title">2.产品介绍</view>
<view class="main-text">DeepChart是一款以"Al智能体为决策核心的智能投资分析平台
<view class="main-text">DeepChart是一款以"Al智能体"为决策核心的智能投资分析平台
专注于深度研究机构行为专为全球散户投资者量身打造它重新定义了人与投资工具之间的关系 专注于深度研究机构行为专为全球散户投资者量身打造它重新定义了人与投资工具之间的关系
是一个真正懂投资懂市场更懂用户的AI投资伙伴</view> 是一个真正懂投资懂市场更懂用户的AI投资伙伴</view>

1
pages/setting/market.vue

@ -206,6 +206,7 @@
.indicator-text { .indicator-text {
font-size: 28rpx; font-size: 28rpx;
flex:1;
} }
.indicator-icons { .indicator-icons {

11
pages/setting/message.vue

@ -3,10 +3,10 @@
<view :style="{height:iSMT+'px'}"></view> <view :style="{height:iSMT+'px'}"></view>
<view class="top"> <view class="top">
<view class="top-list" @click="goToPush"> <view class="top-list" @click="goToPush">
<text>语言</text>
<text class="text">消息推送</text>
<text class="message" v-if="isMessage">通知已开启</text> <text class="message" v-if="isMessage">通知已开启</text>
<text class="message" v-if="!isMessage">通知未开启</text> <text class="message" v-if="!isMessage">通知未开启</text>
<uni-icons type="arrowright" size="16" class="arrow" />
<uni-icons type="arrowright" size="16" />
</view> </view>
</view> </view>
</view> </view>
@ -51,12 +51,11 @@
} }
.message { .message {
margin-left: 60%;
font-size: 14px; font-size: 14px;
color: rgb(203, 203, 203); color: rgb(203, 203, 203);
} }
.arrow {
margin-left: auto;
.text{
flex:1;
} }
</style> </style>

436
pages/setting/password.vue

@ -1,207 +1,245 @@
<template> <template>
<view class="main">
<view :style="{height:iSMT+'px'}"></view>
<view class="tab">
<view class="tab-item" :class="{active: activeTab === 'email'}" @click="activeTab = 'email'">邮箱</view>
<view class="tab-item" :class="{active: activeTab === 'phone'}" @click="activeTab = 'phone'">手机号</view>
</view>
<view class="switch-tab">
<view class="input-list" v-if="activeTab === 'email'">
<image src="/static/my/changeEmail.png" mode="aspectFit"></image>
<input type="text" placeholder="请输入邮箱" class="input" v-model="userEmail"/>
<button class="code-btn" :class="{disabled: gettingCode}" @click="getCode" :disabled="gettingCode">
{{ gettingCode ? `重新发送 ${time}s` : '获取验证码' }}
</button>
</view>
<view class="input-list" v-else>
<image src="/static/my/changeBindPhone.png" mode="aspectFit"></image>
<input type="number" placeholder="请输入手机号" class="input" v-model="userPhone"/>
<button class="code-btn" :class="{disabled: gettingCode}" @click="getCode" :disabled="gettingCode">
{{ gettingCode ? `重新发送 ${time}s` : '获取验证码' }}
</button>
</view>
<view class="input-list">
<image src="/static/my/verification.png" mode="aspectFit"></image>
<input type="text" placeholder="请输入验证码" class="input" v-model="verifyCode"/>
</view>
</view>
<view class="btn-area">
<button class="next-btn" @click="goToPwdNext">下一步</button>
</view>
</view>
<view class="main">
<view :style="{height:iSMT+'px'}"></view>
<view class="tab">
<view class="tab-item" :class="{active: activeTab === 'email'}" @click="activeTab = 'email'">邮箱</view>
<view class="tab-item" :class="{active: activeTab === 'phone'}" @click="activeTab = 'phone'">手机号</view>
</view>
<view class="switch-tab">
<view class="input-list" v-if="activeTab === 'email'">
<image src="/static/my/changeEmail.png" mode="aspectFit"></image>
<input type="text" placeholder="请输入邮箱" class="input" v-model="userEmail" />
<button class="code-btn" :class="{disabled: gettingCode}" @click="getCode" :disabled="gettingCode">
{{ gettingCode ? `重新发送 ${time}s` : '获取验证码' }}
</button>
</view>
<view class="input-list" v-else>
<image src="/static/my/changeBindPhone.png" mode="aspectFit"></image>
<input type="number" placeholder="请输入手机号" class="input" v-model="userPhone" />
<button class="code-btn" :class="{disabled: gettingCode}" @click="getCode" :disabled="gettingCode">
{{ gettingCode ? `重新发送 ${time}s` : '获取验证码' }}
</button>
</view>
<view class="input-list">
<image src="/static/my/verification.png" mode="aspectFit"></image>
<input type="text" placeholder="请输入验证码" class="input" v-model="verifyCode" />
</view>
</view>
<view class="btn-area">
<button class="next-btn" @click="goToPwdNext">下一步</button>
</view>
</view>
</template> </template>
<script setup> <script setup>
import {
ref,
onMounted
} from 'vue'
import {sendEmail, validateCode} from "@/api/setting/password";
const iSMT = ref(0)
const activeTab = ref('email')
const gettingCode = ref(false)
const time = ref(60)
const userEmail = ref('')
const userPhone = ref('')
const verifyCode = ref('')
const getCode = () => {
if (gettingCode.value) return
gettingCode.value = true
time.value = 2
const timer = setInterval(() => {
time.value--
if (time.value <= 0) {
clearInterval(timer)
gettingCode.value = false
time.value = 2
}
}, 1000)
sendEmail({email: userEmail.value})
}
const goToPwdNext = () => {
if (!userEmail.value) {
uni.showToast({title: '请输入邮箱', icon: 'none'})
return
}
if (!verifyCode.value) {
uni.showToast({title: '请输入验证码', icon: 'none'})
return
}
try {
const res = validateCode({
loginType:'EMAIL',
account: userEmail.value,
verifyCode: verifyCode.value
})
console.log('validateCode 返回:', res)
//
if (res.code === 200) {
uni.showToast({title: '验证成功', icon: 'success'})
uni.navigateTo({
url: '../setting/nextPwd'
})
} else {
uni.showToast({title: res.msg || '验证失败', icon: 'none'})
}
} catch (err) {
console.error(err)
uni.showToast({title: '请求出错', icon: 'none'})
}
}
onMounted(() => {
//
iSMT.value = uni.getSystemInfoSync().statusBarHeight;
})
import {
ref,
onMounted
} from 'vue'
import {
sendEmail,
validateCode,
sendPhone
} from "@/api/setting/password";
const iSMT = ref(0)
const activeTab = ref('email')
const gettingCode = ref(false)
const time = ref(60)
const userEmail = ref('')
const userPhone = ref('')
const verifyCode = ref('')
const getCode = () => {
if (gettingCode.value) return
gettingCode.value = true
time.value = 2
const timer = setInterval(() => {
time.value--
if (time.value <= 0) {
clearInterval(timer)
gettingCode.value = false
time.value = 2
}
}, 1000)
if (activeTab.value === 'email') {
sendEmail({
email: userEmail.value
})
} else {
sendPhone({
phone: userPhone.value
})
}
}
const goToPwdNext = async () => {
if (!userEmail.value) {
uni.showToast({
title: '请输入邮箱',
icon: 'none'
})
return
}
if (!verifyCode.value) {
uni.showToast({
title: '请输入验证码',
icon: 'none'
})
return
}
try {
let param;
if (activeTab.value === 'email') {
param = {
loginType: 'EMAIL',
account: userEmail.value,
verifyCode: verifyCode.value
}
} else {
param = {
loginType: 'PHONE',
account: userPhone.value,
verifyCode: verifyCode.value
}
}
const res = await validateCode(param)
console.log('看看参数', param)
console.log('看看结果', res)
//
if (res.code === 200) {
uni.showToast({
title: '验证成功',
icon: 'success'
})
uni.navigateTo({
url: '../setting/nextPwd'
})
} else {
uni.showToast({
title: res.msg || '验证失败',
icon: 'none'
})
}
} catch (err) {
console.error(err)
uni.showToast({
title: '请求出错',
icon: 'none'
})
}
}
onMounted(() => {
//
iSMT.value = uni.getSystemInfoSync().statusBarHeight;
})
</script> </script>
<style> <style>
.tab {
display: flex;
height: 8vh;
background-color: #fff;
border-bottom: 1rpx solid #eee;
}
.tab-item {
flex: 1;
display: flex;
justify-content: center;
align-items: center;
font-size: 32rpx;
position: relative;
}
.tab-item.active {
color: #000;
font-weight: bold;
}
.tab-item.active::after {
content: '';
position: absolute;
bottom: 0;
left: 50%;
transform: translateX(-50%);
width: 40rpx;
height: 6rpx;
background-color: #000; /* ????? */
}
.switch-tab {
background-color: #fff;
padding: 0 60rpx;
}
.input-list {
display: flex;
align-items: center;
justify-content: center;
height: 7vh;
border-bottom: 1rpx solid #eee;
}
.input-list image {
width: 40rpx;
height: 40rpx;
margin-right: 20rpx;
}
.input {
flex: 1;
height: 14vh;
font-size: 28rpx;
}
.code-btn {
width: 200rpx;
height: 60rpx;
font-size: 24rpx;
border-radius: 10rpx;
background-color: #eee;
color: #666;
display: flex;
align-items: center;
justify-content: center;
}
.code-btn.disabled {
background-color: #ccc;
color: #999;
}
.btn-area {
height: 8vh;
background-color: white;
padding-top: 120rpx;
}
.next-btn {
width: 610rpx;
height: 85rpx;
background-color: #000;
color: #fff;
font-size: 30rpx;
border-radius: 40rpx;
display: flex;
align-items: center;
justify-content: center;
}
.tab {
display: flex;
height: 8vh;
background-color: #fff;
border-bottom: 1rpx solid #eee;
}
.tab-item {
flex: 1;
display: flex;
justify-content: center;
align-items: center;
font-size: 32rpx;
position: relative;
}
.tab-item.active {
color: #000;
font-weight: bold;
}
.tab-item.active::after {
content: '';
position: absolute;
bottom: 0;
left: 50%;
transform: translateX(-50%);
width: 40rpx;
height: 6rpx;
background-color: #000;
/* ????? */
}
.switch-tab {
background-color: #fff;
padding: 0 60rpx;
}
.input-list {
display: flex;
align-items: center;
justify-content: center;
height: 7vh;
border-bottom: 1rpx solid #eee;
}
.input-list image {
width: 40rpx;
height: 40rpx;
margin-right: 20rpx;
}
.input {
flex: 1;
height: 14vh;
font-size: 28rpx;
}
.code-btn {
width: 200rpx;
height: 60rpx;
font-size: 24rpx;
border-radius: 10rpx;
background-color: #eee;
color: #666;
display: flex;
align-items: center;
justify-content: center;
}
.code-btn.disabled {
background-color: #ccc;
color: #999;
}
.btn-area {
height: 8vh;
background-color: white;
padding-top: 120rpx;
}
.next-btn {
width: 610rpx;
height: 85rpx;
background-color: #000;
color: #fff;
font-size: 30rpx;
border-radius: 40rpx;
display: flex;
align-items: center;
justify-content: center;
}
</style> </style>

54
pages/setting/phone.vue

@ -11,15 +11,14 @@
<text class="label">已绑手机号{{ phone }}</text> <text class="label">已绑手机号{{ phone }}</text>
</view> </view>
</view> </view>
<view class="top-list"> <view class="top-list">
<view class="left"> <view class="left">
<img src="/static/my/changeBindPhone.png" /> <img src="/static/my/changeBindPhone.png" />
<text class="label">+86</text> <text class="label">+86</text>
<input type="number" placeholder="请输入您的换绑手机号" class="input" />
<input type="number" v-model="userPhone" placeholder="请输入您的换绑手机号" class="input" />
</view> </view>
<view class="right"> <view class="right">
<button class="verification" :class="{ 'disabled': gettingCode }" @click="getVerification"
<button class="verification" :class="{ 'disabled': gettingCode }" @click="getCode"
:disabled="gettingCode"> :disabled="gettingCode">
{{ gettingCode ? `重新发送 ${time}s` : '获取验证码' }} {{ gettingCode ? `重新发送 ${time}s` : '获取验证码' }}
</button> </button>
@ -35,7 +34,7 @@
</view> </view>
<view class="bottom"> <view class="bottom">
<button class="change-btn">换绑</button>
<button class="change-btn" @click="changeAccount">换绑</button>
</view> </view>
</view> </view>
</template> </template>
@ -45,12 +44,34 @@
ref, ref,
onMounted onMounted
} from 'vue' } from 'vue'
import {
sendPhone,
changeBind
} from "@/api/setting/password"
import {
getUserInfo
} from "@/api/member"
const iSMT = ref(0) const iSMT = ref(0)
const phone = ref('15105421566')
const phone = ref('')
const gettingCode = ref(false) const gettingCode = ref(false)
const time = ref(60) const time = ref(60)
const userPhone = ref('')
const userInfoPromise = getUserInfo()
userInfoPromise.then(res => {
if (res.code === 200) {
console.log('个人信息', res.data)
phone.value = res.data.phone
} else {
uni.showToast({
title: '用户信息请求失败',
icon: 'none',
})
}
})
const getVerification = () => {
const getCode = () => {
if (gettingCode.value) return if (gettingCode.value) return
gettingCode.value = true gettingCode.value = true
@ -63,6 +84,27 @@
gettingCode.value = false gettingCode.value = false
} }
}, 1000) }, 1000)
sendPhone({
phone: userPhone.value
})
}
const changeAccount = () => {
const res = changeBind({
verificateType: 1,
account: userPhone.value
})
if(res.code === 200){
uni.showToast({
title: '绑定成功',
icon: 'none',
})
}else {
uni.showToast({
title: '用户绑定失败',
icon: 'none',
})
}
} }
onMounted(() => { onMounted(() => {

50
pages/setting/push.vue

@ -3,25 +3,35 @@
<view :style="{height:iSMT+'px'}"></view> <view :style="{height:iSMT+'px'}"></view>
<view class="top"> <view class="top">
<view class="top-list"> <view class="top-list">
<text style="width:180rpx;">公共消息</text>
<text class="public">重大咨询财经要闻等系统提醒</text>
<switch class="arrow switch-btn" />
<text class="label">公共消息</text>
<view class="right">
<text class="public">重大咨询财经要闻等系统提醒</text>
<switch class="switch-btn" />
</view>
</view> </view>
<view class="top-list"> <view class="top-list">
<text>字体大小</text>
<switch class="arrow switch-btn" />
<text class="label">指标消息提醒</text>
<view class="right">
<text class="public">所有指标消息的提醒</text>
<switch class="switch-btn" />
</view>
</view> </view>
</view> </view>
<view class="bottom"> <view class="bottom">
<view class="bottom-list"> <view class="bottom-list">
<text>盯盘预警</text>
<uni-icons type="arrowright" size="16" class="arrow" />
<text class="label">盯盘预警</text>
<view class="right">
<text class="public">自选股预警和个性化预警设置</text>
<uni-icons type="arrowright" size="16" />
</view>
</view> </view>
<view class="bottom-list"> <view class="bottom-list">
<text>订阅服务</text>
<text class="cache">45.5M</text>
<uni-icons type="arrowright" size="16" class="arrow" />
<text class="label">订阅服务</text>
<view class="right">
<text class="public">订阅你感兴趣的专题服务</text>
<uni-icons type="arrowright" size="16" />
</view>
</view> </view>
</view> </view>
</view> </view>
@ -53,7 +63,6 @@
height: 7vh; height: 7vh;
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center;
margin: 0 40rpx; margin: 0 40rpx;
padding: 0 10rpx; padding: 0 10rpx;
border-bottom: 1rpx solid #eee; border-bottom: 1rpx solid #eee;
@ -63,25 +72,24 @@
border-bottom: none; border-bottom: none;
} }
.right {
display: flex;
align-items: center;
gap: 10rpx;
}
.switch-btn { .switch-btn {
width: 100rpx;
transform: scale(0.6); transform: scale(0.6);
transform-origin: center right; transform-origin: center right;
} }
.public { .public {
width: 450rpx;
margin-left: auto;
font-size: 10px; font-size: 10px;
color: rgb(203, 203, 203); color: rgb(203, 203, 203);
} }
.arrow {
margin-left: auto;
}
.bottom { .bottom {
height: 13.5vh;
height: 14vh;
background-color: white; background-color: white;
margin-top: 1vh; margin-top: 1vh;
} }
@ -105,4 +113,8 @@
.bottom-list:last-child { .bottom-list:last-child {
border-bottom: none; border-bottom: none;
} }
.label {
flex: 1;
}
</style> </style>

23
pages/setting/server.vue

@ -26,9 +26,31 @@
ref, ref,
onMounted onMounted
} from 'vue' } from 'vue'
import {
getSetting
} from "@/api/setting/general"
const iSMT = ref(0) const iSMT = ref(0)
const selectedIndex = ref(0) const selectedIndex = ref(0)
const getServer = async () => {
try {
const res = await getSetting()
if (res.code === 200) {
const fontSize = res.data.fontSize
const sizeMap = {
'auto': 0,
'singapore': 1,
'hongkong': 2
}
console.log('看看服务器', res.data.fontSize)
selectedIndex.value = sizeMap[fontSize] ?? 0;
}
} catch (err) {
console.error("获取服务器设置失败:", err);
}
}
const selectFont = (index) => { const selectFont = (index) => {
selectedIndex.value = index selectedIndex.value = index
console.log('看看选中状态',selectedIndex.value) console.log('看看选中状态',selectedIndex.value)
@ -38,6 +60,7 @@
// //
iSMT.value = uni.getSystemInfoSync().statusBarHeight; iSMT.value = uni.getSystemInfoSync().statusBarHeight;
console.log('看看高度', iSMT.value) console.log('看看高度', iSMT.value)
getServer()
}) })
</script> </script>

21
pages/setting/theme.vue

@ -21,8 +21,28 @@
ref, ref,
onMounted onMounted
} from 'vue' } from 'vue'
import {
getSetting
} from "@/api/setting/general"
const iSMT = ref(0) const iSMT = ref(0)
const selectedIndex = ref(0) const selectedIndex = ref(0)
const getTheme = async () => {
try {
const res = await getSetting()
if (res.code === 200) {
const theme = res.data.theme
const sizeMap = {
'light': 0,
'dark': 1
}
console.log('看看主题', res.data.theme)
selectedIndex.value = sizeMap[theme] ?? 0;
}
} catch (err) {
console.error("获取主题设置失败:", err);
}
}
const selectFont = (index) => { const selectFont = (index) => {
selectedIndex.value = index selectedIndex.value = index
@ -32,6 +52,7 @@
// //
iSMT.value = uni.getSystemInfoSync().statusBarHeight; iSMT.value = uni.getSystemInfoSync().statusBarHeight;
console.log('看看高度', iSMT.value) console.log('看看高度', iSMT.value)
getTheme()
}) })
</script> </script>

39
utils/http.js

@ -1,7 +1,7 @@
import { useUserStore } from "../stores/modules/userInfo" import { useUserStore } from "../stores/modules/userInfo"
import { useDeviceStore } from "../stores/modules/deviceInfo"
const baseURL = "https://dbqb.nfdxy.net/testApi"
// const baseURL = "https://hwjb.homilychart.com/testApi"
const baseURL = "http://192.168.40.8:9000"
const httpInterceptor = { const httpInterceptor = {
@ -22,31 +22,30 @@ const httpInterceptor = {
// 打印最终请求地址 // 打印最终请求地址
console.log('HTTP(finalUrl)=', options.url) console.log('HTTP(finalUrl)=', options.url)
// 2.请求超时,默认60s // 2.请求超时,默认60s
options.timeout = 10000
options.timeout = 60000
console.log(options) console.log(options)
//3 添加小程序端请求头 //3 添加小程序端请求头
const sys = uni.getSystemInfoSync(); const sys = uni.getSystemInfoSync();
// 为对齐后端文档示例,client 固定为 ios(如需按平台设置再改回) // 为对齐后端文档示例,client 固定为 ios(如需按平台设置再改回)
const deviceInfo =useDeviceStore()
const client = 'ios';
options.header = { options.header = {
...options.header, ...options.header,
'source-client': 'miniapp',
// 标准头与文档头同时设置,确保兼容 // 标准头与文档头同时设置,确保兼容
'content-type': 'application/json', 'content-type': 'application/json',
'contentType': 'application/json',
'version': uni.getSystemInfoSync().appVersion,
'client': uni.getSystemInfoSync().platform == 'ios' ? 'ios' : 'android',
'deviceId': deviceInfo.deviceInfo.deviceId
// 'contentType': 'application/json',
'version': '1',
'client': client,
'deviceId':'1'
} }
//4 添加token,优先用store,没有则回退到body中的token,保持与Apifox一致 //4 添加token,优先用store,没有则回退到body中的token,保持与Apifox一致
const memberStore = useUserStore() const memberStore = useUserStore()
const token = memberStore.userInfo?.token || options.data?.token
// const token = '1b3a58424c5324e40d4bf4d085e18047'
if (token) {
options.header.token = token
}
// const token = memberStore.userInfo?.token || options.data?.token
options.header.token = '9cd87893b9282b6a7a6cc9b780c905db'
const token = '9cd87893b9282b6a7a6cc9b780c905db'
if (token) {
options.header.token = token
}
// 避免误用 Authorization 头,后端要求的是 token 头 // 避免误用 Authorization 头,后端要求的是 token 头
// if (options.header.Authorization) delete options.header.Authorization // if (options.header.Authorization) delete options.header.Authorization
return options return options
@ -63,12 +62,6 @@ export const http = (options) => {
// 1.请求成功 // 1.请求成功
success: (result) => { success: (result) => {
if (result.statusCode >= 200 && result.statusCode < 300) { if (result.statusCode >= 200 && result.statusCode < 300) {
if (result.data.code === 401) {
uni.showToast({
title: '请先登录',
icon: 'none'
})
}
resolve(result.data) resolve(result.data)
} else if (result.statusCode === 401) { } else if (result.statusCode === 401) {
// 清除登录信息 // 清除登录信息
@ -91,7 +84,7 @@ export const http = (options) => {
fail: (err) => { fail: (err) => {
reject(err) reject(err)
uni.showToast({ uni.showToast({
title: '请求超时',
title: '网络错误',
icon: 'none' icon: 'none'
}) })
} }

16
vue.config.js

@ -1,14 +1,24 @@
module.exports = { module.exports = {
devServer: { devServer: {
proxy: {
/* proxy: {
'/api': { // 你的目标服务器的请求路径前缀 '/api': { // 你的目标服务器的请求路径前缀
target: 'https://hwjb.homilychart.com', // 目标服务器的地址 target: 'https://hwjb.homilychart.com', // 目标服务器的地址
changeOrigin: true, // 是否跨域 changeOrigin: true, // 是否跨域
secure: false, // 如果是https接口,需要配置这个参数 secure: false, // 如果是https接口,需要配置这个参数
pathRewrite: { pathRewrite: {
'^/': '/testApi' // 将 /api 替换为 /testApi,以便正确请求目标服务器的资源
'^/api': '' // 将 /api 替换为 /testApi,以便正确请求目标服务器的资源
} }
} }
}
} */
proxy: {
'/api': { // 你的目标服务器的请求路径前缀
target: 'http://192.168.40.8:9000', // 目标服务器的地址
changeOrigin: true, // 是否跨域
secure: false, // 如果是https接口,需要配置这个参数
pathRewrite: {
'^/api': '' // 将 /api 替换为 /testApi,以便正确请求目标服务器的资源
}
}
}
} }
} }
Loading…
Cancel
Save