更新web端

This commit is contained in:
全栈小学生 2023-05-20 18:05:21 +08:00
parent fa37c55a5d
commit e2537e99b0
19 changed files with 8909 additions and 34918 deletions

1
web/.gitignore vendored
View File

@ -1,5 +1,4 @@
node_modules node_modules
*.log*
.nuxt .nuxt
.nitro .nitro
.cache .cache

View File

@ -5,27 +5,27 @@ export function getMemberInfo() {
/** /**
* *
*/ */
export function updateMember(data : AnyObject) { export function modifyMember(data: AnyObject) {
return request.put(`member/modify/${data.field}`, data, { showErrorMessage: true }) return request.put(`member/modify/${data.field}`, data, { showErrorMessage: true })
} }
/** /**
* *
*/ */
export function getPointList(data : AnyObject) { export function getPointList(data: AnyObject) {
return request.get('member/account/point', data) return request.get('member/account/point', data)
} }
/** /**
* *
*/ */
export function getBalanceList(data : AnyObject) { export function getBalanceList(data: AnyObject) {
return request.get('member/account/balance', data) return request.get('member/account/balance', data)
} }
/** /**
* *
*/ */
export function bindMobile(data : AnyObject) { export function bindMobile(data: AnyObject) {
return request.put('member/mobile', data, { showErrorMessage: true }) return request.put('member/mobile', data, { showErrorMessage: true })
} }

View File

@ -47,13 +47,6 @@ export function getWechatSkdConfig(data: AnyObject) {
return request.get('wechat/jssdkconfig', data) return request.get('wechat/jssdkconfig', data)
} }
/**
*
*/
export function uploadImage(data: AnyObject) {
return request.upload('file/image', data, { showErrorMessage: true })
}
/** /**
* *
*/ */

View File

@ -18,6 +18,12 @@ import useMemberStore from '@/stores/member'
// //
import '@/assets/styles/index.scss' import '@/assets/styles/index.scss'
if (process.client) {
const match = location.href.match(/\/s(\d*)\//)
const cookie = useCookie('siteId')
match ? cookie.value = match[1] : cookie.value = null
}
// //
const systemStore = useSystemStore() const systemStore = useSystemStore()
const locale = computed(() => (systemStore.lang === 'zh-cn' ? zhCn : en)) const locale = computed(() => (systemStore.lang === 'zh-cn' ? zhCn : en))
@ -37,8 +43,10 @@ watch(route, (nval, oval) => {
// title // title
let path = route.path == '/' ? '/index' : route.path let path = route.path == '/' ? '/index' : route.path
// url /
if (path.slice(-1) == '/') path = path.slice(0, -1)
path = !path.lastIndexOf('/') ? `${path}/index` : path path = !path.lastIndexOf('/') ? `${path}/index` : path
const key = path.replace('/', '').replaceAll('/', '.') let key = path.replace('/', '').replaceAll('/', '.')
setTimeout(() => { setTimeout(() => {
useHead({ useHead({

Binary file not shown.

Before

Width:  |  Height:  |  Size: 228 KiB

After

Width:  |  Height:  |  Size: 268 KiB

View File

@ -73,6 +73,7 @@ captcha.refresh()
const sendSms = useSendSms() const sendSms = useSendSms()
const send = () => { const send = () => {
formData.mobile = prop.mobile
if (sendSms.canGetCode.value) { if (sendSms.canGetCode.value) {
captchaDialog.value = true captchaDialog.value = true
} }
@ -87,8 +88,10 @@ const confirm = async () => {
if (sendRes) { if (sendRes) {
value.value = sendRes value.value = sendRes
captchaDialog.value = false captchaDialog.value = false
loading.value = false
} else if (sendRes === false) { } else if (sendRes === false) {
captcha.refresh() captcha.refresh()
loading.value = false
} }
} }
}) })

View File

@ -2,7 +2,9 @@ import useAppStore from '~/stores/app'
export function t(message: string) { export function t(message: string) {
const i18n = useNuxtApp().$getI18n() const i18n = useNuxtApp().$getI18n()
const path = useAppStore().route let path = useAppStore().route
// 处理部署后不知道为什么url会自动拼接上 / 的问题
if (path != '/' && path.slice(-1) == '/') path = path.slice(0, -1)
const file = path == '/' ? 'index' : path.replace('/', '').replaceAll('/', '.') const file = path == '/' ? 'index' : path.replace('/', '').replaceAll('/', '.')
const key = `${file}.${message}` const key = `${file}.${message}`
return i18n.global.t(key) != key ? i18n.global.t(key) : i18n.global.t(message) return i18n.global.t(key) != key ? i18n.global.t(key) : i18n.global.t(message)

View File

@ -0,0 +1,3 @@
{
"title": "文章"
}

View File

@ -0,0 +1,3 @@
{
"title": "文章"
}

View File

@ -0,0 +1,13 @@
{
"logining": "登录中",
"usernamePlaceholder": "请输入账号",
"passwordPlaceholder": "请输入密码",
"resetpwd": "忘记密码",
"noAccount": "还没有账号",
"toRegister": "去注册",
"and": "和",
"agreeTips": "登录代表您同意",
"usernameLogin": "密码登录",
"mobileLogin": "验证码登录",
"mobilePlaceholder": "请输入手机号"
}

View File

@ -11,6 +11,10 @@
"member": { "member": {
"index": "欢迎页", "index": "欢迎页",
"center": "个人中心" "center": "个人中心"
} },
"article": {
"list": "文章",
"detail": "文章"
}
} }
} }

View File

@ -1,13 +1,13 @@
<template> <template>
<!-- main-container --> <!-- main-container -->
<div class="flex h-full min-w-[1200px]"> <div class="flex h-full min-w-[1200px]">
<div class="flex items-center ml-[20px]"> <div class="flex items-center ml-[20px]">
<NuxtLink to="/"> <NuxtLink to="/">
<div class="w-[132px] mr-[10px]"><img src="@/assets/images/index/logo.jpg" /></div> <div class="w-[132px] mr-[10px]"><img src="@/assets/images/index/logo.jpg" /></div>
</NuxtLink> </NuxtLink>
<div class="hidden text-[14px] text-[#A6B0C8] xl:block">|<span class="ml-[10px]">一款快速开发SAAS通用管理系统后台框架</span> <div class="hidden text-[14px] text-[#A6B0C8] xl:block">|<span class="ml-[10px]">一款快速开发SAAS通用管理系统后台框架</span>
</div> </div>
</div> </div>
<div class="mx-auto flex-shrink"> <div class="mx-auto flex-shrink">
<el-menu :default-active="appStore.route" class="h-full" mode="horizontal" :ellipsis="false" :router="true"> <el-menu :default-active="appStore.route" class="h-full" mode="horizontal" :ellipsis="false" :router="true">
@ -15,11 +15,11 @@
<span class="text-base mx-4">首页</span> <span class="text-base mx-4">首页</span>
<span></span> <span></span>
</el-menu-item> </el-menu-item>
<el-menu-item index="/community/answer" route="/"> <el-menu-item index="/article/list" route="/article/list">
<span class="text-base mx-4">文章</span> <span class="text-base mx-4">文章</span>
<span></span> <span></span>
</el-menu-item> </el-menu-item>
<el-menu-item route="/"> <el-menu-item route="/">
<span class="text-base mx-4">社区</span> <span class="text-base mx-4">社区</span>
<span></span> <span></span>
</el-menu-item> </el-menu-item>
@ -27,15 +27,13 @@
</div> </div>
<div class="flex items-center justify-end mr-[20px] ml-auto whitespace-pre"> <div class="flex items-center justify-end mr-[20px] ml-auto whitespace-pre">
<el-dropdown v-if="info"> <div v-if="info">
<div> <NuxtLink to="/member/center">
<NuxtLink to="/member/center"> <span class="cursor-pointer">{{ info.nickname }}</span>
<span class="cursor-pointer">{{info.nickname}}</span> </NuxtLink>
</NuxtLink> <span class="mx-2">|</span>
<span class="mx-2">|</span> <span class="cursor-pointer" @click="logoutFn">退出</span>
<span class="cursor-pointer" @click="logoutFn">退出</span> </div>
</div>
</el-dropdown>
<NuxtLink to="/auth/login" v-else> <NuxtLink to="/auth/login" v-else>
<el-button type="primary" link>{{ t('login') }} / {{ t('register') }}</el-button> <el-button type="primary" link>{{ t('login') }} / {{ t('register') }}</el-button>
</NuxtLink> </NuxtLink>
@ -50,7 +48,7 @@ import useAppStore from '@/stores/app'
const memberStore = useMemberStore() const memberStore = useMemberStore()
const info = computed(() => memberStore.info) const info = computed(() => memberStore.info)
const logoutFn = ()=>{ const logoutFn = () => {
memberStore.logout() memberStore.logout()
navigateTo(`/auth/login`) navigateTo(`/auth/login`)
} }
@ -62,23 +60,27 @@ const appStore = useAppStore()
:deep(.el-menu--horizontal) { :deep(.el-menu--horizontal) {
border-bottom: none; border-bottom: none;
} }
.el-menu-item{
.el-menu-item {
padding-left: 0; padding-left: 0;
border: none !important; border: none !important;
color: #000 !important; color: #000 !important;
&.is-active{
&.is-active {
border: none !important; border: none !important;
color: #000 !important; color: #000 !important;
span{
&:first-of-type{ span {
&:first-of-type {
position: relative; position: relative;
z-index: 1; z-index: 1;
} }
&:last-of-type{
&:last-of-type {
position: absolute; position: absolute;
width: 16px; width: 16px;
height: 16px; height: 16px;
background-image: linear-gradient(to bottom right,#FFFFFF,var(--el-color-primary)); background-image: linear-gradient(to bottom right, #FFFFFF, var(--el-color-primary));
border-radius: 100px; border-radius: 100px;
bottom: 15px; bottom: 15px;
right: 27px; right: 27px;
@ -86,11 +88,13 @@ const appStore = useAppStore()
} }
} }
} }
&:hover{
&:hover {
background-color: transparent !important; background-color: transparent !important;
color: var(--el-menu-hover-text-color) !important; color: var(--el-menu-hover-text-color) !important;
} }
&:focus{
&:focus {
background-color: transparent !important; background-color: transparent !important;
} }
} }

43336
web/package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,27 +1,27 @@
{ {
"name": "web",
"name": "web", "private": true,
"private": true, "version": "1.0.0",
"version": "1.0.0", "scripts": {
"scripts": { "build": "nuxt build --mode product",
"build": "nuxt build --mode product", "dev": "nuxt dev --mode dev",
"dev": "nuxt dev --mode dev", "generate": "nuxt generate --mode product",
"generate": "nuxt generate --mode product", "preview": "nuxt preview --mode product",
"preview": "nuxt preview --mode product", "postinstall": "nuxt prepare --mode product"
"postinstall": "nuxt prepare --mode product" },
}, "devDependencies": {
"devDependencies": { "@element-plus/nuxt": "^1.0.4",
"@element-plus/nuxt": "^1.0.4", "@types/qrcode": "^1.5.0",
"nuxt": "^3.3.2", "nuxt": "^3.4.1",
"nuxt-windicss": "^2.6.0", "nuxt-windicss": "^2.6.0",
"sass": "^1.60.0", "sass": "^1.60.0",
"vue-i18n": "^9.2.2", "vue-i18n": "^9.2.2"
"@types/qrcode": "^1.5.0" },
}, "dependencies": {
"dependencies": { "@vueuse/core": "^9.13.0",
"@vueuse/core": "^9.13.0", "element-plus": "^2.3.2",
"element-plus": "^2.3.2", "pinia": "^2.0.33",
"pinia": "^2.0.33", "qrcode": "^1.5.1",
"qrcode": "^1.5.1" "sass": "^1.60.0"
} }
} }

View File

@ -0,0 +1,80 @@
<template>
<div class="w-full min-h-[100%] main-container pt-5">
<div class="mt-[20px] mb-[50px]" v-if="articleDeatail">
<el-breadcrumb :separator-icon="ArrowRight">
<el-breadcrumb-item :to="{ path: '/' }">首页</el-breadcrumb-item>
<el-breadcrumb-item :to="{ path: '/article/list' }">文章</el-breadcrumb-item>
<el-breadcrumb-item >{{ articleDeatail.category_name }}</el-breadcrumb-item>
</el-breadcrumb>
<div >
<p class="py-[20px] text-center text-[24px]">{{ articleDeatail.title }}</p>
<div class="flex justify-center">
<!-- <div class="mr-3 flex items-center text-gray-500 text-sm text-[#999]"><el-icon><View /></el-icon> <span class="ml-1">浏览量158</span></div> -->
<div class="mr-3 flex items-center text-gray-500 text-sm text-[#999]"><el-icon><Clock /></el-icon><span class="ml-1">时间{{ articleDeatail.create_time }}</span></div>
</div>
<div class="mt-[50px]" v-html="articleDeatail.content"></div>
</div>
</div>
</div>
</template>
<script lang="ts" setup>
import { ref, reactive, computed } from 'vue'
import { getArticleDetail } from '@/api/article'
import { ArrowRight } from '@element-plus/icons-vue'
import { nMounted } from 'vue';
import { useRoute } from 'vue-router';
const Route = useRoute(); //
const articleDeatail = ref();
onMounted(() => {
obtainArricleInfo(Route.query.id)
});
const obtainArricleInfo = (id) => {
getArticleDetail(id).then(res => {
console.log(res)
articleDeatail.value = res.data;
})
}
</script>
<style lang="scss" scoped>
.index-carousel {
background-image: url('@/assets/images/index_carousel.png');
background-position: center center;
background-repeat: no-repeat;
background-size: cover;
}
.article-wrap{
span{
line-height: 1;
box-shadow: 0 0 5px var(--el-color-primary-light-7);
&.active{
background-image: linear-gradient(to right,var(--el-color-primary-light-5), var(--el-color-primary));
}
&:hover{
background-image: linear-gradient(to right,var(--el-color-primary-light-5), var(--el-color-primary));
color: #fff;
}
}
}
.tow-line-overflow{
overflow: hidden;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
}
.text-color{
color: var(--el-color-primary);
}
// .demo-tabs .el-ta
.custom-tabs-label span{
font-size: 20px;
padding: 0px 10px;
}
</style>

172
web/pages/article/list.vue Normal file
View File

@ -0,0 +1,172 @@
<template>
<div class="w-full main-container pt-5">
<el-carousel height="350px" indicator-position="none" arrow="never">
<el-carousel-item>
<div class="h-full index-carousel"></div>
</el-carousel-item>
</el-carousel>
<div class="mt-[20px] mb-[50px]">
<div>
<div class="w-full">
<el-breadcrumb :separator-icon="ArrowRight">
<el-breadcrumb-item :to="{ path: '/' }">首页</el-breadcrumb-item>
<el-breadcrumb-item :to="{ path: '/article/list' }">文章</el-breadcrumb-item>
<el-breadcrumb-item v-if="selectedCategoryName">{{ selectedCategoryName }}</el-breadcrumb-item>
</el-breadcrumb>
<div class="flex mt-[20px] items-start">
<div class="w-[50px]">类目</div>
<el-row>
<el-button class="mb-[10px]" @click="selectedCategory(categoryItem)" v-for="(categoryItem, categoryIndex) in activeCategotyLsit" :key="categoryIndex">{{ categoryItem.name }}</el-button>
</el-row>
</div>
<div class="article-list mb-[20px] cursor-pointer" v-for="(activeItem, activeIndex) in articleTableData.data" :key="activeIndex" @click="toLink(activeItem.id)">
<div class="flex justify-between relative py-[20px] border-b-1 border-gray-300 border-solid">
<div class="w-[150px] h-[150px] flex items-center">
<img :src="img(activeItem.image)"/>
</div>
<div class="w-[1030px]">
<p class="text-xl font-bold">{{ activeItem.title }}</p>
<span class="overflow-ellipsis mt-2 mb-2 tow-line-overflow text-gray-500">{{ activeItem.intro }}</span>
</div>
<!-- <div class="activeBo flex items-right mt-2 justify-end absolute">
<span class="mr-5 text-sm text-gray-500">{{ activeItem.create_time }}</span>
<div class="mr-3 flex items-center text-gray-500 text-sm"><el-icon><View /></el-icon> <span class="ml-1">158</span></div>
<div class="mr-3 flex items-center text-gray-500 text-sm"><el-icon><Pointer /></el-icon> <span class="ml-1">22</span></div>
<div class="mr-3 flex items-center text-gray-500 text-sm"><el-icon><Star /></el-icon> <span class="ml-1">55</span></div>
<div class="flex items-center text-gray-500 text-sm"><el-icon><ChatDotRound /></el-icon> <span class="ml-1">655</span></div>
</div> -->
</div>
</div>
<el-pagination
class="justify-center"
@current-change="handleCurrentChange"
@size-change="handleSizeChange"
:page-size="articleTableData.limit"
background
layout="prev, pager, next"
:total="articleTableData.total"
/>
</div>
</div>
</div>
</div>
</template>
<script lang="ts" setup>
import { ref, reactive, computed } from 'vue'
import { bind } from '@/api/auth'
import { bindMobile } from '@/api/member'
import useMemberStore from '@/stores/member'
import { getArticleCategory,getArticleList } from '@/api/article'
import { FormInstance } from 'element-plus'
import { ArrowRight } from '@element-plus/icons-vue'
import type { TabsPaneContext } from 'element-plus'
import { useRouter } from 'vue-router';
const router = useRouter();
const activeCategotyLsit = ref([])
const selectedCategoryName = ref()
const articleTableData = reactive({
page: 1,
limit: 10,
total: 0,
loading: true,
data: [],
searchParam: {
title: '',
category_id:''
}
})
const handleClick = (tab: TabsPaneContext, event: Event) => {
console.log(tab, event)
}
/**
* 获取文章列表
*/
const loadArticleList = (page: number = 1) => {
articleTableData.loading = true
articleTableData.page = page
getArticleList({
page: articleTableData.page,
limit: articleTableData.limit,
...articleTableData.searchParam
}).then(res => {
articleTableData.loading = false
articleTableData.data = res.data.data
articleTableData.total = res.data.total
}).catch(() => {
articleTableData.loading = false
})
}
loadArticleList()
const checkArticleCategory = () => {
getArticleCategory().then(res => {
activeCategotyLsit.value = res.data.data;
})
}
checkArticleCategory()
const selectedCategory = (item) => {
articleTableData.searchParam.category_id = item.category_id;
selectedCategoryName.value = item.name
}
const handleSizeChange = (val: number) => {
loadArticleList(val)
}
const handleCurrentChange = (val: number) => {
loadArticleList(val)
}
const toLink = (id) => {
router.push(`/article/detail?id=${id}`)
}
</script>
<style lang="scss" scoped>
.index-carousel {
background-image: url('@/assets/images/index_carousel.png');
background-position: center center;
background-repeat: no-repeat;
background-size: cover;
}
.article-wrap{
span{
line-height: 1;
box-shadow: 0 0 5px var(--el-color-primary-light-7);
&.active{
background-image: linear-gradient(to right,var(--el-color-primary-light-5), var(--el-color-primary));
}
&:hover{
background-image: linear-gradient(to right,var(--el-color-primary-light-5), var(--el-color-primary));
color: #fff;
}
}
}
.tow-line-overflow{
overflow: hidden;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
}
.text-color{
color: var(--el-color-primary);
}
// .demo-tabs .el-ta
.custom-tabs-label span{
font-size: 20px;
padding: 0px 10px;
}
.activeBo {
bottom : 20px;
right : 0px
}
</style>

View File

@ -194,9 +194,6 @@ const formRules = computed(() => {
} }
} }
}) })
console.log(
"memberStore.setToken", memberStore
)
const handleLogin = async () => { const handleLogin = async () => {
await formRef.value?.validate(async (valid, fields) => { await formRef.value?.validate(async (valid, fields) => {

View File

@ -5,28 +5,26 @@
<el-card class="box-card flex-1 ml-4" v-loading="loading" shadow="never"> <el-card class="box-card flex-1 ml-4" v-loading="loading" shadow="never">
<template #header> <template #header>
<div class="card-header"> <div class="card-header">
<span>{{t('personageInfo')}}</span> <span>{{ t('personageInfo') }}</span>
</div> </div>
</template> </template>
<div class="pr-15" v-if="info"> <div class="pr-15" v-if="info">
<el-form :model="info" class="form-wrap" label-width="120px"> <el-form :model="info" class="form-wrap" label-width="120px">
<el-form-item :label="t('memberHeadimg')"> <el-form-item :label="t('memberHeadimg')">
<div class="w-full flex justify-between content-center items-center"> <div class="w-full flex justify-between content-center items-center">
<img v-if="!info.headimg" class="w-[80px] h-[80px]" src="@/assets/images/default_headimg.png" alt=""> <img v-if="!info.headimg" class="w-[80px] h-[80px]"
src="@/assets/images/default_headimg.png" alt="">
<img v-else :src="img(info.headimg)" class="w-[80px] h-[80px]" alt=""> <img v-else :src="img(info.headimg)" class="w-[80px] h-[80px]" alt="">
<el-upload <el-upload class="avatar-uploader" :show-file-list="false" v-bind="upload">
class="avatar-uploader" <span class="cursor-pointer text-color">{{ t('edit') }}</span>
:show-file-list="false"
v-bind="upload"
>
<span class="cursor-pointer text-color">{{t('edit')}}</span>
</el-upload> </el-upload>
</div> </div>
</el-form-item> </el-form-item>
<el-form-item :label="t('nickname')"> <el-form-item :label="t('nickname')">
<div class="w-full flex justify-between content-center"> <div class="w-full flex justify-between content-center">
<span>{{updateNickname.value}}</span> <span>{{ updateNickname.value }}</span>
<span class="cursor-pointer text-color" @click="updateNickname.modal = true">{{t('edit')}}</span> <span class="cursor-pointer text-color" @click="updateNickname.modal = true">{{ t('edit')
}}</span>
</div> </div>
</el-form-item> </el-form-item>
</el-form> </el-form>
@ -41,8 +39,8 @@
</el-form> </el-form>
<template #footer> <template #footer>
<span class="dialog-footer"> <span class="dialog-footer">
<el-button @click="updateNickname.modal = false">{{t('cancel')}}</el-button> <el-button @click="updateNickname.modal = false">{{ t('cancel') }}</el-button>
<el-button type="primary" @click="updateNicknameConfirm">{{t('confirm')}}</el-button> <el-button type="primary" @click="updateNicknameConfirm">{{ t('confirm') }}</el-button>
</span> </span>
</template> </template>
</el-dialog> </el-dialog>
@ -54,9 +52,7 @@
import { reactive, ref, computed } from 'vue' import { reactive, ref, computed } from 'vue'
import useMemberStore from '@/stores/member' import useMemberStore from '@/stores/member'
import useAppStore from '@/stores/app' import useAppStore from '@/stores/app'
import { updateMember } from '@/api/member' import { modifyMember } from '@/api/member'
import { uploadImage } from '@/api/system'
import type { UploadProps } from 'element-plus'
import { ElMessage, UploadFile, UploadFiles } from 'element-plus' import { ElMessage, UploadFile, UploadFiles } from 'element-plus'
import request from '@/utils/request' import request from '@/utils/request'
import storage from '@/utils/storage' import storage from '@/utils/storage'
@ -72,9 +68,9 @@ const updateNickname = reactive({
value: '' value: ''
}) })
const info = computed(() =>{ const info = computed(() => {
updateNickname.value = memberStore.info?.nickname; updateNickname.value = memberStore.info?.nickname;
if(memberStore.info) loading.value = false; if (memberStore.info) loading.value = false;
return memberStore.info; return memberStore.info;
}) })
const appStore = useAppStore() const appStore = useAppStore()
@ -89,13 +85,14 @@ const upload = computed(() => {
limit: 1, limit: 1,
headers, headers,
onSuccess: (response: any, uploadFile: UploadFile, uploadFiles: UploadFiles) => { onSuccess: (response: any, uploadFile: UploadFile, uploadFiles: UploadFiles) => {
console.log('uploadFile',);
let img = uploadFile?.response?.data?.url; let img = uploadFile?.response?.data?.url;
if (response.code == 200) { if (response.code == 200) {
updateMember({ modifyMember({
field: 'headimg', field: 'headimg',
value: img value: img
}).then(() => { }).then(() => {
info.headimg = img memberStore.info.headimg = img
}) })
} else { } else {
uploadFile.status = 'fail' uploadFile.status = 'fail'
@ -107,22 +104,23 @@ const upload = computed(() => {
// //
const updateNicknameConfirm = () => { const updateNicknameConfirm = () => {
if (!updateNickname.value) { ElMessage.error('会员昵称不能为空'); return } if (!updateNickname.value) { ElMessage.error('会员昵称不能为空'); return }
updateMember({ modifyMember({
field: 'nickname', field: 'nickname',
value: updateNickname.value value: updateNickname.value
}).then(res => { }).then(res => {
updateNickname.modal = false updateNickname.modal = false
}) })
} }
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.box-card{ .box-card {
border: none !important; border: none !important;
} }
::v-deep .form-wrap .el-form-item{
::v-deep .form-wrap .el-form-item {
align-items: center; align-items: center;
} }
</style> </style>

View File

@ -14,14 +14,16 @@ interface FetchOptions {
onRequest?: (data: any) => void, onRequest?: (data: any) => void,
onResponse?: (data: any) => void, onResponse?: (data: any) => void,
onResponseError?: (data: any) => void, onResponseError?: (data: any) => void,
showMessageConfig?: ShowMessageConfig showMessageConfig?: ShowMessageConfig,
watch: boolean
} }
class Http { class Http {
private options: FetchOptions = { private options: FetchOptions = {
baseURL: '', baseURL: '',
method: '', method: '',
headers: {} headers: {},
watch: false
} }
public constructor() { public constructor() {
@ -32,7 +34,7 @@ class Http {
const runtimeConfig = useRuntimeConfig() const runtimeConfig = useRuntimeConfig()
this.options.baseURL = runtimeConfig.public.VITE_APP_BASE_URL || `${location.origin}/api/` this.options.baseURL = runtimeConfig.public.VITE_APP_BASE_URL || `${location.origin}/api/`
this.options.headers[runtimeConfig.public.VITE_REQUEST_HEADER_SITEID_KEY] = runtimeConfig.public.VITE_SITE_ID this.options.headers[runtimeConfig.public.VITE_REQUEST_HEADER_SITEID_KEY] = useCookie('siteId').value || runtimeConfig.public.VITE_SITE_ID
this.options.headers[runtimeConfig.public.VITE_REQUEST_HEADER_CHANNEL_KEY] = 'pc' this.options.headers[runtimeConfig.public.VITE_REQUEST_HEADER_CHANNEL_KEY] = 'pc'
if (getToken()) this.options.headers[runtimeConfig.public.VITE_REQUEST_HEADER_TOKEN_KEY] = getToken() if (getToken()) this.options.headers[runtimeConfig.public.VITE_REQUEST_HEADER_TOKEN_KEY] = getToken()
@ -46,7 +48,7 @@ class Http {
this.options.onResponse = ({ response, options }) => { this.options.onResponse = ({ response, options }) => {
const { _data: data } = response const { _data: data } = response
if (data.code == 200) { if (data.code == 1) {
if (options.showMessageConfig.showSuccessMessage) ElMessage({ message: data.msg, type: 'success' }) if (options.showMessageConfig.showSuccessMessage) ElMessage({ message: data.msg, type: 'success' })
} else { } else {
if (options.showMessageConfig.showErrorMessage) ElMessage({ message: data.msg, type: 'error' }) if (options.showMessageConfig.showErrorMessage) ElMessage({ message: data.msg, type: 'error' })
@ -89,7 +91,7 @@ class Http {
const { data: { value }, error } = response const { data: { value }, error } = response
if (value) { if (value) {
if (value.code == 200) { if (value.code == 1) {
resolve(value) resolve(value)
} else { } else {
reject(value) reject(value)