|
|
@@ -0,0 +1,348 @@
|
|
|
+<script setup lang="ts">
|
|
|
+import dayjs from 'dayjs'
|
|
|
+import { isEuropean, getDateFormat } from '@/utils/tools'
|
|
|
+import ChangePasswordDialog from '@/views/Layout/src/components/Header/components/ChangePasswordDialog.vue'
|
|
|
+import { useUserStore } from '@/stores/modules/user'
|
|
|
+
|
|
|
+const userStore = useUserStore()
|
|
|
+const form = reactive({
|
|
|
+ firstName: userStore.userInfo?.first_name,
|
|
|
+ lastName: userStore.userInfo?.last_name,
|
|
|
+ username: userStore.userInfo?.uname,
|
|
|
+ email: userStore.userInfo?.email,
|
|
|
+ password: '**************'
|
|
|
+})
|
|
|
+
|
|
|
+const segmented = ref('dateTime')
|
|
|
+const handleSegmented = (type: string) => {
|
|
|
+ segmented.value = type
|
|
|
+}
|
|
|
+
|
|
|
+const changePasswordDialogRef = ref()
|
|
|
+const handleChangePassword = () => {
|
|
|
+ changePasswordDialogRef.value.openDialog()
|
|
|
+}
|
|
|
+
|
|
|
+const monthMap = {
|
|
|
+ 'MMM/DD/YYYY': 'MM/DD/YYYY',
|
|
|
+ 'DD/MMM/YYYY': 'DD/MM/YYYY',
|
|
|
+ 'YYYY-MMM-DD': 'YYYY-MM-DD'
|
|
|
+}
|
|
|
+// 用户没有指定日期格式化时,通过时区自动判断
|
|
|
+const initDateFormat = () => {
|
|
|
+ return monthMap[userStore.userInfo?.date_format] || getDateFormat()
|
|
|
+}
|
|
|
+const initMonthFormat = () => {
|
|
|
+ return userStore.userInfo?.date_format || getDateFormat()
|
|
|
+}
|
|
|
+const dateFormat = ref(initDateFormat())
|
|
|
+const monthFormat = ref(initMonthFormat())
|
|
|
+const dateFormatExample = computed(() => {
|
|
|
+ return {
|
|
|
+ 'MM/DD/YYYY': [
|
|
|
+ {
|
|
|
+ label: dayjs().format('MM/DD/YYYY'),
|
|
|
+ value: 'MM/DD/YYYY'
|
|
|
+ },
|
|
|
+ {
|
|
|
+ label: dayjs().format('MMM/DD/YYYY'),
|
|
|
+ value: 'MMM/DD/YYYY'
|
|
|
+ }
|
|
|
+ ],
|
|
|
+ 'DD/MM/YYYY': [
|
|
|
+ {
|
|
|
+ label: dayjs().format('DD/MM/YYYY'),
|
|
|
+ value: 'DD/MM/YYYY'
|
|
|
+ },
|
|
|
+ {
|
|
|
+ label: dayjs().format('DD/MMM/YYYY'),
|
|
|
+ value: 'DD/MMM/YYYY'
|
|
|
+ }
|
|
|
+ ],
|
|
|
+ 'YYYY-MM-DD': [
|
|
|
+ {
|
|
|
+ label: dayjs().format('YYYY-MM-DD'),
|
|
|
+ value: 'YYYY-MM-DD'
|
|
|
+ },
|
|
|
+ {
|
|
|
+ label: dayjs().format('YYYY-MMM-DD'),
|
|
|
+ value: 'YYYY-MMM-DD'
|
|
|
+ }
|
|
|
+ ]
|
|
|
+ }
|
|
|
+})
|
|
|
+
|
|
|
+const handleDateFormat = (value: string) => {
|
|
|
+ monthFormat.value = dateFormatExample.value[value][0].value
|
|
|
+}
|
|
|
+
|
|
|
+const numbersFormat = ref(userStore.userInfo?.numbers_format)
|
|
|
+
|
|
|
+// 判断用户是否指定数字格式化,没有指定则自动判断
|
|
|
+const isSpecifyNumbersFormat = () => {
|
|
|
+ numbersFormat.value = isEuropean() ? 'European' : 'US/UK'
|
|
|
+}
|
|
|
+isSpecifyNumbersFormat()
|
|
|
+
|
|
|
+const saveConfig = (model: string) => {
|
|
|
+ let params = {}
|
|
|
+ if (model === 'profile') {
|
|
|
+ params = {
|
|
|
+ save_model: 'profile',
|
|
|
+ first_name: form.firstName,
|
|
|
+ last_name: form.lastName
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ params = {
|
|
|
+ save_model: 'no_profile',
|
|
|
+ date_fromat: monthFormat.value,
|
|
|
+ number_format: numbersFormat.value
|
|
|
+ }
|
|
|
+ }
|
|
|
+ $api.saveUserInfo(params).then((res: any) => {
|
|
|
+ if (res.cdoe === 200) {
|
|
|
+ console.log(res)
|
|
|
+ }
|
|
|
+ })
|
|
|
+}
|
|
|
+</script>
|
|
|
+
|
|
|
+<template>
|
|
|
+ <div class="personal-profile">
|
|
|
+ <div class="basic-information">
|
|
|
+ <div class="title">Basic Information</div>
|
|
|
+ <div class="content">
|
|
|
+ <div class="row">
|
|
|
+ <div class="item">
|
|
|
+ <p class="label">First Name</p>
|
|
|
+ <el-input size="large" v-model="form.firstName" placeholder="Please enter..." />
|
|
|
+ </div>
|
|
|
+ <div class="item">
|
|
|
+ <p class="label">Last Name</p>
|
|
|
+ <el-input size="large" v-model="form.lastName" placeholder="Please enter..." />
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="row">
|
|
|
+ <div class="item">
|
|
|
+ <p class="label">User Name</p>
|
|
|
+ <el-input size="large" :disabled="true" v-model="form.username" />
|
|
|
+ </div>
|
|
|
+ <div class="item">
|
|
|
+ <p class="label">Email</p>
|
|
|
+ <el-input size="large" :disabled="true" v-model="form.email" />
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="row">
|
|
|
+ <div class="item">
|
|
|
+ <p class="label">
|
|
|
+ Password
|
|
|
+ <span style="margin: 0 2px 0 8px" class="font_family icon-icon_time_b"></span>
|
|
|
+ <span>Your password will be expire in</span>
|
|
|
+ <span style="margin-left: 4px; color: var(--color-theme)">4 day(s)</span>
|
|
|
+ </p>
|
|
|
+ <div class="password-change">
|
|
|
+ <el-input
|
|
|
+ size="large"
|
|
|
+ type="password"
|
|
|
+ style="width: 330px"
|
|
|
+ :disabled="true"
|
|
|
+ v-model="form.password"
|
|
|
+ />
|
|
|
+ <el-button @click="handleChangePassword" class="el-button--main" plain size="large"
|
|
|
+ >Change Password</el-button
|
|
|
+ >
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="row">
|
|
|
+ <el-button @click="saveConfig('profile')" class="el-button--dark save-icon" size="large"
|
|
|
+ >Save</el-button
|
|
|
+ >
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="personal-preferences">
|
|
|
+ <div class="title">Personal Preferences</div>
|
|
|
+ <div class="segmented">
|
|
|
+ <div
|
|
|
+ style="width: 121px"
|
|
|
+ :class="{ 'is-active': segmented === 'dateTime' }"
|
|
|
+ @click="handleSegmented('dateTime')"
|
|
|
+ class="item"
|
|
|
+ >
|
|
|
+ Date & Time
|
|
|
+ </div>
|
|
|
+ <div
|
|
|
+ style="width: 162px"
|
|
|
+ :class="{ 'is-active': segmented === 'numbersFormat' }"
|
|
|
+ @click="handleSegmented('numbersFormat')"
|
|
|
+ class="item"
|
|
|
+ >
|
|
|
+ Numbers Format
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="date-format" v-if="segmented === 'dateTime'">
|
|
|
+ <div class="title">Date & Time</div>
|
|
|
+ <div class="content">
|
|
|
+ <el-radio-group v-model="dateFormat" label="string" @change="handleDateFormat">
|
|
|
+ <el-row>
|
|
|
+ <el-col v-for="(list, key) in dateFormatExample" :key="key">
|
|
|
+ ><el-radio :value="key">
|
|
|
+ <template #default>
|
|
|
+ <span>{{ key }}</span>
|
|
|
+ <el-select
|
|
|
+ style="margin-left: 28px; width: 320px"
|
|
|
+ v-if="dateFormat === key"
|
|
|
+ size="large"
|
|
|
+ v-model="monthFormat"
|
|
|
+ >
|
|
|
+ <el-option
|
|
|
+ v-for="item in list"
|
|
|
+ :key="item.value"
|
|
|
+ :label="item.label"
|
|
|
+ :value="item.value"
|
|
|
+ ></el-option>
|
|
|
+ </el-select>
|
|
|
+ </template>
|
|
|
+ </el-radio>
|
|
|
+ </el-col>
|
|
|
+
|
|
|
+ <el-col>
|
|
|
+ <el-button
|
|
|
+ @click="saveConfig('no_profile')"
|
|
|
+ style="padding: 0 40px"
|
|
|
+ class="el-button--dark save-icon"
|
|
|
+ size="large"
|
|
|
+ >Save</el-button
|
|
|
+ >
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
+ </el-radio-group>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="numbers-format" v-if="segmented === 'numbersFormat'">
|
|
|
+ <div class="title">Numbers Format</div>
|
|
|
+ <div class="content">
|
|
|
+ <el-radio-group v-model="numbersFormat" label="string">
|
|
|
+ <el-row>
|
|
|
+ <el-col
|
|
|
+ ><el-radio value="US/UK">
|
|
|
+ <template #default>
|
|
|
+ <span>1,234.56 (US/UK)</span>
|
|
|
+ </template>
|
|
|
+ </el-radio></el-col
|
|
|
+ >
|
|
|
+ <el-col
|
|
|
+ ><el-radio value="European">
|
|
|
+ <template #default>
|
|
|
+ <span>1.234,56 (European)</span>
|
|
|
+ </template>
|
|
|
+ </el-radio></el-col
|
|
|
+ >
|
|
|
+ <el-col>
|
|
|
+ <el-button style="padding: 0 40px" class="el-button--dark save-icon" size="large"
|
|
|
+ >Save</el-button
|
|
|
+ >
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
+ </el-radio-group>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <ChangePasswordDialog ref="changePasswordDialogRef"></ChangePasswordDialog>
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+
|
|
|
+<style scoped lang="scss">
|
|
|
+.personal-profile {
|
|
|
+ .basic-information,
|
|
|
+ .personal-preferences {
|
|
|
+ border: 1px solid var(--color-border);
|
|
|
+ border-radius: 12px;
|
|
|
+ padding: 16px 16px 32px;
|
|
|
+ & > .title {
|
|
|
+ margin-bottom: 21px;
|
|
|
+ font-size: 18px;
|
|
|
+ font-weight: 700;
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+.basic-information {
|
|
|
+ .content {
|
|
|
+ .row {
|
|
|
+ display: flex;
|
|
|
+ gap: 8px;
|
|
|
+ .item {
|
|
|
+ flex: 1;
|
|
|
+ margin-bottom: 16px;
|
|
|
+ .label {
|
|
|
+ margin-bottom: 4px;
|
|
|
+ font-size: 12px;
|
|
|
+ color: var(--color-neutral-2);
|
|
|
+ & > span {
|
|
|
+ font-size: 12px;
|
|
|
+ color: var(--color-neutral-3);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .password-change {
|
|
|
+ display: flex;
|
|
|
+ gap: 8px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .save-icon {
|
|
|
+ margin-top: 16px;
|
|
|
+ padding: 0 40px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+.personal-profile {
|
|
|
+ div.personal-preferences {
|
|
|
+ margin-top: 16px;
|
|
|
+ padding-bottom: 8px;
|
|
|
+ .segmented {
|
|
|
+ width: 291px;
|
|
|
+ height: 40px;
|
|
|
+ margin-bottom: 8px;
|
|
|
+ padding: 4px;
|
|
|
+ border-radius: 12px;
|
|
|
+ background-color: #f5f7fa;
|
|
|
+ .item {
|
|
|
+ display: inline-block;
|
|
|
+ height: 32px;
|
|
|
+ line-height: 32px;
|
|
|
+ font-weight: 700;
|
|
|
+ font-size: 16px;
|
|
|
+ text-align: center;
|
|
|
+ border-radius: 6px;
|
|
|
+ color: var(--color-neutral-2);
|
|
|
+ cursor: pointer;
|
|
|
+ &.is-active {
|
|
|
+ background-color: var(--color-white);
|
|
|
+ color: var(--color-neutral-1);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .date-format,
|
|
|
+ .numbers-format {
|
|
|
+ padding: 0px 16px 32px;
|
|
|
+ background-color: #f5f7fa;
|
|
|
+ border-radius: 12px;
|
|
|
+ .title {
|
|
|
+ height: 40px;
|
|
|
+ font-size: 14px;
|
|
|
+ font-weight: 700;
|
|
|
+ line-height: 40px;
|
|
|
+ }
|
|
|
+ .el-col {
|
|
|
+ margin-bottom: 8px;
|
|
|
+ &:last-child {
|
|
|
+ margin-bottom: 0;
|
|
|
+ margin-top: 32px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+</style>
|