123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249 |
- <template>
- <div class="ml-[20px] min-h-[70vh] px-[20px] py-[30px] w-[1000px] bg-[#fff] rounded-[var(--rounded-big)]">
- <div class="h-full" v-loading="loading">
- <div>
- <div class="text-[18px] text-[#333] mb-[50px]">我的信息</div>
- <div v-if="info">
- <el-form :model="info" class="form-wrap" label-width="120px" label-position="left">
- <el-form-item :label="t('memberHeadimg')" class="pb-[20px] border-b-[1px] border-dashed border-[#ddd]">
- <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-else :src="img(info.headimg)" class="w-[80px] h-[80px]" alt="">
- <el-upload class="avatar-uploader" :show-file-list="false" v-bind="upload" ref="uploadRef">
- <span class="cursor-pointer text-primary">{{ t('edit') }}</span>
- </el-upload>
- </div>
- </el-form-item>
- <el-form-item :label="t('username')" class="pb-[20px] border-b-[1px] border-dashed border-[#ddd]">
- <div class="w-full flex justify-between content-center">
- <span>{{ info.username }}</span>
- </div>
- </el-form-item>
- <el-form-item :label="t('nickname')" class="pb-[20px] border-b-[1px] border-dashed border-[#ddd]">
- <div class="w-full flex justify-between content-center">
- <div>
- <span>{{ updateNickname.value }}</span>
- <span v-if="currentLevel">(当前等级:{{currentLevel}})</span>
- </div>
- <span class="cursor-pointer text-primary" @click="updateNickname.modal = true">{{ t('edit')}}</span>
- </div>
- </el-form-item>
- <el-form-item :label="t('mobile')" class="pb-[20px] border-b-[1px] border-dashed border-[#ddd]">
- <div class="w-full flex justify-between content-center">
- <span>{{ info.mobile }}</span>
- <span v-if="!info.mobile" class="cursor-pointer text-primary" @click="updateMobileDialog = true">{{ t('edit')}}</span>
- </div>
- </el-form-item>
- </el-form>
- <div class="flex justify-end mt-[38px]">
- <span class="cursor-pointer w-[130px] h-[40px] leading-[40px] text-center rounded-[4px] bg-[var(--el-color-primary)] text-white text-[14px]" @click="logoutFn">退出</span>
- </div>
- </div>
- </div>
- <!-- 更改昵称 -->
- <el-dialog v-model="updateNickname.modal" :title="t('nickname')" width="380">
- <el-form :model="info">
- <el-form-item>
- <el-input v-model="updateNickname.value" autocomplete="off" />
- </el-form-item>
- </el-form>
- <template #footer>
- <span class="dialog-footer">
- <el-button @click="updateNickname.modal = false">{{ t('cancel') }}</el-button>
- <el-button type="primary" @click="updateNicknameConfirm">{{ t('confirm') }}</el-button>
- </span>
- </template>
- </el-dialog>
- <!-- 更改手机号码 -->
- <el-dialog v-model="updateMobileDialog" :title="t('updateMobile')" width="420">
- <el-form :model="formData" ref="formRef" :rules="formRules" :validate-on-rule-change="false">
- <el-form-item prop="mobile">
- <el-input v-model="formData.mobile" :placeholder="t('mobilePlaceholder')" clearable>
- </el-input>
- </el-form-item>
- <el-form-item prop="mobile_code">
- <el-input v-model="formData.mobile_code" :placeholder="t('codePlaceholder')">
- <template #suffix>
- <sms-code :mobile="formData.mobile" type="login" v-model="formData.mobile_key" @click="sendSmsCode" ref="smsCodeRef"></sms-code>
- </template>
- </el-input>
- </el-form-item>
- </el-form>
- <template #footer>
- <span class="dialog-footer">
- <el-button @click="updateMobileDialog = false">{{ t('cancel') }}</el-button>
- <el-button type="primary" :loading="mobileLoading" @click="updateMobileConfirm">{{ t('confirm') }}</el-button>
- </span>
- </template>
- </el-dialog>
- </div>
- </div>
- </template>
- <script lang="ts" setup>
- import { reactive, ref, computed } from 'vue'
- import useMemberStore from '@/stores/member'
- import useAppStore from '@/stores/app'
- import { modifyMember, bindMobile, getMemberLevel} from '@/app/api/member'
- import { ElMessage, ElMessageBox, UploadFile, UploadFiles } from 'element-plus'
- import request from '@/utils/request'
- import storage from '@/utils/storage'
- import { getToken } from '@/utils/common'
- const memberStore = useMemberStore()
- const loading = ref(true)
- //会员昵称
- const updateNickname = reactive({
- modal: false,
- value: ''
- })
- const info = computed(() => {
- updateNickname.value = memberStore.info?.nickname;
- if (memberStore.info) loading.value = false;
- return memberStore.info;
- })
- const appStore = useAppStore()
- // 获取会员等级
- let currentLevel = ref('')
- const getMemberLevelFn = () =>{
- getMemberLevel().then(res =>{
- if(info.value && res.data && res.data.length){
- res.data.forEach((item,index)=>{
- if(item.level_id == info.value.member_level){
- currentLevel.value = item.level_name
- }
- })
- }
- })
- }
- getMemberLevelFn()
- const uploadRef = ref(null)
- const upload = computed(() => {
- const headers: Record<string, any> = {}
- headers.token = getToken()
- headers['site-id'] = storage.get('siteId') || 1
- return {
- action: `${request.options.baseURL}/file/image`,
- limit: 1,
- headers,
- onSuccess: (response: any, uploadFile: UploadFile, uploadFiles: UploadFiles) => {
- let img = uploadFile?.response?.data?.url;
- if (response.code == 200 || response.code == 1) {
- modifyMember({
- field: 'headimg',
- value: img
- }).then(() => {
- memberStore.info.headimg = img
- uploadRef.value.clearFiles()
- })
- } else {
- uploadFile.status = 'fail'
- ElMessage({ message: response.msg, type: 'error' })
- }
- }
- }
- })
- // 修改会员名称
- const updateNicknameConfirm = () => {
- if (!updateNickname.value) { ElMessage.error('会员昵称不能为空'); return }
- modifyMember({
- field: 'nickname',
- value: updateNickname.value
- }).then(res => {
- updateNickname.modal = false
- })
- }
- // 手机号
- const updateMobileDialog = ref(false)
- const formData = reactive({
- mobile: '',
- mobile_code: '',
- mobile_key: ''
- })
- const mobileLoading = ref(false)
- const formRef = ref<FormInstance>()
- const formRules = computed(() => {
- return {
- 'mobile': [
- {
- required: true,
- message: t('mobilePlaceholder'),
- trigger: ['blur', 'change'],
- },
- {
- validator(rule: any, value: string, callback: any) {
- const phonePattern = /^1[3456789]\d{9}$/
- if (!phonePattern.test(value)) {
- return callback(new Error(t('mobileTips')))
- } else {
- return callback()
- }
- },
- message: t('mobileError'),
- trigger: ['blur'],
- }
- ],
- 'mobile_code': {
- required: true,
- message: t('codePlaceholder'),
- trigger: ['change']
- }
- }
- })
- const smsCodeRef = ref<AnyObject | null>(null)
- const sendSmsCode = async () => {
- await formRef.value?.validateField('mobile', async (valid, fields) => {
- if (valid) {
- smsCodeRef.value?.send()
- }
- })
- }
- const updateMobileConfirm = async () => {
- await formRef.value?.validate(async (valid, fields) => {
- if (valid) {
- if (mobileLoading.value) return
- mobileLoading.value = true
- bindMobile(formData).then((res) => {
- memberStore.getMemberInfo()
- mobileLoading.value = false
- updateMobileDialog.value = false
- }).catch(() => {
- mobileLoading.value = false
- })
- }
- })
- }
- // 退出登录
- const logoutFn = () => {
- ElMessageBox.confirm('您确定要退出账号吗?', '提示',
- {
- confirmButtonText: '确定',
- cancelButtonText: '取消',
- confirmButtonClass:'!bg-[var(--el-color-primary)] !border-[var(--el-color-primary)]',
- cancelButtonClass:'!border-[#dcdfe6]',
- type: 'warning'
- }
- ).then(() => {
- memberStore.logout()
- navigateTo(`/`)
- })
- }
- </script>
- <style lang="scss" scoped>
- .box-card {
- border: none !important;
- }
- ::v-deep .form-wrap .el-form-item {
- align-items: center;
- }
- </style>
|