fix: 🧩 开关控制封装和邮件发送优化
This commit is contained in:
parent
00fe865e15
commit
a1eb4acacd
|
@ -264,7 +264,9 @@ function addAsyncRoutes(arrRoutes: Array<RouteRecordRaw>) {
|
|||
v.component = IFrame;
|
||||
} else {
|
||||
// 对后端传component组件路径和不传做兼容(如果后端传component组件路径,那么path可以随便写,如果不传,component组件路径会跟path保持一致)
|
||||
const index = v?.component ? modulesRoutesKeys.findIndex(ev => ev.includes(v.component as any)) : modulesRoutesKeys.findIndex(ev => ev.includes(v.path));
|
||||
const index = v?.component
|
||||
? modulesRoutesKeys.findIndex(ev => ev.includes(v.component as any))
|
||||
: modulesRoutesKeys.findIndex(ev => ev.includes(v.path));
|
||||
v.component = modulesRoutes[modulesRoutesKeys[index]];
|
||||
}
|
||||
if (v?.children && v.children.length !== 0) {
|
||||
|
@ -316,6 +318,7 @@ function hasAuth(value: string | Array<string>): boolean {
|
|||
if (metaAuths.includes('*::*::*') || metaAuths.includes('*::*') || metaAuths.includes('*')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return isString(value) ? metaAuths.includes(value) : isIncludeAllChildren(value, metaAuths);
|
||||
}
|
||||
|
||||
|
|
|
@ -7,16 +7,26 @@ import { useAdminUserStore } from '@/store/system/adminUser';
|
|||
import ResetPasswordDialog from '@/components/Table/ResetPasswords.vue';
|
||||
import { removeToken } from '@/utils/auth';
|
||||
import { useRouter } from 'vue-router';
|
||||
import { switchLoadMapControl, usePublicHooks } from '@/views/hooks';
|
||||
import { messageBox } from '@/utils/message';
|
||||
|
||||
const router = useRouter();
|
||||
// 用户是否停用样式
|
||||
const { switchStyle } = usePublicHooks();
|
||||
// 用户是否停用加载集合
|
||||
const switchLoadMap = ref({});
|
||||
// 重置密码表单校验Ref
|
||||
const ruleFormByRestPasswordRef = ref();
|
||||
const router = useRouter();
|
||||
const adminUserStore = useAdminUserStore();
|
||||
|
||||
// 重置密码表单
|
||||
const restPasswordForm = reactive({
|
||||
password: '',
|
||||
});
|
||||
// 提醒状态
|
||||
const reminderStatus = reactive({
|
||||
week: false, // 周账单状态
|
||||
mouth: false, // 月账单状态
|
||||
});
|
||||
|
||||
/** 重置密码 */
|
||||
const onResetPassword = () => {
|
||||
|
@ -46,46 +56,129 @@ const onResetPassword = () => {
|
|||
});
|
||||
};
|
||||
|
||||
const list = ref([
|
||||
{
|
||||
title: $t('account_password'),
|
||||
illustrate: $t('rest_password_tip'),
|
||||
button: $t('modify'),
|
||||
callback: onResetPassword,
|
||||
},
|
||||
// {
|
||||
// title: '密保手机',
|
||||
// illustrate: '已经绑定手机:158****6789',
|
||||
// button: '修改',
|
||||
// },
|
||||
// {
|
||||
// title: '密保问题',
|
||||
// illustrate: '未设置密保问题,密保问题可有效保护账户安全',
|
||||
// button: '修改',
|
||||
// },
|
||||
// {
|
||||
// title: '备用邮箱',
|
||||
// illustrate: '已绑定邮箱:pure***@163.com',
|
||||
// button: '修改',
|
||||
// },
|
||||
]);
|
||||
/** 更新用户周账单提醒是否开启 */
|
||||
const updateUserReportStatusByWeek = async (index: number) => {
|
||||
// 点击时开始loading加载
|
||||
switchLoadMapControl(switchLoadMap, index, true);
|
||||
|
||||
// 是否确认修改弹窗内容
|
||||
const confirm = await messageBox({
|
||||
title: $t('confirm_update_status'),
|
||||
showMessage: false,
|
||||
confirmMessage: undefined,
|
||||
cancelMessage: $t('cancel'),
|
||||
});
|
||||
|
||||
// 如果不修改将值恢复到之前状态
|
||||
if (!confirm) {
|
||||
reminderStatus.week = !reminderStatus.week;
|
||||
switchLoadMapControl(switchLoadMap, index, false);
|
||||
return;
|
||||
}
|
||||
|
||||
// 修改用户状态
|
||||
// const data = { userId: row.id, status: row.status };
|
||||
// const result = await adminUserStore.updateUserStatusByAdmin(data);
|
||||
// if (!result) {
|
||||
// row.status = !row.status;
|
||||
// switchLoadMap.value[index] = Object.assign({}, switchLoadMap.value[index], {
|
||||
// loading: false,
|
||||
// });
|
||||
// return;
|
||||
// }
|
||||
// await onSearch();
|
||||
switchLoadMapControl(switchLoadMap, index, false);
|
||||
};
|
||||
|
||||
/** 更新用户周账单提醒是否开启 */
|
||||
const updateUserReportStatusByMouth = async (index: number) => {
|
||||
// 点击时开始loading加载
|
||||
switchLoadMapControl(switchLoadMap, index, true);
|
||||
|
||||
// 是否确认修改弹窗内容
|
||||
const confirm = await messageBox({
|
||||
title: $t('confirm_update_status'),
|
||||
showMessage: false,
|
||||
confirmMessage: undefined,
|
||||
cancelMessage: $t('cancel'),
|
||||
});
|
||||
|
||||
// 如果不修改将值恢复到之前状态
|
||||
if (!confirm) {
|
||||
reminderStatus.week = !reminderStatus.week;
|
||||
switchLoadMapControl(switchLoadMap, index, false);
|
||||
return;
|
||||
}
|
||||
|
||||
// 修改用户状态
|
||||
// const data = { userId: row.id, status: row.status };
|
||||
// const result = await adminUserStore.updateUserStatusByAdmin(data);
|
||||
// if (!result) {
|
||||
// row.status = !row.status;
|
||||
// switchLoadMap.value[index] = Object.assign({}, switchLoadMap.value[index], {
|
||||
// loading: false,
|
||||
// });
|
||||
// return;
|
||||
// }
|
||||
// await onSearch();
|
||||
switchLoadMapControl(switchLoadMap, index, false);
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div :class="['min-w-[180px]', deviceDetection() ? 'max-w-[100%]' : 'max-w-[70%]']">
|
||||
<h3 class="my-8">{{ $t('account_management') }}</h3>
|
||||
<div v-for="(item, index) in list" :key="index">
|
||||
<div class="flex items-center">
|
||||
<ul>
|
||||
<!-- 重置密码 -->
|
||||
<li class="flex items-center">
|
||||
<div class="flex-1">
|
||||
<p>{{ item.title }}</p>
|
||||
<el-text class="mx-1" type="info">{{ item.illustrate }}</el-text>
|
||||
<p>{{ $t('account_password') }}</p>
|
||||
<el-text class="mx-1" type="info">{{ $t('rest_password_tip') }}</el-text>
|
||||
</div>
|
||||
<el-button text type="primary" @click="item.callback">
|
||||
{{ item.button }}
|
||||
</el-button>
|
||||
</div>
|
||||
<el-button text type="primary" @click="onResetPassword"> {{ $t('modify') }}</el-button>
|
||||
</li>
|
||||
<el-divider />
|
||||
</div>
|
||||
|
||||
<!-- 是否开启周账单提醒 -->
|
||||
<li class="flex items-center">
|
||||
<div class="flex-1">
|
||||
<p>周账单提醒</p>
|
||||
<el-text class="mx-1" type="info">是否开启周账单提醒(需要保证有邮箱)</el-text>
|
||||
</div>
|
||||
<el-switch
|
||||
v-model="reminderStatus.week"
|
||||
:active-text="$t('enable')"
|
||||
:active-value="false"
|
||||
:inactive-text="$t('disable')"
|
||||
:inactive-value="true"
|
||||
:loading="switchLoadMap[0]?.loading"
|
||||
:style="switchStyle"
|
||||
inline-prompt
|
||||
@click="updateUserReportStatusByWeek(0)"
|
||||
/>
|
||||
</li>
|
||||
<el-divider />
|
||||
|
||||
<!-- 是否开启月账单提醒 -->
|
||||
<li class="flex items-center">
|
||||
<div class="flex-1">
|
||||
<p>月账单提醒</p>
|
||||
<el-text class="mx-1" type="info">是否开启月账单提醒(需要保证有邮箱)</el-text>
|
||||
</div>
|
||||
<el-switch
|
||||
v-model="reminderStatus.mouth"
|
||||
:active-text="$t('enable')"
|
||||
:active-value="false"
|
||||
:inactive-text="$t('disable')"
|
||||
:inactive-value="true"
|
||||
:loading="switchLoadMap[1]?.loading"
|
||||
:style="switchStyle"
|
||||
inline-prompt
|
||||
@click="updateUserReportStatusByMouth(1)"
|
||||
/>
|
||||
</li>
|
||||
<el-divider />
|
||||
</ul>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@ import { rules } from '@/views/configuration/emailTemplate/utils/columns';
|
|||
import { FormProps } from '@/views/configuration/emailTemplate/utils/types';
|
||||
import { $t } from '@/plugins/i18n';
|
||||
import { useEmailTemplateStore } from '@/store/configuration/emailTemplate';
|
||||
import { usePublicHooks } from '@/views/hooks';
|
||||
|
||||
const props = withDefaults(defineProps<FormProps>(), {
|
||||
formInline: () => ({
|
||||
|
@ -14,6 +15,8 @@ const props = withDefaults(defineProps<FormProps>(), {
|
|||
emailUser: undefined,
|
||||
// 主题
|
||||
subject: undefined,
|
||||
// 是否默认
|
||||
isDefault: false,
|
||||
// 邮件内容
|
||||
body: undefined,
|
||||
// 邮件类型
|
||||
|
@ -21,6 +24,8 @@ const props = withDefaults(defineProps<FormProps>(), {
|
|||
}),
|
||||
});
|
||||
|
||||
// 用户是否停用样式
|
||||
const { switchStyle } = usePublicHooks();
|
||||
const formRef = ref<FormInstance>();
|
||||
const form = ref(props.formInline);
|
||||
const emailTemplateStore = useEmailTemplateStore();
|
||||
|
@ -51,6 +56,19 @@ defineExpose({ formRef });
|
|||
<el-input v-model="form.subject" autocomplete="off" type="text" />
|
||||
</el-form-item>
|
||||
|
||||
<!-- 用户状态 -->
|
||||
<el-form-item :label="$t('isDefault')" prop="isDefault">
|
||||
<el-switch
|
||||
v-model="form.isDefault"
|
||||
:active-text="$t('enable')"
|
||||
:active-value="true"
|
||||
:inactive-text="$t('disable')"
|
||||
:inactive-value="false"
|
||||
:style="switchStyle"
|
||||
inline-prompt
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<!-- 配置邮件发送体 -->
|
||||
<el-form-item :label="$t('emailTemplate_body')" prop="body">
|
||||
<el-input v-model="form.body" :autosize="{ minRows: 2, maxRows: 26 }" autocomplete="off" type="textarea" />
|
||||
|
|
|
@ -55,7 +55,12 @@ onMounted(() => {
|
|||
<Auth :value="auth.search">
|
||||
<el-form ref="formRef" :inline="true" :model="emailTemplateStore.form" class="search-form bg-bg_color w-[99/100] pl-8 pt-[12px] overflow-auto">
|
||||
<el-form-item :label="$t('emailTemplate_templateName')" prop="templateName">
|
||||
<el-input v-model="emailTemplateStore.form.templateName" :placeholder="`${$t('input')}${$t('emailTemplate_templateName')}`" class="!w-[180px]" clearable />
|
||||
<el-input
|
||||
v-model="emailTemplateStore.form.templateName"
|
||||
:placeholder="`${$t('input')}${$t('emailTemplate_templateName')}`"
|
||||
class="!w-[180px]"
|
||||
clearable
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('emailTemplate_subject')" prop="subject">
|
||||
<el-input v-model="emailTemplateStore.form.subject" :placeholder="`${$t('input')}${$t('emailTemplate_subject')}`" class="!w-[180px]" clearable />
|
||||
|
@ -67,7 +72,9 @@ onMounted(() => {
|
|||
<el-input v-model="emailTemplateStore.form.type" :placeholder="`${$t('input')}${$t('emailTemplate_type')}`" class="!w-[180px]" clearable />
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button :icon="useRenderIcon('ri:search-line')" :loading="emailTemplateStore.loading" type="primary" @click="onSearch"> {{ $t('search') }} </el-button>
|
||||
<el-button :icon="useRenderIcon('ri:search-line')" :loading="emailTemplateStore.loading" type="primary" @click="onSearch">
|
||||
{{ $t('search') }}
|
||||
</el-button>
|
||||
<el-button :icon="useRenderIcon(Refresh)" @click="resetForm(formRef)"> {{ $t('buttons.reset') }}</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
@ -126,7 +133,15 @@ onMounted(() => {
|
|||
<el-button :icon="useRenderIcon(View)" :size="size" class="reset-margin" link type="primary" @click="viewTemplate(row.body)">
|
||||
{{ $t('view') }}
|
||||
</el-button>
|
||||
<el-button v-if="hasAuth(auth.update)" :icon="useRenderIcon(EditPen)" :size="size" class="reset-margin" link type="primary" @click="onUpdate(row)">
|
||||
<el-button
|
||||
v-if="hasAuth(auth.update)"
|
||||
:icon="useRenderIcon(EditPen)"
|
||||
:size="size"
|
||||
class="reset-margin"
|
||||
link
|
||||
type="primary"
|
||||
@click="onUpdate(row)"
|
||||
>
|
||||
{{ $t('modify') }}
|
||||
</el-button>
|
||||
<el-popconfirm v-if="hasAuth(auth.deleted)" :title="`${$t('delete')} ${row.templateName}?`" @confirm="onDelete(row)">
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import { reactive } from 'vue';
|
||||
import { $t } from '@/plugins/i18n';
|
||||
import { ElTag } from 'element-plus';
|
||||
|
||||
// 表格列
|
||||
export const columns: TableColumnList = [
|
||||
|
@ -14,7 +15,21 @@ export const columns: TableColumnList = [
|
|||
// 邮件内容
|
||||
{ label: $t('emailTemplate_body'), prop: 'body' },
|
||||
// 邮件类型
|
||||
{ label: $t('emailTemplate_type'), prop: 'type' },
|
||||
{ label: $t('emailTemplate_type'), prop: 'summary' },
|
||||
// 是否默认
|
||||
{
|
||||
label: $t('isDefault'),
|
||||
prop: 'isDefault',
|
||||
formatter({ isDefault }) {
|
||||
return isDefault ? (
|
||||
<ElTag type={'success'}>{$t('default')}</ElTag>
|
||||
) : (
|
||||
<ElTag size={'large'} type={'danger'}>
|
||||
{$t('no_default')}
|
||||
</ElTag>
|
||||
);
|
||||
},
|
||||
},
|
||||
{ label: $t('table.updateTime'), prop: 'updateTime', sortable: true, width: 160 },
|
||||
{ label: $t('table.createTime'), prop: 'createTime', sortable: true, width: 160 },
|
||||
{ label: $t('table.createUser'), prop: 'createUser', slot: 'createUser', width: 130 },
|
|
@ -29,6 +29,7 @@ export function onAdd() {
|
|||
templateName: undefined,
|
||||
emailUser: undefined,
|
||||
subject: undefined,
|
||||
isDefault: undefined,
|
||||
body: undefined,
|
||||
type: undefined,
|
||||
},
|
||||
|
@ -64,6 +65,7 @@ export function onUpdate(row: any) {
|
|||
templateName: row.templateName,
|
||||
emailUser: row.emailUser,
|
||||
subject: row.subject,
|
||||
isDefault: row.isDefault,
|
||||
body: row.body,
|
||||
type: row.type,
|
||||
},
|
||||
|
|
|
@ -6,6 +6,8 @@ export interface FormItemProps {
|
|||
emailUser: string;
|
||||
// 主题
|
||||
subject: string;
|
||||
// 是否默认
|
||||
isDefault: boolean;
|
||||
// 邮件内容
|
||||
body: string;
|
||||
// 邮件类型
|
||||
|
|
|
@ -61,7 +61,15 @@ defineExpose({ formRef });
|
|||
|
||||
<!-- 是否为默认 -->
|
||||
<el-form-item :label="$t('emailUsers_isDefault')" prop="isDefault">
|
||||
<el-switch v-model="form.isDefault" :active-text="$t('default')" :active-value="true" :inactive-text="$t('no_default')" :inactive-value="false" :style="switchStyle" inline-prompt />
|
||||
<el-switch
|
||||
v-model="form.isDefault"
|
||||
:active-text="$t('default')"
|
||||
:active-value="true"
|
||||
:inactive-text="$t('no_default')"
|
||||
:inactive-value="false"
|
||||
:style="switchStyle"
|
||||
inline-prompt
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</template>
|
||||
|
|
|
@ -63,6 +63,7 @@ defineExpose({ formRef });
|
|||
<el-date-picker
|
||||
v-model="form.transactionDate"
|
||||
:placeholder="$t('select') + $t('transactionDate')"
|
||||
class="!w-[100%]"
|
||||
format="YYYY/MM/DD HH:mm:ss"
|
||||
type="datetime"
|
||||
value-format="YYYY-MM-DD HH:mm:ss"
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// 抽离可公用的工具函数等用于系统管理页面逻辑
|
||||
import { computed } from 'vue';
|
||||
import { computed, type UnwrapRef } from 'vue';
|
||||
import { useDark } from '@pureadmin/utils';
|
||||
|
||||
export function usePublicHooks() {
|
||||
|
@ -36,3 +36,15 @@ export function usePublicHooks() {
|
|||
tagStyle,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 样式开关控制封装
|
||||
* @param switchLoadMap
|
||||
* @param index
|
||||
* @param loading
|
||||
*/
|
||||
export const switchLoadMapControl = (switchLoadMap: Ref<UnwrapRef<any>>, index: number, loading: boolean) => {
|
||||
switchLoadMap.value[index] = Object.assign({}, switchLoadMap.value[index], {
|
||||
loading,
|
||||
});
|
||||
};
|
||||
|
|
|
@ -92,7 +92,15 @@ defineExpose({ formRef });
|
|||
|
||||
<re-col :sm="24" :value="12" :xs="24">
|
||||
<el-form-item :label="$t('adminUser_dept')" prop="deptId">
|
||||
<el-cascader v-model="form.deptId" :options="deptList" :placeholder="$t('select') + $t('adminUser_dept')" :props="deptSelector" class="w-full" clearable filterable>
|
||||
<el-cascader
|
||||
v-model="form.deptId"
|
||||
:options="deptList"
|
||||
:placeholder="$t('select') + $t('adminUser_dept')"
|
||||
:props="deptSelector"
|
||||
class="w-full"
|
||||
clearable
|
||||
filterable
|
||||
>
|
||||
<template #default="{ node, data }">
|
||||
<span>{{ data.deptName }}</span>
|
||||
<span v-if="!node.isLeaf"> ({{ data.children.length }}) </span>
|
||||
|
@ -104,7 +112,15 @@ defineExpose({ formRef });
|
|||
<!-- 用户状态 -->
|
||||
<re-col :sm="24" :value="12" :xs="24">
|
||||
<el-form-item :label="$t('adminUser_status')" prop="status">
|
||||
<el-switch v-model="form.status" :active-text="$t('enable')" :active-value="false" :inactive-text="$t('disable')" :inactive-value="true" :style="switchStyle" inline-prompt />
|
||||
<el-switch
|
||||
v-model="form.status"
|
||||
:active-text="$t('enable')"
|
||||
:active-value="false"
|
||||
:inactive-text="$t('disable')"
|
||||
:inactive-value="true"
|
||||
:style="switchStyle"
|
||||
inline-prompt
|
||||
/>
|
||||
</el-form-item>
|
||||
</re-col>
|
||||
|
||||
|
|
|
@ -88,7 +88,13 @@ onMounted(() => {
|
|||
|
||||
<template>
|
||||
<div :class="['flex', 'justify-between', deviceDetection() && 'flex-wrap']">
|
||||
<tree ref="treeRef" :class="['mr-2', deviceDetection() ? 'w-full' : 'min-w-[200px]']" :treeData="deptList" :treeLoading="deptStore.loading" @tree-select="onTreeSelect" />
|
||||
<tree
|
||||
ref="treeRef"
|
||||
:class="['mr-2', deviceDetection() ? 'w-full' : 'min-w-[200px]']"
|
||||
:treeData="deptList"
|
||||
:treeLoading="deptStore.loading"
|
||||
@tree-select="onTreeSelect"
|
||||
/>
|
||||
<div :class="[deviceDetection() ? ['w-full', 'mt-2'] : 'w-[calc(100%-200px)]']">
|
||||
<Auth :value="auth.search">
|
||||
<el-form ref="formRef" :inline="true" :model="adminUserStore.form" class="search-form bg-bg_color w-[99/100] pl-8 pt-[12px] overflow-auto">
|
||||
|
@ -126,13 +132,21 @@ onMounted(() => {
|
|||
|
||||
<!-- 查询状态 -->
|
||||
<el-form-item :label="$t('adminUser_status')" prop="status">
|
||||
<el-select v-model="adminUserStore.form.status" :placeholder="`${$t('input')}${$t('adminUser_status')}`" class="!w-[180px]" clearable filterable>
|
||||
<el-select
|
||||
v-model="adminUserStore.form.status"
|
||||
:placeholder="`${$t('input')}${$t('adminUser_status')}`"
|
||||
class="!w-[180px]"
|
||||
clearable
|
||||
filterable
|
||||
>
|
||||
<el-option v-for="(item, index) in userStatus" :key="index" :label="item.label" :navigationBar="false" :value="item.value" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item>
|
||||
<el-button :icon="useRenderIcon('ri:search-line')" :loading="adminUserStore.loading" type="primary" @click="onSearch"> {{ $t('search') }} </el-button>
|
||||
<el-button :icon="useRenderIcon('ri:search-line')" :loading="adminUserStore.loading" type="primary" @click="onSearch">
|
||||
{{ $t('search') }}
|
||||
</el-button>
|
||||
<el-button :icon="useRenderIcon(Refresh)" @click="resetForm(formRef)"> {{ $t('buttons.reset') }}</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
@ -173,7 +187,13 @@ onMounted(() => {
|
|||
>
|
||||
<!-- 显示头像 -->
|
||||
<template #avatar="{ row }">
|
||||
<el-image :preview-src-list="Array.of(row.avatar || UserAvatar)" :src="row.avatar || UserAvatar" class="w-[24px] h-[24px] rounded-full align-middle" fit="cover" preview-teleported>
|
||||
<el-image
|
||||
:preview-src-list="Array.of(row.avatar || UserAvatar)"
|
||||
:src="row.avatar || UserAvatar"
|
||||
class="w-[24px] h-[24px] rounded-full align-middle"
|
||||
fit="cover"
|
||||
preview-teleported
|
||||
>
|
||||
<template #error>
|
||||
<div class="image-slot">
|
||||
<img :src="UserAvatar" alt="" />
|
||||
|
@ -218,7 +238,17 @@ onMounted(() => {
|
|||
|
||||
<template #operation="{ row }">
|
||||
<!-- 修改 -->
|
||||
<el-button v-if="hasAuth(auth.update)" :icon="useRenderIcon(EditPen)" :size="size" class="reset-margin" link type="primary" @click="onUpdate(row)"> {{ $t('modify') }} </el-button>
|
||||
<el-button
|
||||
v-if="hasAuth(auth.update)"
|
||||
:icon="useRenderIcon(EditPen)"
|
||||
:size="size"
|
||||
class="reset-margin"
|
||||
link
|
||||
type="primary"
|
||||
@click="onUpdate(row)"
|
||||
>
|
||||
{{ $t('modify') }}
|
||||
</el-button>
|
||||
|
||||
<!-- 删除 -->
|
||||
<el-popconfirm v-if="hasAuth(auth.deleted)" :title="`${$t('delete')} ${row.username}?`" @confirm="onDelete(row)">
|
||||
|
@ -236,19 +266,27 @@ onMounted(() => {
|
|||
<el-dropdown-menu>
|
||||
<!-- 上传头像 -->
|
||||
<el-dropdown-item v-if="hasAuth(auth.uploadAvatarByAdmin)">
|
||||
<el-button :class="tableSelectButtonClass" :icon="useRenderIcon(Upload)" :size="size" link type="primary" @click="onUploadAvatar(row)"> {{ $t('upload_avatar') }} </el-button>
|
||||
<el-button :class="tableSelectButtonClass" :icon="useRenderIcon(Upload)" :size="size" link type="primary" @click="onUploadAvatar(row)">
|
||||
{{ $t('upload_avatar') }}
|
||||
</el-button>
|
||||
</el-dropdown-item>
|
||||
<!-- 重置密码 -->
|
||||
<el-dropdown-item v-if="hasAuth(auth.updateUserPasswordByAdmin)">
|
||||
<el-button :class="tableSelectButtonClass" :icon="useRenderIcon(Password)" :size="size" link type="primary" @click="onResetPassword(row)"> {{ $t('reset_passwords') }} </el-button>
|
||||
<el-button :class="tableSelectButtonClass" :icon="useRenderIcon(Password)" :size="size" link type="primary" @click="onResetPassword(row)">
|
||||
{{ $t('reset_passwords') }}
|
||||
</el-button>
|
||||
</el-dropdown-item>
|
||||
<!-- 分配角色 -->
|
||||
<el-dropdown-item v-if="hasAuth(auth.updateUserPasswordByAdmin)">
|
||||
<el-button :class="tableSelectButtonClass" :icon="useRenderIcon(Role)" :size="size" link type="primary" @click="onAssignRolesToUser(row)"> {{ $t('assign_roles') }} </el-button>
|
||||
<el-button :class="tableSelectButtonClass" :icon="useRenderIcon(Role)" :size="size" link type="primary" @click="onAssignRolesToUser(row)">
|
||||
{{ $t('assign_roles') }}
|
||||
</el-button>
|
||||
</el-dropdown-item>
|
||||
<!-- 强制下线 -->
|
||||
<el-dropdown-item v-if="hasAuth(auth.forcedOffline)">
|
||||
<el-button :class="tableSelectButtonClass" :icon="useRenderIcon(Airplane)" :size="size" link type="primary" @click="onForcedOffline(row)"> {{ $t('forced_offline') }} </el-button>
|
||||
<el-button :class="tableSelectButtonClass" :icon="useRenderIcon(Airplane)" :size="size" link type="primary" @click="onForcedOffline(row)">
|
||||
{{ $t('forced_offline') }}
|
||||
</el-button>
|
||||
</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</template>
|
||||
|
|
|
@ -14,7 +14,14 @@ import { currentMouth, currentYear, shortcutsAllMouth } from '@/enums/dateEnums'
|
|||
|
||||
const { isDark } = useDark();
|
||||
// 日期范围选择
|
||||
const shortcuts = [{ text: $t('thisMonth'), value: currentMouth }, { text: $t('thisYear'), value: currentYear }, ...shortcutsAllMouth()];
|
||||
const shortcuts = [
|
||||
{ text: $t('thisMonth'), value: currentMouth },
|
||||
{
|
||||
text: $t('thisYear'),
|
||||
value: currentYear,
|
||||
},
|
||||
...shortcutsAllMouth(),
|
||||
];
|
||||
|
||||
onMounted(() => {
|
||||
onSearch();
|
||||
|
@ -69,13 +76,16 @@ onMounted(() => {
|
|||
<el-card class="line-card" shadow="never">
|
||||
<div class="flex justify-between">
|
||||
<span class="text-md font-medium"> {{ $t('percentageOfExpenditure') }} </span>
|
||||
<div :style="{ backgroundColor: isDark ? 'transparent' : '#fff5f4' }" class="w-8 h-8 flex justify-center items-center rounded-md">
|
||||
<IconifyIconOnline color="#F56C6C" icon="tabler:percentage-66" width="18" />
|
||||
<div
|
||||
:style="{ backgroundColor: isDark ? 'transparent' : 'rgba(227,225,239,0.67)' }"
|
||||
class="w-8 h-8 flex justify-center items-center rounded-md"
|
||||
>
|
||||
<IconifyIconOnline color="#7872E8" icon="tabler:percentage-66" width="18" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex justify-between items-start mt-3">
|
||||
<div class="w-1/2">
|
||||
<span class="font-medium text-purple-500" style="font-size: 1.6em">{{ `${expendPercent} %` }}</span>
|
||||
<span class="font-medium text-violet-500" style="font-size: 1.6em">{{ `${expendPercent} %` }}</span>
|
||||
</div>
|
||||
<ChartRound :data="expendPercent" class="!w-1/2" />
|
||||
</div>
|
||||
|
|
|
@ -103,7 +103,7 @@ function homeCardFun(income, expend) {
|
|||
const profitValue = (income - expend).toFixed(2);
|
||||
data = {
|
||||
icon: 'hugeicons:profit',
|
||||
bgColor: '#fff5f4',
|
||||
bgColor: '#eef4ff',
|
||||
color: '#409EFF',
|
||||
duration: 2200,
|
||||
name: $t('amountOfProfit'),
|
||||
|
|
Loading…
Reference in New Issue