style: 格式化代码

This commit is contained in:
bunny 2025-04-28 09:39:28 +08:00
parent ac5c738267
commit a0a6165ee3
129 changed files with 453 additions and 2664 deletions

View File

@ -14,7 +14,7 @@ export default {
// 在 JSX 中使用单引号替代双引号默认false
jsxSingleQuote: false,
// 每行最多字符数量,超出换行(默认100)
printWidth: 120,
printWidth: 160,
// 超出打印宽度 (always | never | preserve )
proseWrap: 'preserve',
// 对象属性是否使用引号(as-needed | consistent | preserve;默认as-needed:对象的属性需要加引号才添加;)

View File

@ -31,12 +31,7 @@ class PureHttp {
}
/** 通用请求工具函数 */
public request<T>(
method: RequestMethods,
url: string,
param?: AxiosRequestConfig,
axiosConfig?: PureHttpRequestConfig
): Promise<T> {
public request<T>(method: RequestMethods, url: string, param?: AxiosRequestConfig, axiosConfig?: PureHttpRequestConfig): Promise<T> {
const config = {
method,
url,

View File

@ -33,12 +33,7 @@ class PureHttp {
}
/** 通用请求工具函数 */
public request<T>(
method: RequestMethods,
url: string,
param?: AxiosRequestConfig,
axiosConfig?: PureHttpRequestConfig
): Promise<T> {
public request<T>(method: RequestMethods, url: string, param?: AxiosRequestConfig, axiosConfig?: PureHttpRequestConfig): Promise<T> {
const config = { method, url, ...param, ...axiosConfig } as PureHttpRequestConfig;
// 单独处理自定义请求/响应回调

View File

@ -38,12 +38,7 @@ export interface PureHttpRequestConfig extends AxiosRequestConfig {
}
export default class PureHttp {
request<T>(
method: RequestMethods,
url: string,
param?: AxiosRequestConfig,
axiosConfig?: PureHttpRequestConfig
): Promise<T>;
request<T>(method: RequestMethods, url: string, param?: AxiosRequestConfig, axiosConfig?: PureHttpRequestConfig): Promise<T>;
post<T, P>(url: string, params?: P, config?: PureHttpRequestConfig): Promise<T>;

View File

@ -9,22 +9,12 @@ export const getFilesPage = (data: any) => {
};
/** 系统文件管理---添加系统文件 */
export const fetchAddFiles = (data: any) => {
return http.request<BaseResult<any>>(
'post',
'files',
{ data },
{ headers: { 'Content-Type': 'multipart/form-data' } }
);
return http.request<BaseResult<any>>('post', 'files', { data }, { headers: { 'Content-Type': 'multipart/form-data' } });
};
/** 系统文件管理---更新系统文件 */
export const updateFiles = (data: any) => {
return http.request<BaseResult<object>>(
'put',
'files',
{ data },
{ headers: { 'Content-Type': 'multipart/form-data' } }
);
return http.request<BaseResult<object>>('put', 'files', { data }, { headers: { 'Content-Type': 'multipart/form-data' } });
};
/** 系统文件管理---删除系统文件 */

View File

@ -35,12 +35,7 @@ export const downloadI18n = (params: object) => {
/** 多语言管理---文件更新多语言可以是JSON、Excel */
export const uploadI18nFile = (data: any) => {
return http.request<BaseResult<object>>(
'put',
'i18n/file',
{ data },
{ headers: { 'Content-Type': 'multipart/form-data' } }
);
return http.request<BaseResult<object>>('put', 'i18n/file', { data }, { headers: { 'Content-Type': 'multipart/form-data' } });
};
// ------------------------------------------------

View File

@ -47,12 +47,7 @@ export const createUserByAdmin = (data: any) => {
/** 用户信息---更新用户信息 */
export const updateUserByAdmin = (data: any) => {
return http.request<BaseResult<object>>(
'put',
'user',
{ data },
{ headers: { 'Content-Type': 'multipart/form-data' } }
);
return http.request<BaseResult<object>>('put', 'user', { data }, { headers: { 'Content-Type': 'multipart/form-data' } });
};
/** 用户信息---删除用户信息 */
@ -91,12 +86,7 @@ export const refreshTokenApi = (data?: object) => {
/** 发送邮件 */
export const sendLoginEmail = (data: any) => {
return http.request<BaseResult<any>>(
'post',
'/user/public/sendLoginEmail',
{ data },
{ headers: { 'Content-Type': 'multipart/form-data' } }
);
return http.request<BaseResult<any>>('post', '/user/public/sendLoginEmail', { data }, { headers: { 'Content-Type': 'multipart/form-data' } });
};
/** 获取用户信息,根据当前token获取 */
@ -116,10 +106,5 @@ export const updateUserinfo = (data: any) => {
/** 用户信息---更新用户密码 */
export const updateUserPassword = (data: any) => {
return http.request<BaseResult<object>>(
'put',
'user/private/update/password',
{ data },
{ headers: { 'Content-Type': 'multipart/form-data' } }
);
return http.request<BaseResult<object>>('put', 'user/private/update/password', { data }, { headers: { 'Content-Type': 'multipart/form-data' } });
};

View File

@ -30,12 +30,7 @@ export const exportPermission = () => {
/** 权限---导入权限权限 */
export const importPermission = (data: any) => {
return http.request<any>(
'put',
'permission/file/import',
{ data },
{ headers: { 'Content-Type': 'multipart/form-data' } }
);
return http.request<any>('put', 'permission/file/import', { data }, { headers: { 'Content-Type': 'multipart/form-data' } });
};
/** 权限---获取所有权限 */

View File

@ -34,12 +34,7 @@ export const exportRoleList = () => {
/* 角色---使用Excel更新角色列表 */
export const updateRoleByFile = (data: any) => {
return http.request<BaseResult<any>>(
'put',
`/role/file/import`,
{ data },
{ headers: { 'Content-Type': 'multipart/form-data' } }
);
return http.request<BaseResult<any>>('put', `/role/file/import`, { data }, { headers: { 'Content-Type': 'multipart/form-data' } });
};
/** 为用户分配角色---根据用户id获取所有角色 */

View File

@ -8,10 +8,5 @@ export const fetchRouterAsync = () => {
/** 上传文件 */
export const uploadFile = (data: any) => {
return http.request<BaseResult<any>>(
'post',
'/files/private/upload',
{ data },
{ headers: { 'Content-Type': 'multipart/form-data' } }
);
return http.request<BaseResult<any>>('post', '/files/private/upload', { data }, { headers: { 'Content-Type': 'multipart/form-data' } });
};

View File

@ -16,9 +16,7 @@
if (c && !e.__iconfont__svg__cssinject__) {
e.__iconfont__svg__cssinject__ = !0;
try {
document.write(
'<style>.svgfont {display: inline-block;width: 1em;height: 1em;fill: currentColor;vertical-align: -0.1em;font-size:16px;}</style>'
);
document.write('<style>.svgfont {display: inline-block;width: 1em;height: 1em;fill: currentColor;vertical-align: -0.1em;font-size:16px;}</style>');
} catch (t) {
console && console.log(t);
}

View File

@ -54,7 +54,6 @@ export default defineComponent({
state.rAF = requestAnimationFrame(count);
}
// eslint-disable-next-line @typescript-eslint/no-unused-vars
function pauseResume() {
if (state.paused) {
resume();
@ -76,7 +75,6 @@ export default defineComponent({
requestAnimationFrame(count);
}
// eslint-disable-next-line @typescript-eslint/no-unused-vars
function reset() {
state.startTime = null;
cancelAnimationFrame(state.rAF);
@ -91,23 +89,15 @@ export default defineComponent({
state.remaining = (state.localDuration as number) - progress;
if (useEasing) {
if (unref(getCountDown)) {
state.printVal =
state.localStartVal - easingFn(progress, 0, state.localStartVal - endVal, state.localDuration as number);
state.printVal = state.localStartVal - easingFn(progress, 0, state.localStartVal - endVal, state.localDuration as number);
} else {
state.printVal = easingFn(
progress,
state.localStartVal,
endVal - state.localStartVal,
state.localDuration as number
);
state.printVal = easingFn(progress, state.localStartVal, endVal - state.localStartVal, state.localDuration as number);
}
} else {
if (unref(getCountDown)) {
state.printVal =
state.localStartVal - (state.localStartVal - endVal) * (progress / (state.localDuration as number));
state.printVal = state.localStartVal - (state.localStartVal - endVal) * (progress / (state.localDuration as number));
} else {
state.printVal =
state.localStartVal + (endVal - state.localStartVal) * (progress / (state.localDuration as number));
state.printVal = state.localStartVal + (endVal - state.localStartVal) * (progress / (state.localDuration as number));
}
}
if (unref(getCountDown)) {

View File

@ -39,13 +39,7 @@ defineExpose({ hidePopover });
</div>
</template>
<div class="flex flex-wrap justify-center items-center text-center">
<el-image
v-if="cropperImg"
:preview-src-list="Array.of(cropperImg)"
:src="cropperImg"
class="cropper-img-preview"
fit="contain"
/>
<el-image v-if="cropperImg" :preview-src-list="Array.of(cropperImg)" :src="cropperImg" class="cropper-img-preview" fit="contain" />
<div v-if="infos" class="mt-1">
<p>{{ $t('image_size') }}{{ parseInt(infos.width) }} × {{ parseInt(infos.height) }}{{ $t('pixel') }}</p>
<p>{{ $t('file_size') }}{{ formatBytes(infos.size) }}{{ infos.size }} {{ $t('bytes') }}</p>

View File

@ -14,29 +14,13 @@ const router = useRouter();
<div class="flex justify-center items-center h-[640px]">
<noAccess />
<div class="ml-12">
<p
v-motion
:enter="{ opacity: 1, y: 0, transition: { delay: 80 } }"
:initial="{ opacity: 0, y: 100 }"
class="font-medium text-4xl mb-4 dark:text-white"
>
<p v-motion :enter="{ opacity: 1, y: 0, transition: { delay: 80 } }" :initial="{ opacity: 0, y: 100 }" class="font-medium text-4xl mb-4 dark:text-white">
403
</p>
<p
v-motion
:enter="{ opacity: 1, y: 0, transition: { delay: 120 } }"
:initial="{ opacity: 0, y: 100 }"
class="mb-4 text-gray-500"
>
<p v-motion :enter="{ opacity: 1, y: 0, transition: { delay: 120 } }" :initial="{ opacity: 0, y: 100 }" class="mb-4 text-gray-500">
{{ $t('sorryNoAccess') }}
</p>
<el-button
v-motion
:enter="{ opacity: 1, y: 0, transition: { delay: 160 } }"
:initial="{ opacity: 0, y: 100 }"
type="primary"
@click="router.push('/')"
>
<el-button v-motion :enter="{ opacity: 1, y: 0, transition: { delay: 160 } }" :initial="{ opacity: 0, y: 100 }" type="primary" @click="router.push('/')">
{{ $t('returnToHomepage') }}
</el-button>
</div>

View File

@ -14,20 +14,10 @@ const router = useRouter();
<div class="flex justify-center items-center h-[640px]">
<noExist />
<div class="ml-12">
<p
v-motion
:enter="{ opacity: 1, y: 0, transition: { delay: 80 } }"
:initial="{ opacity: 0, y: 100 }"
class="font-medium text-4xl mb-4 dark:text-white"
>
<p v-motion :enter="{ opacity: 1, y: 0, transition: { delay: 80 } }" :initial="{ opacity: 0, y: 100 }" class="font-medium text-4xl mb-4 dark:text-white">
404
</p>
<p
v-motion
:enter="{ opacity: 1, y: 0, transition: { delay: 120 } }"
:initial="{ opacity: 0, y: 100 }"
class="mb-4 text-gray-500"
>
<p v-motion :enter="{ opacity: 1, y: 0, transition: { delay: 120 } }" :initial="{ opacity: 0, y: 100 }" class="mb-4 text-gray-500">
{{ $t('sorryPageNotFound') }}
</p>
<el-button

View File

@ -14,29 +14,13 @@ const router = useRouter();
<div class="flex justify-center items-center h-[640px]">
<noServer />
<div class="ml-12">
<p
v-motion
:enter="{ opacity: 1, y: 0, transition: { delay: 80 } }"
:initial="{ opacity: 0, y: 100 }"
class="font-medium text-4xl mb-4 dark:text-white"
>
<p v-motion :enter="{ opacity: 1, y: 0, transition: { delay: 80 } }" :initial="{ opacity: 0, y: 100 }" class="font-medium text-4xl mb-4 dark:text-white">
500
</p>
<p
v-motion
:enter="{ opacity: 1, y: 0, transition: { delay: 120 } }"
:initial="{ opacity: 0, y: 100 }"
class="mb-4 text-gray-500"
>
<p v-motion :enter="{ opacity: 1, y: 0, transition: { delay: 120 } }" :initial="{ opacity: 0, y: 100 }" class="mb-4 text-gray-500">
{{ $t('sorryServerError') }}
</p>
<el-button
v-motion
:enter="{ opacity: 1, y: 0, transition: { delay: 160 } }"
:initial="{ opacity: 0, y: 100 }"
type="primary"
@click="router.push('/')"
>
<el-button v-motion :enter="{ opacity: 1, y: 0, transition: { delay: 160 } }" :initial="{ opacity: 0, y: 100 }" type="primary" @click="router.push('/')">
{{ $t('returnToHomepage') }}
</el-button>
</div>

View File

@ -101,20 +101,12 @@ function onMouseleave() {
@mouseenter.prevent="onMouseEnter(index)"
@mouseleave.prevent="onMouseleave"
>
<h4
:class="[
`animate__animated animate__${animateMap[index]?.loading ? animate + ' animate__infinite' : ''} `,
]"
>
<h4 :class="[`animate__animated animate__${animateMap[index]?.loading ? animate + ' animate__infinite' : ''} `]">
{{ animate }}
</h4>
</li>
</ul>
<el-empty
v-show="animatesList.length === 0"
:description="`${searchVal} ${$t('animationNotExist')}`"
:image-size="60"
/>
<el-empty v-show="animatesList.length === 0" :description="`${searchVal} ${$t('animationNotExist')}`" :image-size="60" />
</el-scrollbar>
</div>
</template>

View File

@ -101,15 +101,7 @@ export default defineComponent({
});
const iconClass = computed(() => {
return [
'p-[6px]',
'h-[30px]',
'w-[30px]',
'outline-none',
'rounded-[4px]',
'cursor-pointer',
'hover:bg-[rgba(0,0,0,0.06)]',
];
return ['p-[6px]', 'h-[30px]', 'w-[30px]', 'outline-none', 'rounded-[4px]', 'cursor-pointer', 'hover:bg-[rgba(0,0,0,0.06)]'];
});
const getWrapperStyle = computed((): CSSProperties => {
@ -249,11 +241,7 @@ export default defineComponent({
realTimeCroppered();
}}
/>
<Reload
class={iconClass.value}
v-tippy={{ content: '重置', placement: 'right-start' }}
onClick={() => handCropper('reset')}
/>
<Reload class={iconClass.value} v-tippy={{ content: '重置', placement: 'right-start' }} onClick={() => handCropper('reset')} />
<ArrowUp
class={iconClass.value}
v-tippy={{ content: '上移(可长按)', placement: 'left-start' }}
@ -277,26 +265,10 @@ export default defineComponent({
v-tippy={{ content: '右移(可长按)', placement: 'right-start' }}
v-longpress={[() => handCropper('move', [10, 0]), '0:100']}
/>
<ArrowH
class={iconClass.value}
v-tippy={{ content: '水平翻转', placement: 'left-start' }}
onClick={() => handCropper('scaleX', -1)}
/>
<ArrowV
class={iconClass.value}
v-tippy={{ content: '垂直翻转', placement: 'right-start' }}
onClick={() => handCropper('scaleY', -1)}
/>
<RotateLeft
class={iconClass.value}
v-tippy={{ content: '逆时针旋转', placement: 'left-start' }}
onClick={() => handCropper('rotate', -45)}
/>
<RotateRight
class={iconClass.value}
v-tippy={{ content: '顺时针旋转', placement: 'right-start' }}
onClick={() => handCropper('rotate', 45)}
/>
<ArrowH class={iconClass.value} v-tippy={{ content: '水平翻转', placement: 'left-start' }} onClick={() => handCropper('scaleX', -1)} />
<ArrowV class={iconClass.value} v-tippy={{ content: '垂直翻转', placement: 'right-start' }} onClick={() => handCropper('scaleY', -1)} />
<RotateLeft class={iconClass.value} v-tippy={{ content: '逆时针旋转', placement: 'left-start' }} onClick={() => handCropper('rotate', -45)} />
<RotateRight class={iconClass.value} v-tippy={{ content: '顺时针旋转', placement: 'right-start' }} onClick={() => handCropper('rotate', 45)} />
<SearchPlus
class={iconClass.value}
v-tippy={{ content: '放大(可长按)', placement: 'left-start' }}

View File

@ -107,19 +107,12 @@ function handleClose(options: DialogOptions, index: number, args = { command: 'c
}
"
>
<IconifyIconOffline
:icon="options?.fullscreen ? ExitFullscreen : fullscreen ? ExitFullscreen : Fullscreen"
class="pure-dialog-svg"
/>
<IconifyIconOffline :icon="options?.fullscreen ? ExitFullscreen : fullscreen ? ExitFullscreen : Fullscreen" class="pure-dialog-svg" />
</i>
</div>
<component :is="options?.headerRenderer({ close, titleId, titleClass })" v-else />
</template>
<component
:is="options.contentRenderer({ options, index })"
v-bind="options?.props"
@close="(args) => handleClose(options, index, args)"
/>
<component :is="options.contentRenderer({ options, index })" v-bind="options?.props" @close="(args) => handleClose(options, index, args)" />
<!-- footer -->
<template v-if="!options?.hideFooter" #footer>
<template v-if="options?.footerRenderer">

View File

@ -157,15 +157,7 @@ interface DialogOptions extends DialogProps {
* @description
* @see {@link https://element-plus.org/zh-CN/component/dialog.html#%E8%87%AA%E5%AE%9A%E4%B9%89%E5%A4%B4%E9%83%A8}
*/
headerRenderer?: ({
close,
titleId,
titleClass,
}: {
close: Function;
titleId: string;
titleClass: string;
}) => VNode | Component;
headerRenderer?: ({ close, titleId, titleClass }: { close: Function; titleId: string; titleClass: string }) => VNode | Component;
/** 自定义内容渲染器 */
contentRenderer?: ({ options, index }: { options: DialogOptions; index: number }) => VNode | Component;
/** 自定义按钮操作区的内容渲染器,会覆盖`footerButtons`以及默认的 `取消` 和 `确定` 按钮 */

View File

@ -98,13 +98,7 @@ onMounted(() => {
<el-button bg class="justify-end mr-2 ml-2" size="small" text type="danger" @click="onClear">清空</el-button>
</div>
</el-popover>
<el-link
:title="$t('systemMenuIcon.officialWebsite')"
:underline="false"
href="https://icon-sets.iconify.design/"
target="_blank"
type="primary"
>
<el-link :title="$t('systemMenuIcon.officialWebsite')" :underline="false" href="https://icon-sets.iconify.design/" target="_blank" type="primary">
{{ $t('systemMenuIcon.officialWebsite') }}
</el-link>
</div>

View File

@ -97,9 +97,7 @@ function onClear() {
watch(
() => pageList.value,
() =>
currentActiveType.value !== 'web' &&
(totalPage.value = copyIconList[currentActiveType.value].filter((i) => i.includes(filterValue.value)).length),
() => currentActiveType.value !== 'web' && (totalPage.value = copyIconList[currentActiveType.value].filter((i) => i.includes(filterValue.value)).length),
{ immediate: true }
);
watch(
@ -165,9 +163,7 @@ watch(
size="small"
@current-change="onCurrentChange"
/>
<el-button bg class="justify-end mr-2 ml-2" size="small" text type="danger" @click="onClear">
清空
</el-button>
<el-button bg class="justify-end mr-2 ml-2" size="small" text type="danger" @click="onClear">清空</el-button>
</div>
</el-tab-pane>
</el-tabs>

View File

@ -70,16 +70,7 @@ export default defineComponent({
});
const topClass = computed(() => {
return [
'flex',
'justify-between',
'pt-[3px]',
'px-[11px]',
'border-b-[1px]',
'border-solid',
'border-[#dcdfe6]',
'dark:border-[#303030]',
];
return ['flex', 'justify-between', 'pt-[3px]', 'px-[11px]', 'border-b-[1px]', 'border-solid', 'border-[#dcdfe6]', 'dark:border-[#303030]'];
});
function onReFresh() {
@ -100,9 +91,7 @@ export default defineComponent({
}
function reloadColumn() {
const curCheckedColumns = cloneDeep(dynamicColumns.value).filter((item) =>
checkedColumns.value.includes(item.title)
);
const curCheckedColumns = cloneDeep(dynamicColumns.value).filter((item) => checkedColumns.value.includes(item.title));
props.vxeTableRef.reloadColumn(curCheckedColumns);
}
@ -154,8 +143,7 @@ export default defineComponent({
const rowDrop = (event: { preventDefault: () => void }) => {
event.preventDefault();
nextTick(() => {
const wrapper: HTMLElement = (instance?.proxy?.$refs[`VxeGroupRef${unref(props.tableKey)}`] as any).$el
.firstElementChild;
const wrapper: HTMLElement = (instance?.proxy?.$refs[`VxeGroupRef${unref(props.tableKey)}`] as any).$el.firstElementChild;
Sortable.create(wrapper, {
animation: 300,
handle: '.drag-btn',
@ -205,13 +193,7 @@ export default defineComponent({
<>
<div
{...attrs}
class={[
'w-[99/100]',
'px-2',
'pb-2',
'bg-bg_color',
isFullscreen.value ? ['!w-full', '!h-full', 'z-[2002]', 'fixed', 'inset-0'] : 'mt-2',
]}
class={['w-[99/100]', 'px-2', 'pb-2', 'bg-bg_color', isFullscreen.value ? ['!w-full', '!h-full', 'z-[2002]', 'fixed', 'inset-0'] : 'mt-2']}
>
<div class="flex justify-between w-full h-[60px] p-4">
{slots?.title ? slots.title() : <p class="font-bold truncate">{props.title}</p>}
@ -241,13 +223,7 @@ export default defineComponent({
</el-dropdown>
<el-divider direction="vertical" />
<el-popover
v-slots={reference}
placement="bottom-start"
popper-style={{ padding: 0 }}
width="200"
trigger="click"
>
<el-popover v-slots={reference} placement="bottom-start" popper-style={{ padding: 0 }} width="200" trigger="click">
<div class={[topClass.value]}>
<el-checkbox
class="!-mr-1"
@ -273,17 +249,11 @@ export default defineComponent({
return (
<div class="flex items-center">
<DragIcon
class={[
'drag-btn w-[16px] mr-2',
isFixedColumn(item) ? '!cursor-no-drop' : '!cursor-grab',
]}
class={['drag-btn w-[16px] mr-2', isFixedColumn(item) ? '!cursor-no-drop' : '!cursor-grab']}
onMouseenter={(event: { preventDefault: () => void }) => rowDrop(event)}
/>
<el-checkbox key={index} label={item} value={item} onChange={reloadColumn}>
<span
title={transformI18n(item)}
class="inline-block w-[120px] truncate hover:text-text_color_primary"
>
<span title={transformI18n(item)} class="inline-block w-[120px] truncate hover:text-text_color_primary">
{transformI18n(item)}
</span>
</el-checkbox>

View File

@ -13,9 +13,7 @@
if (d && !e.__iconfont__svg__cssinject__) {
e.__iconfont__svg__cssinject__ = !0;
try {
document.write(
'<style>.svgfont {display: inline-block;width: 1em;height: 1em;fill: currentColor;vertical-align: -0.1em;font-size:16px;}</style>'
);
document.write('<style>.svgfont {display: inline-block;width: 1em;height: 1em;fill: currentColor;vertical-align: -0.1em;font-size:16px;}</style>');
} catch (e) {
console && console.log(e);
}

View File

@ -31,11 +31,7 @@ export default defineComponent({
const rightClass = ref(['splitter-pane splitter-paneR', props.splitSet?.split]);
const cursor = computed(() => {
return active.value
? props.splitSet?.split === 'vertical'
? { cursor: 'col-resize' }
: { cursor: 'row-resize' }
: { cursor: 'default' };
return active.value ? (props.splitSet?.split === 'vertical' ? { cursor: 'col-resize' } : { cursor: 'row-resize' }) : { cursor: 'default' };
});
const onClick = (): void => {
@ -75,8 +71,7 @@ export default defineComponent({
}
const currentPage = props.splitSet?.split === 'vertical' ? e.pageX : e.pageY;
const targetOffset =
props.splitSet?.split === 'vertical' ? e.currentTarget.offsetWidth : e.currentTarget.offsetHeight;
const targetOffset = props.splitSet?.split === 'vertical' ? e.currentTarget.offsetWidth : e.currentTarget.offsetHeight;
const percents = Math.floor(((currentPage - offset) / targetOffset) * 10000) / 100;
if (percents > props.splitSet?.minPercent && percents < 100 - props.splitSet?.minPercent) {
@ -91,12 +86,7 @@ export default defineComponent({
return () => (
<>
<div
class="vue-splitter-container clearfix"
style={unref(cursor)}
onMouseup={() => onMouseUp()}
onMousemove={() => onMouseMove(event)}
>
<div class="vue-splitter-container clearfix" style={unref(cursor)} onMouseup={() => onMouseUp()} onMousemove={() => onMouseMove(event)}>
<div class={unref(leftClass)} style={{ [unref(type)]: unref(percent) + '%' }}>
{ctx.slots.paneL()}
</div>

View File

@ -53,13 +53,7 @@ defineExpose({ ruleFormRef });
<div class="my-2">
<el-form ref="ruleFormRef" :model="form" :rules="rules">
<el-form-item :label="$t('adminUser_password')" prop="password">
<el-input
v-model="form.password!"
:placeholder="$t('adminUser_password')"
clearable
show-password
type="password"
/>
<el-input v-model="form.password!" :placeholder="$t('adminUser_password')" clearable show-password type="password" />
</el-form-item>
</el-form>

View File

@ -11,13 +11,5 @@ defineProps({
</script>
<template>
<el-image
:initial-index="index"
:preview-src-list="[image]"
:src="image"
class="w-[50px] h-[50px]"
fit="fill"
loading="lazy"
preview-teleported
/>
<el-image :initial-index="index" :preview-src-list="[image]" :src="image" class="w-[50px] h-[50px]" fit="fill" loading="lazy" preview-teleported />
</template>

View File

@ -44,11 +44,7 @@ onMounted(() => {
</div>
<h1 class="list-card-item_detail--name">{{ $t('user_details') }}</h1>
</div>
<el-tag
:color="userinfo.status ? '#F67676' : '#00a870'"
class="mx-1 list-card-item_detail--operation--tag"
effect="dark"
>
<el-tag :color="userinfo.status ? '#F67676' : '#00a870'" class="mx-1 list-card-item_detail--operation--tag" effect="dark">
{{ $t('user_status') }}{{ userinfo.status ? $t('disable') : $t('normal') }}
</el-tag>
</el-row>

View File

@ -87,9 +87,7 @@ const isIndeterminate = ref(false);
//
const dynamicColumns = ref(props.column);
//
const filterColumns = cloneDeep(props.column).filter((column) =>
isBoolean(column?.hide) ? !column.hide : !(isFunction(column?.hide) && column?.hide())
);
const filterColumns = cloneDeep(props.column).filter((column) => (isBoolean(column?.hide) ? !column.hide : !(isFunction(column?.hide) && column?.hide())));
//
const checkedColumns = ref(getKeyList(cloneDeep(filterColumns), 'label'));
const checkColumnList = ref(getKeyList(cloneDeep(dynamicColumns.value), 'label'));
@ -174,8 +172,7 @@ const onReset = async () => {
/** 列展示拖拽排序 */
const rowDrop = (event: any) => {
nextTick(() => {
const wrapper: HTMLElement = (instance?.proxy?.$refs[`GroupRef${unref(props.tableKey)}`] as any).$el
.firstElementChild;
const wrapper: HTMLElement = (instance?.proxy?.$refs[`GroupRef${unref(props.tableKey)}`] as any).$el.firstElementChild;
Sortable.create(wrapper, {
animation: 300,
handle: '.drag-btn',
@ -260,11 +257,7 @@ onMounted(() => {
</div>
<!-- 表格刷新按钮 -->
<RefreshIcon
v-tippy="rendTipProps('刷新')"
:class="`w-[16px] ${iconClass()}} ${loading ? 'animate-spin' : ''}`"
@click="onReFresh"
/>
<RefreshIcon v-tippy="rendTipProps('刷新')" :class="`w-[16px] ${iconClass()}} ${loading ? 'animate-spin' : ''}`" @click="onReFresh" />
<el-divider direction="vertical" />
<!-- 选择表格大小 -->
@ -275,10 +268,7 @@ onMounted(() => {
<el-dropdown-item :style="getDropdownItemStyle(size, 'large')" @click="handleTableSizeClick('large')">
{{ $t('style.larger') }}
</el-dropdown-item>
<el-dropdown-item
:style="getDropdownItemStyle(size, 'default')"
@click="handleTableSizeClick('default')"
>
<el-dropdown-item :style="getDropdownItemStyle(size, 'default')" @click="handleTableSizeClick('default')">
{{ t('style.default') }}
</el-dropdown-item>
<el-dropdown-item :style="getDropdownItemStyle(size, 'small')" @click="handleTableSizeClick('small')">
@ -296,13 +286,7 @@ onMounted(() => {
</template>
<div :class="topClass()">
<el-checkbox
v-model="checkAll"
:indeterminate="isIndeterminate"
class="!-mr-1"
label="列展示"
@change="handleCheckAllChange"
/>
<el-checkbox v-model="checkAll" :indeterminate="isIndeterminate" class="!-mr-1" label="列展示" @change="handleCheckAllChange" />
<el-button link type="primary" @click="onReset">
{{ t('buttons.rest') }}
</el-button>
@ -310,23 +294,11 @@ onMounted(() => {
<div class="pt-[6px] pl-[11px]">
<el-scrollbar max-height="36vh">
<el-checkbox-group
:ref="`GroupRef${unref(props.tableKey)}`"
:modelValue="checkedColumns"
@change="handleCheckedColumnsChange"
>
<el-checkbox-group :ref="`GroupRef${unref(props.tableKey)}`" :modelValue="checkedColumns" @change="handleCheckedColumnsChange">
<el-space :alignment="'flex-start'" :size="0" direction="vertical">
<div v-for="(item, index) in checkColumnList" :key="index" class="flex items-center">
<DragIcon
:class="`drag-btn w-[16px] mr-2 ${isFixedColumn(item) ? '!cursor-no-drop' : '!cursor-grab'}`"
@mouseenter.prevent="rowDrop"
/>
<el-checkbox
:key="index"
:label="item"
:value="item"
@change="handleCheckColumnListChange(item)"
>
<DragIcon :class="`drag-btn w-[16px] mr-2 ${isFixedColumn(item) ? '!cursor-no-drop' : '!cursor-grab'}`" @mouseenter.prevent="rowDrop" />
<el-checkbox :key="index" :label="item" :value="item" @change="handleCheckColumnListChange(item)">
<span :title="item" class="inline-block w-[120px] truncate hover:text-text_color_primary">
{{ item }}
</span>

View File

@ -70,16 +70,7 @@ export default defineComponent({
});
const topClass = computed(() => {
return [
'flex',
'justify-between',
'pt-[3px]',
'px-[11px]',
'border-b-[1px]',
'border-solid',
'border-[#dcdfe6]',
'dark:border-[#303030]',
];
return ['flex', 'justify-between', 'pt-[3px]', 'px-[11px]', 'border-b-[1px]', 'border-solid', 'border-[#dcdfe6]', 'dark:border-[#303030]'];
});
function onReFresh() {
@ -153,8 +144,7 @@ export default defineComponent({
const rowDrop = (event: { preventDefault: () => void }) => {
event.preventDefault();
nextTick(() => {
const wrapper: HTMLElement = (instance?.proxy?.$refs[`GroupRef${unref(props.tableKey)}`] as any).$el
.firstElementChild;
const wrapper: HTMLElement = (instance?.proxy?.$refs[`GroupRef${unref(props.tableKey)}`] as any).$el.firstElementChild;
Sortable.create(wrapper, {
animation: 300,
handle: '.drag-btn',
@ -200,13 +190,7 @@ export default defineComponent({
<>
<div
{...attrs}
class={[
'w-[99/100]',
'px-2',
'pb-2',
'bg-bg_color',
isFullscreen.value ? ['!w-full', '!h-full', 'z-[2002]', 'fixed', 'inset-0'] : 'mt-2',
]}
class={['w-[99/100]', 'px-2', 'pb-2', 'bg-bg_color', isFullscreen.value ? ['!w-full', '!h-full', 'z-[2002]', 'fixed', 'inset-0'] : 'mt-2']}
>
<div class="flex justify-between w-full h-[50px] p-3">
{slots?.title ? slots.title() : <p class="font-bold truncate">{props.title}</p>}
@ -234,13 +218,7 @@ export default defineComponent({
</el-dropdown>
<el-divider direction="vertical" />
<el-popover
v-slots={reference}
placement="bottom-start"
popper-style={{ padding: 0 }}
width="200"
trigger="click"
>
<el-popover v-slots={reference} placement="bottom-start" popper-style={{ padding: 0 }} width="200" trigger="click">
<div class={[topClass.value]}>
<el-checkbox
class="!-mr-1"
@ -266,22 +244,11 @@ export default defineComponent({
return (
<div class="flex items-center">
<DragIcon
class={[
'drag-btn w-[16px] mr-2',
isFixedColumn(item) ? '!cursor-no-drop' : '!cursor-grab',
]}
class={['drag-btn w-[16px] mr-2', isFixedColumn(item) ? '!cursor-no-drop' : '!cursor-grab']}
onMouseenter={(event: { preventDefault: () => void }) => rowDrop(event)}
/>
<el-checkbox
key={index}
label={item}
value={item}
onChange={(value) => handleCheckColumnListChange(value, item)}
>
<span
title={item}
class="inline-block w-[120px] truncate hover:text-text_color_primary"
>
<el-checkbox key={index} label={item} value={item} onChange={(value) => handleCheckColumnListChange(value, item)}>
<span title={item} class="inline-block w-[120px] truncate hover:text-text_color_primary">
{item}
</span>
</el-checkbox>

View File

@ -10,12 +10,10 @@ export const cellHeaderStyle = () => ({
});
// * icon 样式
export const iconClass = () =>
'text-black dark:text-white duration-100 hover:!text-primary cursor-pointer outline-none ';
export const iconClass = () => 'text-black dark:text-white duration-100 hover:!text-primary cursor-pointer outline-none ';
// * 顶部样式
export const topClass = () =>
'flex justify-between pt-[3px] px-[11px] border-b-[1px] border-solid border-[#dcdfe6] dark:border-[#303030]';
export const topClass = () => 'flex justify-between pt-[3px] px-[11px] border-b-[1px] border-solid border-[#dcdfe6] dark:border-[#303030]';
/**
* *

View File

@ -1,12 +1,5 @@
<template>
<el-upload
:auto-upload="true"
:before-upload="beforeUpload"
:http-request="onUpload"
:show-file-list="false"
accept="image/*"
drag
>
<el-upload :auto-upload="true" :before-upload="beforeUpload" :http-request="onUpload" :show-file-list="false" accept="image/*" drag>
<el-image v-if="imageSrc" :src="imageSrc" fit="cover" lazy>
<template #placeholder>
<ImageLoading />

View File

@ -55,9 +55,7 @@ export const longpress: Directive = {
useEventListener(el, 'pointerup', clear);
useEventListener(el, 'pointerleave', clear);
} else {
throw new Error(
'[Directive: longpress]: need callback and callback must be a function! Like v-longpress="callback"'
);
throw new Error('[Directive: longpress]: need callback and callback must be a function! Like v-longpress="callback"');
}
},
};

View File

@ -40,13 +40,7 @@ export const isReadStatus = [
/** 分页默认数组个数 */
export const pageSizes: number[] = [15, 30, 50, 100, 150];
export const tableSelectButtonClass = computed(() => [
'!h-[20px]',
'reset-margin',
'!text-gray-500',
'dark:!text-white',
'dark:hover:!text-primary',
]);
export const tableSelectButtonClass = computed(() => ['!h-[20px]', 'reset-margin', '!text-gray-500', 'dark:!text-white', 'dark:hover:!text-primary']);
export const UserAvatar =
'https://thirdwx.qlogo.cn/mmopen/vi_32/DYAIOgq83eoj0hHXhgJNOTSOFsS4uZs8x1ConecaVOB8eIl115xmJZcT4oCicvia7wMEufibKtTLqiaJeanU2Lpg3w/132';

View File

@ -84,12 +84,4 @@ const frameLoadingOptions: Array<OptionsType> = [
},
];
export {
menuTypeOptions,
fixedTagOptions,
showLinkOptions,
keepAliveOptions,
hiddenTagOptions,
showParentOptions,
frameLoadingOptions,
};
export { menuTypeOptions, fixedTagOptions, showLinkOptions, keepAliveOptions, hiddenTagOptions, showParentOptions, frameLoadingOptions };

View File

@ -52,9 +52,7 @@ const getSectionStyle = computed(() => {
!hideTabs.value && layout ? (showModel.value == 'chrome' ? 'padding-top: 85px;' : 'padding-top: 81px;') : '',
hideTabs.value && !layout.value ? 'padding-top: 48px;' : '',
!hideTabs.value && !layout.value ? (showModel.value == 'chrome' ? 'padding-top: 85px;' : 'padding-top: 81px;') : '',
props.fixedHeader
? ''
: `padding-top: 0;${hideTabs.value ? 'min-height: calc(100vh - 48px);' : 'min-height: calc(100vh - 86px);'}`,
props.fixedHeader ? '' : `padding-top: 0;${hideTabs.value ? 'min-height: calc(100vh - 48px);' : 'min-height: calc(100vh - 86px);'}`,
];
});

View File

@ -16,19 +16,7 @@ import { userI18nTypeStore } from '@/store/i18n/i18nType';
import { onMounted } from 'vue';
import DropdownMenu from '@/layout/components/lay-navbar/dropdown-menu.vue';
const {
layout,
device,
logout,
onPanel,
pureApp,
username,
userAvatar,
avatarsStyle,
toggleSideBar,
getDropdownItemStyle,
getDropdownItemClass,
} = useNav();
const { layout, device, logout, onPanel, pureApp, username, userAvatar, avatarsStyle, toggleSideBar, getDropdownItemStyle, getDropdownItemClass } = useNav();
const { locale, translation } = useTranslationLang();
@ -41,12 +29,7 @@ onMounted(() => {
<template>
<div class="navbar bg-[#fff] shadow-sm shadow-[rgba(0,21,41,0.08)]">
<LaySidebarTopCollapse
v-if="device === 'mobile'"
:is-active="pureApp.sidebar.opened"
class="hamburger-container"
@toggleClick="toggleSideBar"
/>
<LaySidebarTopCollapse v-if="device === 'mobile'" :is-active="pureApp.sidebar.opened" class="hamburger-container" @toggleClick="toggleSideBar" />
<LaySidebarBreadCrumb v-if="layout !== 'mix' && device !== 'mobile'" class="breadcrumb-container" />

View File

@ -22,9 +22,7 @@ const router = useRouter();
function hoverTitle() {
nextTick(() => {
titleRef.value?.scrollWidth > titleRef.value?.clientWidth
? (titleTooltip.value = true)
: (titleTooltip.value = false);
titleRef.value?.scrollWidth > titleRef.value?.clientWidth ? (titleTooltip.value = true) : (titleTooltip.value = false);
});
}
@ -50,10 +48,7 @@ function goMessageDetail(message: ListItem) {
</script>
<template>
<div
class="notice-container border-b-[1px] border-solid border-[#f0f0f0] dark:border-[#303030]"
@click="goMessageDetail(noticeItem)"
>
<div class="notice-container border-b-[1px] border-solid border-[#f0f0f0] dark:border-[#303030]" @click="goMessageDetail(noticeItem)">
<!--<el-avatar v-if="noticeItem.cover" :size="30" :src="noticeItem.cover" class="notice-container-avatar" />-->
<img v-if="noticeItem.cover" :src="noticeItem.cover" alt="" class="notice-container-avatar" />
<div class="notice-container-text">
@ -82,11 +77,7 @@ function goMessageDetail(message: ListItem) {
placement="top-start"
popper-class="notice-title-popper"
>
<div
ref="descriptionRef"
class="notice-text-description"
@mouseover="hoverDescription($event, noticeItem.description)"
>
<div ref="descriptionRef" class="notice-text-description" @mouseover="hoverDescription($event, noticeItem.description)">
{{ noticeItem.description }}
</div>
</el-tooltip>

View File

@ -29,12 +29,7 @@ onMounted(() => {
</span>
<template #dropdown>
<el-dropdown-menu>
<el-tabs
v-model="activeKey"
:stretch="true"
:style="{ width: notices.length === 0 ? '200px' : '330px' }"
class="dropdown-tabs"
>
<el-tabs v-model="activeKey" :stretch="true" :style="{ width: notices.length === 0 ? '200px' : '330px' }" class="dropdown-tabs">
<el-empty v-if="notices.length === 0" :description="t('status.pureNoMessage')" :image-size="60" />
<span v-else>
<template v-for="item in notices" :key="item.key">

View File

@ -62,13 +62,7 @@ onBeforeUnmount(() => {
}"
:class="iconClass"
>
<IconifyIconOffline
:icon="CloseIcon"
class="dark:text-white"
height="18px"
width="18px"
@click="show = !show"
/>
<IconifyIconOffline :icon="CloseIcon" class="dark:text-white" height="18px" width="18px" @click="show = !show" />
</span>
</div>
<el-scrollbar>

View File

@ -32,17 +32,8 @@ function handleDelete(item) {
<span class="history-item-title">
{{ $t(item.meta?.title) }}
</span>
<IconifyIconOffline
v-show="item.type === 'history'"
:icon="StarIcon"
class="w-[18px] h-[18px] mr-2 hover:text-[#d7d5d4]"
@click.stop="handleCollect(item)"
/>
<IconifyIconOffline
:icon="CloseIcon"
class="w-[18px] h-[18px] hover:text-[#d7d5d4] cursor-pointer"
@click.stop="handleDelete(item)"
/>
<IconifyIconOffline v-show="item.type === 'history'" :icon="StarIcon" class="w-[18px] h-[18px] mr-2 hover:text-[#d7d5d4]" @click.stop="handleCollect(item)" />
<IconifyIconOffline :icon="CloseIcon" class="w-[18px] h-[18px] hover:text-[#d7d5d4] cursor-pointer" @click.stop="handleDelete(item)" />
</template>
<style lang="scss" scoped>

View File

@ -110,8 +110,7 @@ function search() {
resultOptions.value = flatMenusData.filter((menu) =>
keyword.value
? $t(menu.meta?.title).toLocaleLowerCase().includes(keyword.value.toLocaleLowerCase().trim()) ||
(locale.value === 'zh' &&
!isAllEmpty(match($t(menu.meta?.title).toLocaleLowerCase(), keyword.value.toLocaleLowerCase().trim())))
(locale.value === 'zh' && !isAllEmpty(match($t(menu.meta?.title).toLocaleLowerCase(), keyword.value.toLocaleLowerCase().trim())))
: false
);
activePath.value = resultOptions.value?.length > 0 ? resultOptions.value[0].path : '';
@ -270,14 +269,7 @@ onKeyStroke('ArrowDown', handleDown);
@closed="inputRef.blur()"
@opened="inputRef.focus()"
>
<el-input
ref="inputRef"
v-model="keyword"
:placeholder="t('search.purePlaceholder')"
clearable
size="large"
@input="handleSearch"
>
<el-input ref="inputRef" v-model="keyword" :placeholder="t('search.purePlaceholder')" clearable size="large" @input="handleSearch">
<template #prefix>
<IconifyIconOffline :icon="SearchIcon" class="text-primary w-[24px] h-[24px]" />
</template>
@ -295,13 +287,7 @@ onKeyStroke('ArrowDown', handleDown);
@delete="handleDelete"
@drag="handleDrag"
/>
<SearchResult
v-if="showSearchResult"
ref="resultRef"
v-model:value="activePath"
:options="resultOptions"
@click="handleEnter"
/>
<SearchResult v-if="showSearchResult" ref="resultRef" v-model:value="activePath" :options="resultOptions" @click="handleEnter" />
</el-scrollbar>
</div>
<template #footer>

View File

@ -27,8 +27,7 @@ const mixRef = ref();
const verticalRef = ref();
const horizontalRef = ref();
const { dataTheme, overallStyle, layoutTheme, themeColors, toggleClass, dataThemeChange, setLayoutThemeColor } =
useDataThemeChange();
const { dataTheme, overallStyle, layoutTheme, themeColors, toggleClass, dataThemeChange, setLayoutThemeColor } = useDataThemeChange();
/* body添加layout属性作用于src/style/sidebar.scss */
if (unref(layoutTheme)) {
@ -366,13 +365,7 @@ onUnmounted(() => removeMatchMedia);
<span v-if="useAppStoreHook().getViewportWidth > 1280">
<p :class="['mt-5', pClass]">{{ t('panel.pureStretch') }}</p>
<Segmented
:modelValue="isNumber(settings.stretch) ? 1 : 0"
:options="stretchTypeOptions"
class="mb-2 select-none"
resize
@change="stretchTypeChange"
/>
<Segmented :modelValue="isNumber(settings.stretch) ? 1 : 0" :options="stretchTypeOptions" class="mb-2 select-none" resize @change="stretchTypeChange" />
<el-input-number
v-if="isNumber(settings.stretch)"
v-model="settings.stretch as number"
@ -387,11 +380,7 @@ onUnmounted(() => removeMatchMedia);
class="bg-transparent flex-c w-full h-20 rounded-md border border-[var(--pure-border-color)]"
@click="setStretch(!settings.stretch)"
>
<div
:class="[settings.stretch ? 'w-[24%]' : 'w-[50%]']"
class="flex-bc transition-all duration-300"
style="color: var(--el-color-primary)"
>
<div :class="[settings.stretch ? 'w-[24%]' : 'w-[50%]']" class="flex-bc transition-all duration-300" style="color: var(--el-color-primary)">
<IconifyIconOffline :icon="settings.stretch ? RightArrow : LeftArrow" height="20" />
<div class="flex-grow border-b border-dashed" style="border-color: var(--el-color-primary)" />
<IconifyIconOffline :icon="settings.stretch ? LeftArrow : RightArrow" height="20" />
@ -400,13 +389,7 @@ onUnmounted(() => removeMatchMedia);
</span>
<p :class="['mt-4', pClass]">{{ t('panel.pureTagsStyle') }}</p>
<Segmented
:modelValue="markValue === 'smart' ? 0 : markValue === 'card' ? 1 : 2"
:options="markOptions"
class="select-none"
resize
@change="onChange"
/>
<Segmented :modelValue="markValue === 'smart' ? 0 : markValue === 'card' ? 1 : 2" :options="markOptions" class="select-none" resize @change="onChange" />
<p class="mt-5 font-medium text-sm dark:text-white">
{{ t('panel.pureInterfaceDisplay') }}

View File

@ -18,23 +18,10 @@ import Check from '@iconify-icons/ep/check';
import { $t } from '@/plugins/i18n';
const menuRef = ref();
const showLogo = ref(
storageLocal().getItem<StorageConfigs>(`${responsiveStorageNameSpace()}configure`)?.showLogo ?? true
);
const showLogo = ref(storageLocal().getItem<StorageConfigs>(`${responsiveStorageNameSpace()}configure`)?.showLogo ?? true);
const { t, route, locale, translationCh, translationEn } = useTranslationLang(menuRef);
const {
title,
logout,
onPanel,
getLogo,
username,
userAvatar,
backTopMenu,
avatarsStyle,
getDropdownItemStyle,
getDropdownItemClass,
} = useNav();
const { title, logout, onPanel, getLogo, username, userAvatar, backTopMenu, avatarsStyle, getDropdownItemStyle, getDropdownItemClass } = useNav();
const defaultActive = computed(() => (!isAllEmpty(route.meta?.activePath) ? route.meta.activePath : route.path));
@ -55,19 +42,8 @@ onMounted(() => {
<img :src="getLogo()" alt="logo" />
<span>{{ title }}</span>
</div>
<el-menu
ref="menuRef"
:default-active="defaultActive"
class="horizontal-header-menu"
mode="horizontal"
popper-class="pure-scrollbar"
>
<LaySidebarItem
v-for="route in usePermissionStoreHook().wholeMenus"
:key="route.path"
:base-path="route.path"
:item="route"
/>
<el-menu ref="menuRef" :default-active="defaultActive" class="horizontal-header-menu" mode="horizontal" popper-class="pure-scrollbar">
<LaySidebarItem v-for="route in usePermissionStoreHook().wholeMenus" :key="route.path" :base-path="route.path" :item="route" />
</el-menu>
<div class="horizontal-header-right">
<!-- 菜单搜索 -->

View File

@ -22,26 +22,13 @@ const menuRef = ref();
const defaultActive = ref(null);
const { t } = useI18n();
const { route, locale, translationCh, translationEn } = useTranslationLang(menuRef);
const {
device,
logout,
onPanel,
resolvePath,
username,
userAvatar,
getDivStyle,
avatarsStyle,
getDropdownItemStyle,
getDropdownItemClass,
} = useNav();
const { device, logout, onPanel, resolvePath, username, userAvatar, getDivStyle, avatarsStyle, getDropdownItemStyle, getDropdownItemClass } = useNav();
function getDefaultActive(routePath) {
const wholeMenus = usePermissionStoreHook().wholeMenus;
/** 当前路由的父级路径 */
const parentRoutes = getParentPaths(routePath, wholeMenus)[0];
defaultActive.value = !isAllEmpty(route.meta?.activePath)
? route.meta.activePath
: findRouteByPath(parentRoutes, wholeMenus)?.children[0]?.path;
defaultActive.value = !isAllEmpty(route.meta?.activePath) ? route.meta.activePath : findRouteByPath(parentRoutes, wholeMenus)?.children[0]?.path;
}
onMounted(() => {
@ -61,24 +48,9 @@ watch(
</script>
<template>
<div
v-if="device !== 'mobile'"
v-loading="usePermissionStoreHook().wholeMenus.length === 0"
class="horizontal-header"
>
<el-menu
ref="menuRef"
:default-active="defaultActive"
class="horizontal-header-menu"
mode="horizontal"
popper-class="pure-scrollbar"
router
>
<el-menu-item
v-for="route in usePermissionStoreHook().wholeMenus"
:key="route.path"
:index="resolvePath(route) || route.redirect"
>
<div v-if="device !== 'mobile'" v-loading="usePermissionStoreHook().wholeMenus.length === 0" class="horizontal-header">
<el-menu ref="menuRef" :default-active="defaultActive" class="horizontal-header-menu" mode="horizontal" popper-class="pure-scrollbar" router>
<el-menu-item v-for="route in usePermissionStoreHook().wholeMenus" :key="route.path" :index="resolvePath(route) || route.redirect">
<template #title>
<div v-if="toRaw(route.meta.icon)" :class="['sub-menu-icon', route.meta.icon]">
<component :is="useRenderIcon(route.meta && toRaw(route.meta.icon))" />

View File

@ -14,18 +14,14 @@ import LaySidebarCenterCollapse from '../lay-sidebar/components/SidebarCenterCol
const route = useRoute();
const isShow = ref(false);
const showLogo = ref(
storageLocal().getItem<StorageConfigs>(`${responsiveStorageNameSpace()}configure`)?.showLogo ?? true
);
const showLogo = ref(storageLocal().getItem<StorageConfigs>(`${responsiveStorageNameSpace()}configure`)?.showLogo ?? true);
const { device, pureApp, isCollapse, tooltipEffect, menuSelect, toggleSideBar } = useNav();
const subMenuData = ref([]);
const menuData = computed(() => {
return pureApp.layout === 'mix' && device.value !== 'mobile'
? subMenuData.value
: usePermissionStoreHook().wholeMenus;
return pureApp.layout === 'mix' && device.value !== 'mobile' ? subMenuData.value : usePermissionStoreHook().wholeMenus;
});
const loading = computed(() => (pureApp.layout === 'mix' ? false : menuData.value.length === 0 ? true : false));
@ -86,25 +82,11 @@ onBeforeUnmount(() => {
popper-class="pure-scrollbar"
unique-opened
>
<LaySidebarItem
v-for="routes in menuData"
:key="routes.path"
:base-path="routes.path"
:item="routes"
class="outer-most select-none"
/>
<LaySidebarItem v-for="routes in menuData" :key="routes.path" :base-path="routes.path" :item="routes" class="outer-most select-none" />
</el-menu>
</el-scrollbar>
<LaySidebarCenterCollapse
v-if="device !== 'mobile' && (isShow || isCollapse)"
:is-active="pureApp.sidebar.opened"
@toggleClick="toggleSideBar"
/>
<LaySidebarLeftCollapse
v-if="device !== 'mobile'"
:is-active="pureApp.sidebar.opened"
@toggleClick="toggleSideBar"
/>
<LaySidebarCenterCollapse v-if="device !== 'mobile' && (isShow || isCollapse)" :is-active="pureApp.sidebar.opened" @toggleClick="toggleSideBar" />
<LaySidebarLeftCollapse v-if="device !== 'mobile'" :is-active="pureApp.sidebar.opened" @toggleClick="toggleSideBar" />
</div>
</template>

View File

@ -5,12 +5,7 @@ import { useNav } from '@/layout/hooks/useNav';
const screenIcon = ref();
const { toggle, isFullscreen, Fullscreen, ExitFullscreen } = useNav();
isFullscreen.value = !!(
document.fullscreenElement ||
document.webkitFullscreenElement ||
document.mozFullScreenElement ||
document.msFullscreenElement
);
isFullscreen.value = !!(document.fullscreenElement || document.webkitFullscreenElement || document.mozFullScreenElement || document.msFullscreenElement);
watch(
isFullscreen,

View File

@ -94,16 +94,8 @@ function resolvePath(routePath) {
</script>
<template>
<SidebarLinkItem
v-if="hasOneShowingChild(item.children, item) && (!onlyOneChild.children || onlyOneChild.noShowingChildren)"
:to="item"
>
<el-menu-item
:class="{ 'submenu-title-noDropdown': !isNest }"
:index="resolvePath(onlyOneChild.path)"
:style="getNoDropdownStyle"
v-bind="attrs"
>
<SidebarLinkItem v-if="hasOneShowingChild(item.children, item) && (!onlyOneChild.children || onlyOneChild.noShowingChildren)" :to="item">
<el-menu-item :class="{ 'submenu-title-noDropdown': !isNest }" :index="resolvePath(onlyOneChild.path)" :style="getNoDropdownStyle" v-bind="attrs">
<div v-if="toRaw(item.meta.icon)" :style="getSubMenuIconStyle" class="sub-menu-icon">
<component :is="useRenderIcon(toRaw(onlyOneChild.meta.icon) || (item.meta && toRaw(item.meta.icon)))" />
</div>
@ -160,13 +152,6 @@ function resolvePath(routePath) {
<SidebarExtraIcon v-if="!isCollapse" :extraIcon="item.meta.extraIcon" />
</template>
<sidebar-item
v-for="child in item.children"
:key="child.path"
:base-path="resolvePath(child.path)"
:is-nest="true"
:item="child"
class="nest-menu"
/>
<sidebar-item v-for="child in item.children" :key="child.path" :base-path="resolvePath(child.path)" :is-nest="true" :item="child" class="nest-menu" />
</el-sub-menu>
</template>

View File

@ -12,13 +12,7 @@ const { title, getLogo } = useNav();
<template>
<div :class="{ collapses: collapse }" class="sidebar-logo-container">
<transition name="sidebarLogoFade">
<router-link
v-if="collapse"
key="collapse"
:title="title"
:to="getTopMenu()?.path ?? '/'"
class="sidebar-logo-link"
>
<router-link v-if="collapse" key="collapse" :title="title" :to="getTopMenu()?.path ?? '/'" class="sidebar-logo-link">
<img :src="getLogo()" alt="logo" />
<span class="sidebar-title">{{ title }}</span>
</router-link>

View File

@ -23,14 +23,7 @@ const toggleClick = () => {
</script>
<template>
<div
class="px-3 mr-1 navbar-bg-hover"
:title="isActive ? t('buttons.pureClickCollapse') : t('buttons.pureClickExpand')"
@click="toggleClick"
>
<IconifyIconOffline
:icon="isActive ? MenuFold : MenuUnfold"
class="inline-block align-middle hover:text-primary dark:hover:!text-white"
/>
<div class="px-3 mr-1 navbar-bg-hover" :title="isActive ? t('buttons.pureClickCollapse') : t('buttons.pureClickExpand')" @click="toggleClick">
<IconifyIconOffline :icon="isActive ? MenuFold : MenuUnfold" class="inline-block align-middle hover:text-primary dark:hover:!text-white" />
</div>
</template>

View File

@ -91,10 +91,7 @@ const moveToView = async (index: number): Promise<void> => {
} else if (tabItemElOffsetLeft < -translateX.value) {
//
translateX.value = -tabItemElOffsetLeft + tabNavPadding;
} else if (
tabItemElOffsetLeft > -translateX.value &&
tabItemElOffsetLeft + tabItemOffsetWidth < -translateX.value + scrollbarDomWidth
) {
} else if (tabItemElOffsetLeft > -translateX.value && tabItemElOffsetLeft + tabItemOffsetWidth < -translateX.value + scrollbarDomWidth) {
//
translateX.value = Math.min(0, scrollbarDomWidth - tabItemOffsetWidth - tabItemElOffsetLeft - tabNavPadding);
} else {
@ -204,10 +201,7 @@ function deleteDynamicTag(obj: any, current: any, tag?: string) {
const spliceRoute = (startIndex?: number, length?: number, other?: boolean): void => {
if (other) {
useMultiTagsStoreHook().handleTags(
'equal',
[VITE_HIDE_HOME === 'false' ? fixedTags : toRaw(getTopMenu()), obj].flat()
);
useMultiTagsStoreHook().handleTags('equal', [VITE_HIDE_HOME === 'false' ? fixedTags : toRaw(getTopMenu()), obj].flat());
} else {
useMultiTagsStoreHook().handleTags('splice', '', {
startIndex,
@ -525,23 +519,13 @@ onBeforeUnmount(() => {
<span v-show="isShowArrow" class="arrow-left">
<IconifyIconOffline :icon="ArrowLeftSLine" @click="handleScroll(200)" />
</span>
<div
ref="scrollbarDom"
:class="showModel === 'chrome' && 'chrome-scroll-container'"
class="scroll-container"
@wheel.prevent="handleWheel"
>
<div ref="scrollbarDom" :class="showModel === 'chrome' && 'chrome-scroll-container'" class="scroll-container" @wheel.prevent="handleWheel">
<div ref="tabDom" :style="getTabStyle" class="tab select-none">
<div
v-for="(item, index) in multiTags"
:key="index"
:ref="'dynamic' + index"
:class="[
'scroll-item is-closable',
linkIsActive(item),
showModel === 'chrome' && 'chrome-item',
isFixedTag(item) && 'fixed-tag',
]"
:class="['scroll-item is-closable', linkIsActive(item), showModel === 'chrome' && 'chrome-item', isFixedTag(item) && 'fixed-tag']"
@click="tagOnClick(item)"
@contextmenu.prevent="openMenu(item, $event)"
@mouseenter.prevent="onMouseenter(index)"
@ -596,13 +580,7 @@ onBeforeUnmount(() => {
</span>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item
v-for="(item, key) in tagsViews"
:key="key"
:command="{ key, item }"
:disabled="item.disabled"
:divided="item.divided"
>
<el-dropdown-item v-for="(item, key) in tagsViews" :key="key" :command="{ key, item }" :disabled="item.disabled" :divided="item.divided">
<IconifyIconOffline :icon="item.icon" />
{{ item.text }}
</el-dropdown-item>

View File

@ -71,10 +71,7 @@ export function useDataThemeChange() {
}
function setPropertyPrimary(mode: string, i: number, color: string) {
document.documentElement.style.setProperty(
`--el-color-primary-${mode}-${i}`,
dataTheme.value ? darken(color, i / 10) : lighten(color, i / 10)
);
document.documentElement.style.setProperty(`--el-color-primary-${mode}-${i}`, dataTheme.value ? darken(color, i / 10) : lighten(color, i / 10));
}
/** 设置 `element-plus` 主题色 */

View File

@ -31,12 +31,9 @@ export function useTags() {
const isScrolling = ref(false);
/** 显示模式,默认灵动模式 */
const showModel = ref(
storageLocal().getItem<StorageConfigs>(`${responsiveStorageNameSpace()}configure`)?.showModel || 'smart'
);
const showModel = ref(storageLocal().getItem<StorageConfigs>(`${responsiveStorageNameSpace()}configure`)?.showModel || 'smart');
/** 是否隐藏标签页,默认显示 */
const showTags =
ref(storageLocal().getItem<StorageConfigs>(`${responsiveStorageNameSpace()}configure`).hideTabs) ?? ref('false');
const showTags = ref(storageLocal().getItem<StorageConfigs>(`${responsiveStorageNameSpace()}configure`).hideTabs) ?? ref('false');
const multiTags: any = computed(() => {
return useMultiTagsStoreHook().multiTags;
});

View File

@ -131,9 +131,7 @@ const LayHeader = defineComponent({
},
{
default: () => [
!pureSetting.hiddenSideBar && (layout.value.includes('vertical') || layout.value.includes('mix'))
? h(LayNavbar)
: null,
!pureSetting.hiddenSideBar && (layout.value.includes('vertical') || layout.value.includes('mix')) ? h(LayNavbar) : null,
!pureSetting.hiddenSideBar && layout.value.includes('horizontal') ? h(NavHorizontal) : null,
h(LayTag),
],
@ -145,11 +143,7 @@ const LayHeader = defineComponent({
<template>
<div ref="appWrapperRef" :class="['app-wrapper', set.classes]">
<div
v-show="set.device === 'mobile' && set.sidebar.opened && layout.includes('vertical')"
class="app-mask"
@click="useAppStoreHook().toggleSideBar()"
/>
<div v-show="set.device === 'mobile' && set.sidebar.opened && layout.includes('vertical')" class="app-mask" @click="useAppStoreHook().toggleSideBar()" />
<NavVertical v-show="!pureSetting.hiddenSideBar && (layout.includes('vertical') || layout.includes('mix'))" />
<div :class="['main-container', pureSetting.hiddenSideBar ? 'main-hidden' : '']">
<div v-if="set.fixedHeader">

View File

@ -38,9 +38,7 @@ Object.keys(modules).forEach((key) => {
});
/** 导出处理后的静态路由(三级及以上的路由全部拍成二级) */
export const constantRoutes: Array<RouteRecordRaw> = formatTwoStageRoutes(
formatFlatteningRoutes(buildHierarchyTree(ascending(routes.flat(Infinity))))
);
export const constantRoutes: Array<RouteRecordRaw> = formatTwoStageRoutes(formatFlatteningRoutes(buildHierarchyTree(ascending(routes.flat(Infinity)))));
/** 用于渲染菜单,保持原始层级 */
export const constantMenus: Array<RouteComponent> = ascending(routes.flat(Infinity)).concat(...remainingRouter);
@ -75,9 +73,7 @@ export function resetRouter() {
const { name, meta } = route;
if (name && router.hasRoute(name) && meta?.backstage) {
router.removeRoute(name);
router.options.routes = formatTwoStageRoutes(
formatFlatteningRoutes(buildHierarchyTree(ascending(routes.flat(Infinity))))
);
router.options.routes = formatTwoStageRoutes(formatFlatteningRoutes(buildHierarchyTree(ascending(routes.flat(Infinity)))));
}
});
usePermissionStoreHook().clearAllCachePage();

View File

@ -1,10 +1,4 @@
import {
createWebHashHistory,
createWebHistory,
type RouteComponent,
type RouteRecordRaw,
type RouterHistory,
} from 'vue-router';
import { createWebHashHistory, createWebHistory, type RouteComponent, type RouteRecordRaw, type RouterHistory } from 'vue-router';
import { router } from './index';
import { isProxy, toRaw } from 'vue';
import { useTimeoutFn } from '@vueuse/core';
@ -140,10 +134,7 @@ function handleAsyncRoutes(routeList) {
usePermissionStoreHook().handleWholeMenus(routeList);
}
if (!useMultiTagsStoreHook().getMultiTagsCache) {
useMultiTagsStoreHook().handleTags('equal', [
...routerArrays,
...usePermissionStoreHook().flatteningRoutes.filter((v) => v?.meta?.fixedTag),
]);
useMultiTagsStoreHook().handleTags('equal', [...routerArrays, ...usePermissionStoreHook().flatteningRoutes.filter((v) => v?.meta?.fixedTag)]);
}
addPathMatch();
}

View File

@ -1,11 +1,5 @@
import { defineStore } from 'pinia';
import {
createEmailTemplate,
deleteEmailTemplate,
getEmailTemplatePage,
getEmailTypeList,
updateEmailTemplate,
} from '@/api/v1/email/emailTemplate';
import { createEmailTemplate, deleteEmailTemplate, getEmailTemplatePage, getEmailTypeList, updateEmailTemplate } from '@/api/v1/email/emailTemplate';
import { pageSizes } from '@/enums/baseConstant';
import { storeMessage } from '@/utils/message';
import { storePagination } from '@/store/useStorePagination';

View File

@ -1,11 +1,5 @@
import { defineStore } from 'pinia';
import {
createEmailUsers,
deleteEmailUsers,
getEmailUserList,
getEmailUserPage,
updateEmailUsers,
} from '@/api/v1/email/emailUsers';
import { createEmailUsers, deleteEmailUsers, getEmailUserList, getEmailUserPage, updateEmailUsers } from '@/api/v1/email/emailUsers';
import { pageSizes } from '@/enums/baseConstant';
import { storeMessage } from '@/utils/message';
import { storePagination } from '@/store/useStorePagination';

View File

@ -1,11 +1,5 @@
import { defineStore } from 'pinia';
import {
createMenuIcon,
deleteMenuIcon,
getIconNameListByIconName,
getMenuIconPage,
updateMenuIcon,
} from '@/api/v1/menu/menuIcon';
import { createMenuIcon, deleteMenuIcon, getIconNameListByIconName, getMenuIconPage, updateMenuIcon } from '@/api/v1/menu/menuIcon';
import { pageSizes } from '@/enums/baseConstant';
import { storeMessage } from '@/utils/message';
import { storePagination } from '@/store/useStorePagination';

View File

@ -4,11 +4,8 @@ import { getConfig, responsiveStorageNameSpace, storageLocal, store } from './ut
export const useEpThemeStore = defineStore({
id: 'pure-epTheme',
state: () => ({
epThemeColor:
storageLocal().getItem<StorageConfigs>(`${responsiveStorageNameSpace()}layout`)?.epThemeColor ??
getConfig().EpThemeColor,
epTheme:
storageLocal().getItem<StorageConfigs>(`${responsiveStorageNameSpace()}layout`)?.theme ?? getConfig().Theme,
epThemeColor: storageLocal().getItem<StorageConfigs>(`${responsiveStorageNameSpace()}layout`)?.epThemeColor ?? getConfig().EpThemeColor,
epTheme: storageLocal().getItem<StorageConfigs>(`${responsiveStorageNameSpace()}layout`)?.theme ?? getConfig().Theme,
}),
getters: {
getEpThemeColor(state) {

View File

@ -1,12 +1,4 @@
import {
createI18n,
deleteI18n,
downloadI18n,
getI18nMap,
getI18nPage,
updateI18n,
uploadI18nFile,
} from '@/api/v1/i18n';
import { createI18n, deleteI18n, downloadI18n, getI18nMap, getI18nPage, updateI18n, uploadI18nFile } from '@/api/v1/i18n';
import { pageSizes } from '@/enums/baseConstant';
import { storePagination } from '@/store/useStorePagination';
import { storeMessage } from '@/utils/message';

View File

@ -1,9 +1,5 @@
import { defineStore } from 'pinia';
import {
deleteMessageReceivedByAdmin,
getMessageReceivedPage,
updateMessageReceivedByAdmin,
} from '@/api/v1/message/messageReceived';
import { deleteMessageReceivedByAdmin, getMessageReceivedPage, updateMessageReceivedByAdmin } from '@/api/v1/message/messageReceived';
import { pageSizes } from '@/enums/baseConstant';
import { storeMessage } from '@/utils/message';
import { storePagination } from '@/store/useStorePagination';

View File

@ -1,12 +1,6 @@
import { defineStore } from 'pinia';
import { pageSizes } from '@/enums/baseConstant';
import {
createMessage,
deleteMessage,
getMessagePage,
getReceivedUserinfoByMessageId,
updateMessage,
} from '@/api/v1/message/messageSend';
import { createMessage, deleteMessage, getMessagePage, getReceivedUserinfoByMessageId, updateMessage } from '@/api/v1/message/messageSend';
import { storePagination } from '@/store/useStorePagination';
import { storeMessage } from '@/utils/message';

View File

@ -1,11 +1,5 @@
import { defineStore } from 'pinia';
import {
createMessageType,
deleteMessageType,
getMessageTypeList,
getMessageTypePage,
updateMessageType,
} from '@/api/v1/message/messageType';
import { createMessageType, deleteMessageType, getMessageTypeList, getMessageTypePage, updateMessageType } from '@/api/v1/message/messageType';
import { pageSizes } from '@/enums/baseConstant';
import { storeMessage } from '@/utils/message';
import { storePagination } from '@/store/useStorePagination';

View File

@ -3,11 +3,7 @@ import { pageSizes } from '@/enums/baseConstant';
import { storePagination } from '@/store/useStorePagination';
import { storeMessage } from '@/utils/message';
import { decode } from 'js-base64';
import {
deleteMessageReceivedByUser,
getMessageReceivedPageByUser,
updateMessageByUser,
} from '@/api/v1/message/messageReceived';
import { deleteMessageReceivedByUser, getMessageReceivedPageByUser, updateMessageByUser } from '@/api/v1/message/messageReceived';
import { getMessageDetailById } from '@/api/v1/message/messageSend';
/**

View File

@ -5,15 +5,12 @@ export const useAppStore = defineStore({
id: 'pure-app',
state: (): appType => ({
sidebar: {
opened:
storageLocal().getItem<StorageConfigs>(`${responsiveStorageNameSpace()}layout`)?.sidebarStatus ??
getConfig().SidebarStatus,
opened: storageLocal().getItem<StorageConfigs>(`${responsiveStorageNameSpace()}layout`)?.sidebarStatus ?? getConfig().SidebarStatus,
withoutAnimation: false,
isClickCollapse: false,
},
// 这里的layout用于监听容器拖拉后恢复对应的导航模式
layout:
storageLocal().getItem<StorageConfigs>(`${responsiveStorageNameSpace()}layout`)?.layout ?? getConfig().Layout,
layout: storageLocal().getItem<StorageConfigs>(`${responsiveStorageNameSpace()}layout`)?.layout ?? getConfig().Layout,
device: deviceDetection() ? 'mobile' : 'desktop',
// 浏览器窗口的可视区域大小
viewportSize: {

View File

@ -1,12 +1,5 @@
import { defineStore } from 'pinia';
import {
deleteFiles,
fetchAddFiles,
getFilesPage,
getFilesStoragePath,
getMediaTypeList,
updateFiles,
} from '@/api/v1/files';
import { deleteFiles, fetchAddFiles, getFilesPage, getFilesStoragePath, getMediaTypeList, updateFiles } from '@/api/v1/files';
import { pageSizes } from '@/enums/baseConstant';
import { storeMessage } from '@/utils/message';
import { storePagination } from '@/store/useStorePagination';

View File

@ -1,15 +1,5 @@
import { defineStore } from 'pinia';
import {
ascending,
type cacheType,
constantMenus,
debounce,
filterNoPermissionTree,
filterTree,
formatFlatteningRoutes,
getKeyList,
store,
} from './utils';
import { ascending, type cacheType, constantMenus, debounce, filterNoPermissionTree, filterTree, formatFlatteningRoutes, getKeyList, store } from './utils';
import { useMultiTagsStoreHook } from './multiTags';
export const usePermissionStore = defineStore({

View File

@ -1,11 +1,4 @@
import {
clearRouterRole,
createRouter,
deletedRouterByIds,
getRoleListByRouterId,
getRouterList,
updateRouter,
} from '@/api/v1/menu/menu';
import { clearRouterRole, createRouter, deletedRouterByIds, getRoleListByRouterId, getRouterList, updateRouter } from '@/api/v1/menu/menu';
import { $t } from '@/plugins/i18n';
import { storeMessage } from '@/utils/message';
import { handleTree } from '@/utils/tree';

View File

@ -2,14 +2,17 @@ import { defineStore } from 'pinia';
import {
createPermission,
deletePermission,
exportPermission,
getPermissionList,
getPermissionPage,
importPermission,
updatePermission,
updatePermissionListByParentId,
} from '@/api/v1/system/power';
import { pageSizes } from '@/enums/baseConstant';
import { storeMessage } from '@/utils/message';
import { storePagination } from '@/store/useStorePagination';
import { downloadBlob } from '@/utils/sso';
/**
* Store
@ -79,9 +82,16 @@ export const usePermissionStore = defineStore('PermissionStore', {
return storeMessage(result);
},
/** 批量修改权限父级 */
async updatePermissionListByParentId(data: any) {
const result = await updatePermissionListByParentId(data);
/* 使用Excel导出权限 */
async downloadPermissionByFile() {
const result = await exportPermission();
downloadBlob(result, 'role.zip');
},
/* 使用文件导入权限 */
async uploadPermissionByFile(data: any) {
const result = await importPermission(data);
return storeMessage(result);
},
@ -91,5 +101,11 @@ export const usePermissionStore = defineStore('PermissionStore', {
if (result.code !== 200) return;
this.allPowerList = result.data;
},
/** 批量修改权限父级 */
async updatePermissionListByParentId(data: any) {
const result = await updatePermissionListByParentId(data);
return storeMessage(result);
},
},
});

View File

@ -1,16 +1,9 @@
import { defineStore } from 'pinia';
import {
crateRole,
createRolePermission,
deleteRole,
getRoleList,
getRolePage,
updateRole,
updateRoleByFile,
} from '@/api/v1/system/role';
import { crateRole, createRolePermission, deleteRole, exportRoleList, getRoleList, getRolePage, updateRole, updateRoleByFile } from '@/api/v1/system/role';
import { pageSizes } from '@/enums/baseConstant';
import { storeMessage } from '@/utils/message';
import { storePagination } from '@/store/useStorePagination';
import { downloadBlob } from '@/utils/sso';
/**
* Store
@ -84,6 +77,13 @@ export const useRoleStore = defineStore('roleStore', {
return storeMessage(result);
},
/* 使用Excel导出角色 */
async downloadRoleByFile() {
const result = await exportRoleList();
downloadBlob(result, 'role.zip');
},
/* 使用Excel更新角色列表 */
async editRoleByFile(data: any) {
const result = await updateRoleByFile(data);

View File

@ -3,14 +3,5 @@ export { routerArrays } from '@/layout/types';
export { router, resetRouter, constantMenus } from '@/router';
export { getConfig, responsiveStorageNameSpace } from '@/config';
export { ascending, filterTree, filterNoPermissionTree, formatFlatteningRoutes } from '@/router/utils';
export {
isUrl,
isEqual,
isNumber,
debounce,
isBoolean,
getKeyList,
storageLocal,
deviceDetection,
} from '@pureadmin/utils';
export { isUrl, isEqual, isNumber, debounce, isBoolean, getKeyList, storageLocal, deviceDetection } from '@pureadmin/utils';
export type { setType, appType, userType, multiType, cacheType, positionType } from './types';

View File

@ -25,8 +25,7 @@ body {
width: 100%;
height: 100%;
margin: 0;
font-family: 'Helvetica Neue', Helvetica, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', '微软雅黑', Arial,
sans-serif;
font-family: 'Helvetica Neue', Helvetica, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', '微软雅黑', Arial, sans-serif;
line-height: inherit;
-moz-osx-font-smoothing: grayscale;
-webkit-font-smoothing: antialiased;

View File

@ -51,9 +51,7 @@ export function setToken(data: any) {
expires = new Date(data.expires).getTime(); // 如果后端直接设置时间戳将此处代码改为expires = data.expires然后把上面的DataInfo<Date>改成DataInfo<number>即可
const cookieString = JSON.stringify({ token, expires, refreshToken });
expires > 0
? Cookies.set(TokenKey, cookieString, { expires: (expires - Date.now()) / 86400000 })
: Cookies.set(TokenKey, cookieString);
expires > 0 ? Cookies.set(TokenKey, cookieString, { expires: (expires - Date.now()) / 86400000 }) : Cookies.set(TokenKey, cookieString);
Cookies.set(multipleTabsKey, 'true', isRemembered ? { expires: readMeDay } : {});

View File

@ -31,10 +31,7 @@ interface LocalForageDbMethodsCore {
keys(callback?: (err: any, keys: string[]) => void): Promise<string[]>;
iterate<T, U>(
iteratee: (value: T, key: string, iterationNumber: number) => U,
callback?: (err: any, result: U) => void
): Promise<U>;
iterate<T, U>(iteratee: (value: T, key: string, iterationNumber: number) => U, callback?: (err: any, result: U) => void): Promise<U>;
}
interface LocalForageDropInstanceFn {

View File

@ -2,9 +2,7 @@ import { useEventListener } from '@vueuse/core';
/** 是否为`img`标签 */
function isImgElement(element) {
return typeof HTMLImageElement !== 'undefined'
? element instanceof HTMLImageElement
: element.tagName.toLowerCase() === 'img';
return typeof HTMLImageElement !== 'undefined' ? element instanceof HTMLImageElement : element.tagName.toLowerCase() === 'img';
}
// 在 src/main.ts 引入并调用即可 import { addPreventDefault } from "@/utils/preventDefault"; addPreventDefault();

View File

@ -106,8 +106,7 @@ export const appendFieldByUniqueId = (tree: any[], uniqueId: number | string, fi
if (!tree || tree.length === 0) return [];
for (const node of tree) {
const hasChildren = node.children && node.children.length > 0;
if (node.uniqueId === uniqueId && Object.prototype.toString.call(fields) === '[object Object]')
Object.assign(node, fields);
if (node.uniqueId === uniqueId && Object.prototype.toString.call(fields) === '[object Object]') Object.assign(node, fields);
if (hasChildren) {
appendFieldByUniqueId(node.children, uniqueId, fields);
}

View File

@ -4,15 +4,7 @@ import { sexConstant } from '@/enums/baseConstant';
import { $t } from '@/plugins/i18n';
import { useAdminUserStore } from '@/store/system/adminUser';
import { message } from '@/utils/message';
import {
cropperBlob,
handleSubmitImage,
isShow,
onSearchByUserinfo,
rules,
uploadAvatarSrc,
userInfos,
} from '@/views/account-settings/utils';
import { cropperBlob, handleSubmitImage, isShow, onSearchByUserinfo, rules, uploadAvatarSrc, userInfos } from '@/views/account-settings/utils';
import uploadLine from '@iconify-icons/ri/upload-line';
import { deviceDetection } from '@pureadmin/utils';
import type { FormInstance } from 'element-plus';
@ -82,14 +74,7 @@ onMounted(() => {
<el-form ref="userInfoFormRef" :model="userInfos" :rules="rules" label-position="top">
<el-form-item :label="$t('avatar')">
<el-avatar :size="80" :src="userInfos.avatar" />
<el-upload
ref="uploadRef"
:auto-upload="false"
:limit="1"
:on-change="onChange"
:show-file-list="false"
accept="image/*"
>
<el-upload ref="uploadRef" :auto-upload="false" :limit="1" :on-change="onChange" :show-file-list="false" accept="image/*">
<el-button class="ml-4" plain>
<IconifyIconOffline :icon="uploadLine" />
<span class="ml-2">{{ $t('upload_avatar') }}</span>
@ -102,13 +87,7 @@ onMounted(() => {
<!-- 用户名 -->
<el-form-item :label="$t('adminUser_username')" prop="username">
<el-input
v-model="userInfos.username"
:placeholder="$t('adminUser_username')"
autocomplete="off"
disabled
type="text"
/>
<el-input v-model="userInfos.username" :placeholder="$t('adminUser_username')" autocomplete="off" disabled type="text" />
</el-form-item>
<!-- 昵称 -->
@ -129,13 +108,7 @@ onMounted(() => {
<!-- 性别 -->
<el-form-item :label="$t('adminUser_sex')" prop="sex">
<el-select v-model="userInfos.sex" :placeholder="$t('adminUser_sex')" clearable filterable>
<el-option
v-for="(item, index) in sexConstant"
:key="index"
:label="item.label"
:navigationBar="false"
:value="item.value"
/>
<el-option v-for="(item, index) in sexConstant" :key="index" :label="item.label" :navigationBar="false" :value="item.value" />
</el-select>
</el-form-item>

View File

@ -69,16 +69,8 @@ onBeforeMount(() => {
</el-menu>
</el-aside>
<el-main>
<LaySidebarTopCollapse
v-if="deviceDetection()"
:is-active="isOpen"
class="px-0"
@toggleClick="isOpen = !isOpen"
/>
<component
:is="panes.find((item) => item.key === witchPane).component"
:class="[!deviceDetection() && 'ml-[120px]']"
/>
<LaySidebarTopCollapse v-if="deviceDetection()" :is-active="isOpen" class="px-0" @toggleClick="isOpen = !isOpen" />
<component :is="panes.find((item) => item.key === witchPane).component" :class="[!deviceDetection() && 'ml-[120px]']" />
</el-main>
</el-container>
</template>

View File

@ -49,13 +49,7 @@ defineExpose({ formRef });
<!-- 配置模板邮件关联用户邮件 -->
<el-form-item :label="$t('emailTemplate_emailUser')" prop="emailUser">
<el-select v-model="form.emailUser" :placeholder="$t('emailTemplate_emailUser')" clearable filterable>
<el-option
v-for="(item, index) in emailUsersStore.emailUserList"
:key="index"
:label="item.key"
:navigationBar="false"
:value="item.value"
/>
<el-option v-for="(item, index) in emailUsersStore.emailUserList" :key="index" :label="item.key" :navigationBar="false" :value="item.value" />
</el-select>
</el-form-item>
@ -85,13 +79,7 @@ defineExpose({ formRef });
<!--配置邮件类型-->
<el-form-item :label="$t('emailTemplate_type')" prop="type">
<el-select v-model="form.type" :placeholder="$t('emailTemplate_type')" clearable filterable>
<el-option
v-for="(item, index) in emailTemplateStore.allEmailTypes"
:key="index"
:label="item.key"
:navigationBar="false"
:value="item.value"
/>
<el-option v-for="(item, index) in emailTemplateStore.allEmailTypes" :key="index" :label="item.key" :navigationBar="false" :value="item.value" />
</el-select>
</el-form-item>
</el-form>

View File

@ -6,16 +6,7 @@ import PureTableBar from '@/components/TableBar/src/bar';
import { $t } from '@/plugins/i18n';
import { hasAuth } from '@/router/utils';
import { useEmailTemplateStore } from '@/store/configuration/emailTemplate';
import {
auth,
columns,
onAdd,
onDelete,
onDeleteBatch,
onSearch,
onUpdate,
selectRows,
} from '@/views/configuration/email-template/utils';
import { auth, columns, onAdd, onDelete, onDeleteBatch, onSearch, onUpdate, selectRows } from '@/views/configuration/email-template/utils';
import Delete from '@iconify-icons/ep/delete';
import EditPen from '@iconify-icons/ep/edit-pen';
import Refresh from '@iconify-icons/ep/refresh';
@ -78,12 +69,7 @@ onMounted(() => {
<template>
<div class="main">
<ReAuth :value="auth.query">
<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 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"
@ -93,36 +79,16 @@ onMounted(() => {
/>
</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
/>
<el-input v-model="emailTemplateStore.form.subject" :placeholder="`${$t('input')}${$t('emailTemplate_subject')}`" class="!w-[180px]" clearable />
</el-form-item>
<el-form-item :label="$t('emailTemplate_body')" prop="body">
<el-input
v-model="emailTemplateStore.form.body"
:placeholder="`${$t('input')}${$t('emailTemplate_body')}`"
class="!w-[180px]"
clearable
/>
<el-input v-model="emailTemplateStore.form.body" :placeholder="`${$t('input')}${$t('emailTemplate_body')}`" class="!w-[180px]" clearable />
</el-form-item>
<el-form-item :label="$t('emailTemplate_type')" prop="type">
<el-input
v-model="emailTemplateStore.form.type"
:placeholder="`${$t('input')}${$t('emailTemplate_type')}`"
class="!w-[180px]"
clearable
/>
<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"
>
<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>
@ -130,26 +96,14 @@ onMounted(() => {
</el-form>
</ReAuth>
<PureTableBar
:columns="columns"
:title="$t('emailTemplate')"
@fullscreen="tableRef.setAdaptive()"
@refresh="onSearch"
>
<PureTableBar :columns="columns" :title="$t('emailTemplate')" @fullscreen="tableRef.setAdaptive()" @refresh="onSearch">
<template #buttons>
<el-button v-if="hasAuth(auth.add)" :icon="useRenderIcon(AddFill)" plain type="primary" @click="onAdd">
{{ $t('addNew') }}
</el-button>
<!-- 批量删除按钮 -->
<el-button
v-if="hasAuth(auth.delete)"
:disabled="!(selectRows.length > 0)"
:icon="useRenderIcon(Delete)"
plain
type="danger"
@click="onDeleteBatch"
>
<el-button v-if="hasAuth(auth.delete)" :disabled="!(selectRows.length > 0)" :icon="useRenderIcon(Delete)" plain type="danger" @click="onDeleteBatch">
{{ $t('deleteBatches') }}
</el-button>
</template>
@ -195,36 +149,17 @@ onMounted(() => {
<template #operation="{ row }">
<!--查看模板-->
<el-button
:icon="useRenderIcon(View)"
:size="size"
class="reset-margin"
link
type="primary"
@click="viewTemplate(row.body)"
>
<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.delete)"
:title="`${$t('delete')} ${row.templateName}?`"
@confirm="onDelete(row)"
>
<el-popconfirm v-if="hasAuth(auth.delete)" :title="`${$t('delete')} ${row.templateName}?`" @confirm="onDelete(row)">
<template #reference>
<el-button :icon="useRenderIcon(Delete)" :size="size" class="reset-margin" link type="primary">
{{ $t('delete') }}

View File

@ -21,11 +21,7 @@ export const columns: TableColumnList = [
label: $t('isDefault'),
prop: 'isDefault',
formatter({ isDefault }) {
return isDefault ? (
<ElTag type={'success'}>{$t('default')}</ElTag>
) : (
<ElTag type={'danger'}>{$t('no_default')}</ElTag>
);
return isDefault ? <ElTag type={'success'}>{$t('default')}</ElTag> : <ElTag type={'danger'}>{$t('no_default')}</ElTag>;
},
minWidth: 100,
},

View File

@ -68,30 +68,15 @@ onMounted(() => {
<template>
<div class="main">
<ReAuth :value="auth.query">
<el-form
ref="formRef"
:inline="true"
:model="emailUsersStore.form"
class="search-form bg-bg_color w-[99/100] pl-8 pt-[12px] overflow-auto"
>
<el-form ref="formRef" :inline="true" :model="emailUsersStore.form" class="search-form bg-bg_color w-[99/100] pl-8 pt-[12px] overflow-auto">
<!-- 邮箱-->
<el-form-item :label="$t('emailUsers_email')" prop="email">
<el-input
v-model="emailUsersStore.form.email"
:placeholder="`${$t('input')}${$t('emailUsers_email')}`"
class="!w-[180px]"
clearable
/>
<el-input v-model="emailUsersStore.form.email" :placeholder="`${$t('input')}${$t('emailUsers_email')}`" class="!w-[180px]" clearable />
</el-form-item>
<!-- host地址-->
<el-form-item :label="$t('emailUsers_host')" prop="host">
<el-input
v-model="emailUsersStore.form.host"
:placeholder="`${$t('input')}${$t('emailUsers_host')}`"
class="!w-[180px]"
clearable
/>
<el-input v-model="emailUsersStore.form.host" :placeholder="`${$t('input')}${$t('emailUsers_host')}`" class="!w-[180px]" clearable />
</el-form-item>
<!-- 端口号-->
@ -120,23 +105,12 @@ onMounted(() => {
<!-- 是否启用SSL -->
<el-form-item label="SSL" prop="openSSL">
<el-select v-model="emailUsersStore.form.openSSL" class="!w-[180px]" clearable filterable placeholder="SSL">
<el-option
v-for="(item, index) in enabledOrNotStatus"
:key="index"
:label="item.label"
:navigationBar="false"
:value="item.value"
/>
<el-option v-for="(item, index) in enabledOrNotStatus" :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="emailUsersStore.loading"
type="primary"
@click="onSearch"
>
<el-button :icon="useRenderIcon('ri:search-line')" :loading="emailUsersStore.loading" type="primary" @click="onSearch">
{{ $t('search') }}
</el-button>
<el-button :icon="useRenderIcon(Refresh)" @click="resetForm(formRef)">{{ $t('buttons.reset') }}</el-button>
@ -144,26 +118,14 @@ onMounted(() => {
</el-form>
</ReAuth>
<PureTableBar
:columns="columns"
:title="$t('email_user_send_config')"
@fullscreen="tableRef.setAdaptive()"
@refresh="onSearch"
>
<PureTableBar :columns="columns" :title="$t('email_user_send_config')" @fullscreen="tableRef.setAdaptive()" @refresh="onSearch">
<template #buttons>
<el-button v-if="hasAuth(auth.add)" :icon="useRenderIcon(AddFill)" plain type="primary" @click="onAdd">
{{ $t('addNew') }}
</el-button>
<!-- 批量删除按钮 -->
<el-button
v-if="hasAuth(auth.delete)"
:disabled="!(deleteIds.length > 0)"
:icon="useRenderIcon(Delete)"
plain
type="danger"
@click="onDeleteBatch"
>
<el-button v-if="hasAuth(auth.delete)" :disabled="!(deleteIds.length > 0)" :icon="useRenderIcon(Delete)" plain type="danger" @click="onDeleteBatch">
{{ $t('deleteBatches') }}
</el-button>
</template>
@ -217,27 +179,13 @@ onMounted(() => {
<!-- 插槽-更新用户 -->
<template #updateUser="{ row }">
<el-button
v-if="hasAuth(auth.update)"
v-show="row.updateUser"
link
type="primary"
@click="selectUserinfo(row.updateUser)"
>
<el-button v-if="hasAuth(auth.update)" v-show="row.updateUser" link type="primary" @click="selectUserinfo(row.updateUser)">
{{ row.updateUsername }}
</el-button>
</template>
<template #operation="{ row }">
<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.delete)" :title="`${$t('delete')}${row.email}?`" @confirm="onDelete(row)">

View File

@ -39,13 +39,7 @@ defineExpose({ formRef });
<!-- icon 官网 -->
<el-form-item :label="$t('systemMenuIcon.officialWebsite')">
<el-link
:title="$t('systemMenuIcon.officialWebsite')"
:underline="false"
href="https://icon-sets.iconify.design/"
target="_blank"
type="primary"
>
<el-link :title="$t('systemMenuIcon.officialWebsite')" :underline="false" href="https://icon-sets.iconify.design/" target="_blank" type="primary">
{{ $t('systemMenuIcon.officialWebsite') }}
</el-link>
</el-form-item>

View File

@ -41,12 +41,7 @@ const onRequestIconName = async (iconName: string) => {
remote
remote-show-suffix
>
<el-option
v-for="menuIcon in menuIconStore.iconNameList"
:key="menuIcon.id"
:label="menuIcon.iconName"
:value="menuIcon.iconName"
/>
<el-option v-for="menuIcon in menuIconStore.iconNameList" :key="menuIcon.id" :label="menuIcon.iconName" :value="menuIcon.iconName" />
<template #loading>
<el-icon class="is-loading">
<LoadingSvg />

View File

@ -1,15 +1,6 @@
<script lang="ts" setup>
import { onMounted, ref } from 'vue';
import {
auth,
columns,
deleteIds,
onAdd,
onDelete,
onDeleteBatch,
onSearch,
onUpdate,
} from '@/views/configuration/menu-icon/utils';
import { auth, columns, deleteIds, onAdd, onDelete, onDeleteBatch, onSearch, onUpdate } from '@/views/configuration/menu-icon/utils';
import PureTableBar from '@/components/TableBar/src/bar';
import { useRenderIcon } from '@/components/ReIcon/src/hooks';
import AddFill from '@iconify-icons/ri/add-circle-line';
@ -61,30 +52,15 @@ onMounted(() => {
<template>
<div class="main">
<ReAuth :value="auth.query">
<el-form
ref="formRef"
:inline="true"
:model="menuIconStore.form"
class="search-form bg-bg_color w-[99/100] pl-8 pt-[12px] overflow-auto"
>
<el-form ref="formRef" :inline="true" :model="menuIconStore.form" class="search-form bg-bg_color w-[99/100] pl-8 pt-[12px] overflow-auto">
<el-form-item :label="$t('menuIcon_iconCode')" prop="iconCode">
<el-input
v-model="menuIconStore.form.iconCode"
:placeholder="`${$t('input')} ${$t('iconCode')}`"
class="!w-[180px]"
clearable
/>
<el-input v-model="menuIconStore.form.iconCode" :placeholder="`${$t('input')} ${$t('iconCode')}`" class="!w-[180px]" clearable />
</el-form-item>
<el-form-item :label="$t('menuIcon_iconName')" prop="iconName">
<MenuIconSelectIconName :form-inline="menuIconStore.form" class="!w-[180px]" />
</el-form-item>
<el-form-item>
<el-button
:icon="useRenderIcon('ri:search-line')"
:loading="menuIconStore.loading"
type="primary"
@click="onSearch"
>
<el-button :icon="useRenderIcon('ri:search-line')" :loading="menuIconStore.loading" type="primary" @click="onSearch">
{{ $t('search') }}
</el-button>
<el-button :icon="useRenderIcon(Refresh)" @click="resetForm(formRef)">{{ $t('buttons.reset') }}</el-button>
@ -99,14 +75,7 @@ onMounted(() => {
</el-button>
<!-- 批量删除按钮 -->
<el-button
v-if="hasAuth(auth.delete)"
:disabled="!(deleteIds.length > 0)"
:icon="useRenderIcon(Delete)"
plain
type="danger"
@click="onDeleteBatch"
>
<el-button v-if="hasAuth(auth.delete)" :disabled="!(deleteIds.length > 0)" :icon="useRenderIcon(Delete)" plain type="danger" @click="onDeleteBatch">
{{ $t('deleteBatches') }}
</el-button>
</template>
@ -151,22 +120,10 @@ onMounted(() => {
</template>
<template #operation="{ row }">
<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.delete)"
:title="`${$t('delete')}${row.iconName}?`"
@confirm="onDelete(row)"
>
<el-popconfirm v-if="hasAuth(auth.delete)" :title="`${$t('delete')}${row.iconName}?`" @confirm="onDelete(row)">
<template #reference>
<el-button :icon="useRenderIcon(Delete)" :size="size" class="reset-margin" link type="primary">
{{ $t('delete') }}

View File

@ -25,15 +25,7 @@ onMounted(() => {
</script>
<template>
<el-form
ref="ruleFormRef"
:model="form"
:rules="rules"
class="bg-white p-[30px] h-[100%]"
label-position="left"
label-width="auto"
status-icon
>
<el-form ref="ruleFormRef" :model="form" :rules="rules" class="bg-white p-[30px] h-[100%]" label-position="left" label-width="auto" status-icon>
<el-row :gutter="30">
<!-- 应用程序的版本 -->
<re-col :sm="24" :value="12" :xs="24">
@ -52,12 +44,7 @@ onMounted(() => {
<!-- 版权信息 -->
<re-col :sm="24" :value="12" :xs="24">
<el-form-item :label="$t('copyright')" prop="copyright">
<el-input
v-model="form.copyright"
:placeholder="$t('input') + $t('copyright')"
autocomplete="off"
type="text"
/>
<el-input v-model="form.copyright" :placeholder="$t('input') + $t('copyright')" autocomplete="off" type="text" />
</el-form-item>
</re-col>
@ -125,12 +112,7 @@ onMounted(() => {
<re-col :sm="24" :value="12" :xs="24">
<el-form-item :label="$t('appLocale')" prop="locale">
<el-select v-model="form.locale" :placeholder="$t('select') + $t('appLocale')" filterable>
<el-option
v-for="item in i18nTypeStore.datalist"
:key="item.id"
:label="item.summary"
:value="item.typeName"
/>
<el-option v-for="item in i18nTypeStore.datalist" :key="item.id" :label="item.summary" :value="item.typeName" />
</el-select>
</el-form-item>
</re-col>
@ -292,12 +274,7 @@ onMounted(() => {
<!-- 要显示的模型 -->
<re-col :sm="24" :value="12" :xs="24">
<el-form-item :label="$t('showModel')" prop="showModel">
<el-input
v-model="form.showModel"
:placeholder="$t('input') + $t('showModel')"
autocomplete="off"
type="text"
/>
<el-input v-model="form.showModel" :placeholder="$t('input') + $t('showModel')" autocomplete="off" type="text" />
</el-form-item>
</re-col>
@ -343,26 +320,14 @@ onMounted(() => {
<!-- 响应式存储的命名空间 -->
<re-col :sm="24" :value="12" :xs="24">
<el-form-item :label="$t('responsiveStorageNameSpace')" prop="responsiveStorageNameSpace">
<el-input
v-model="form.responsiveStorageNameSpace"
:placeholder="$t('input') + $t('responsiveStorageNameSpace')"
autocomplete="off"
type="text"
/>
<el-input v-model="form.responsiveStorageNameSpace" :placeholder="$t('input') + $t('responsiveStorageNameSpace')" autocomplete="off" type="text" />
</el-form-item>
</re-col>
<!-- 菜单搜索历史 -->
<re-col :sm="24" :value="12" :xs="24">
<el-form-item :label="$t('menuSearchHistory')" prop="menuSearchHistory">
<el-input
v-model="form.menuSearchHistory"
:max="99"
:min="1"
:placeholder="$t('input') + $t('menuSearchHistory')"
autocomplete="off"
type="number"
/>
<el-input v-model="form.menuSearchHistory" :max="99" :min="1" :placeholder="$t('input') + $t('menuSearchHistory')" autocomplete="off" type="number" />
</el-form-item>
</re-col>

View File

@ -27,12 +27,7 @@ defineExpose({ ruleFormRef });
<el-form ref="ruleFormRef" :model="form" :rules="rules" isDefault-icon label-position="left" label-width="135px">
<el-form-item :label="$t('i18n.typeName')" prop="typeName">
<el-select v-model="form.typeName" :placeholder="$t('select') + $t('i18n.typeName')" filterable>
<el-option
v-for="item in i18nTypeStore.datalist"
:key="item.id"
:label="item.typeName"
:value="item.typeName"
/>
<el-option v-for="item in i18nTypeStore.datalist" :key="item.id" :label="item.typeName" :value="item.typeName" />
</el-select>
</el-form-item>

View File

@ -47,25 +47,12 @@ defineExpose({ formRef });
<el-form ref="formRef" :model="form" :rules="rules" isDefault-icon>
<el-form-item :label="$t('i18n_type')" prop="type">
<el-select v-model="form.type" :placeholder="$t('select') + $t('i18n.typeName')" filterable>
<el-option
v-for="(item, index) in i18nTypeStore.datalist"
:key="index"
:label="item.typeName"
:value="item.typeName"
/>
<el-option v-for="(item, index) in i18nTypeStore.datalist" :key="index" :label="item.typeName" :value="item.typeName" />
</el-select>
</el-form-item>
<el-form-item :label="$t('files')" prop="file">
<el-upload
ref="uploadRef"
v-model:file-list="form.file"
:autoUpload="false"
:limit="1"
:on-exceed="handleExceed"
class="w-full mt-2"
drag
>
<el-upload ref="uploadRef" v-model:file-list="form.file" :autoUpload="false" :limit="1" :on-exceed="handleExceed" class="w-full mt-2" drag>
<el-icon class="el-icon--upload">
<UploadFilled />
</el-icon>

View File

@ -65,43 +65,18 @@ onMounted(() => {
<template>
<div class="main">
<ReAuth :value="auth.query">
<el-form
ref="pageFormRef"
:inline="true"
:model="i18nStore.form"
class="search-form bg-bg_color w-[99/100] pl-8 pt-[12px] overflow-auto"
>
<el-form ref="pageFormRef" :inline="true" :model="i18nStore.form" class="search-form bg-bg_color w-[99/100] pl-8 pt-[12px] overflow-auto">
<el-form-item :label="$t('i18n.keyName')" prop="keyName">
<el-input
v-model="i18nStore.form.keyName"
:placeholder="`${$t('input')}${$t('i18n.keyName')}`"
class="!w-[180px]"
clearable
/>
<el-input v-model="i18nStore.form.keyName" :placeholder="`${$t('input')}${$t('i18n.keyName')}`" class="!w-[180px]" clearable />
</el-form-item>
<el-form-item :label="$t('i18n.translation')" prop="translation">
<el-input
v-model="i18nStore.form.translation"
:placeholder="`${$t('input')}${$t('i18n.translation')}`"
class="!w-[180px]"
clearable
/>
<el-input v-model="i18nStore.form.translation" :placeholder="`${$t('input')}${$t('i18n.translation')}`" class="!w-[180px]" clearable />
</el-form-item>
<el-form-item :label="$t('i18n.typeName')" prop="typeName">
<el-input
v-model="i18nStore.form.typeName"
:placeholder="`${$t('input')}${$t('i18n.typeName')}`"
class="!w-[180px]"
clearable
/>
<el-input v-model="i18nStore.form.typeName" :placeholder="`${$t('input')}${$t('i18n.typeName')}`" class="!w-[180px]" clearable />
</el-form-item>
<el-form-item>
<el-button
:icon="useRenderIcon('ri:search-line')"
:loading="i18nStore.loading"
type="primary"
@click="onSearch"
>
<el-button :icon="useRenderIcon('ri:search-line')" :loading="i18nStore.loading" type="primary" @click="onSearch">
{{ $t('search') }}
</el-button>
<el-button :icon="useRenderIcon(Refresh)" @click="resetForm(pageFormRef)">
@ -111,12 +86,7 @@ onMounted(() => {
</el-form>
</ReAuth>
<PureTableBar
:columns="columns"
:title="$t('multilingualManagement')"
@fullscreen="tableRef.setAdaptive()"
@refresh="onSearch"
>
<PureTableBar :columns="columns" :title="$t('multilingualManagement')" @fullscreen="tableRef.setAdaptive()" @refresh="onSearch">
<template #buttons>
<!-- 下载多语言配置 -->
<el-dropdown v-if="hasAuth(auth.download)" class="mr-1" type="primary">
@ -148,14 +118,7 @@ onMounted(() => {
</el-button>
<!-- 批量删除按钮 -->
<el-button
v-if="hasAuth(auth.deleted)"
:disabled="!(deleteIds.length > 0)"
:icon="useRenderIcon(Delete)"
plain
type="danger"
@click="onDeleteBatch"
>
<el-button v-if="hasAuth(auth.deleted)" :disabled="!(deleteIds.length > 0)" :icon="useRenderIcon(Delete)" plain type="danger" @click="onDeleteBatch">
{{ $t('deleteBatches') }}
</el-button>
</template>
@ -198,22 +161,10 @@ onMounted(() => {
</template>
<template #operation="{ row }">
<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('confirmDelete')} ${row.translation}`"
@confirm="onDelete(row)"
>
<el-popconfirm v-if="hasAuth(auth.deleted)" :title="`${$t('confirmDelete')} ${row.translation}`" @confirm="onDelete(row)">
<template #reference>
<el-button :icon="useRenderIcon(Delete)" :size="size" class="reset-margin" link type="primary">
{{ $t('delete') }}

View File

@ -23,27 +23,13 @@ defineExpose({ formRef });
<template>
<el-form ref="formRef" :model="form" :rules="rules" label-width="auto">
<el-form-item :label="$t('i18n_typeName')" prop="typeName">
<el-input
v-model="form.typeName"
:placeholder="$t('select') + $t('i18n_typeName')"
autocomplete="off"
type="text"
/>
<el-input v-model="form.typeName" :placeholder="$t('select') + $t('i18n_typeName')" autocomplete="off" type="text" />
</el-form-item>
<el-form-item :label="$t('i18n_summary')" prop="summary">
<el-input
v-model="form.summary"
:placeholder="$t('select') + $t('i18n_summary')"
autocomplete="off"
type="text"
/>
<el-input v-model="form.summary" :placeholder="$t('select') + $t('i18n_summary')" autocomplete="off" type="text" />
</el-form-item>
<el-form-item :label="$t('isDefault')" prop="isDefault">
<Segmented
:modelValue="form.isDefault ? 0 : 1"
:options="frameSureOptions"
@change="({ option: { value } }) => (form.isDefault = value)"
/>
<Segmented :modelValue="form.isDefault ? 0 : 1" :options="frameSureOptions" @change="({ option: { value } }) => (form.isDefault = value)" />
</el-form-item>
</el-form>
</template>

View File

@ -33,35 +33,15 @@ onMounted(() => {
<template>
<div class="main">
<el-form
ref="formRef"
:inline="true"
:model="i18nTypeStore.form"
class="search-form bg-bg_color w-[99/100] pl-8 pt-[12px] overflow-auto"
>
<el-form ref="formRef" :inline="true" :model="i18nTypeStore.form" class="search-form bg-bg_color w-[99/100] pl-8 pt-[12px] overflow-auto">
<el-form-item :label="$t('i18n_typeName')" prop="typeName">
<el-input
v-model="i18nTypeStore.form.typeName"
:placeholder="`${$t('input')}${$t('i18n_typeName')}`"
class="!w-[180px]"
clearable
/>
<el-input v-model="i18nTypeStore.form.typeName" :placeholder="`${$t('input')}${$t('i18n_typeName')}`" class="!w-[180px]" clearable />
</el-form-item>
<el-form-item :label="$t('i18n_summary')" prop="summary">
<el-input
v-model="i18nTypeStore.form.summary"
:placeholder="`${$t('input')}${$t('i18n_summary')}`"
class="!w-[180px]"
clearable
/>
<el-input v-model="i18nTypeStore.form.summary" :placeholder="`${$t('input')}${$t('i18n_summary')}`" class="!w-[180px]" clearable />
</el-form-item>
<el-form-item>
<el-button
:icon="useRenderIcon('ri:search-line')"
:loading="i18nTypeStore.loading"
type="primary"
@click="onSearch"
>
<el-button :icon="useRenderIcon('ri:search-line')" :loading="i18nTypeStore.loading" type="primary" @click="onSearch">
{{ $t('search') }}
</el-button>
<el-button :icon="useRenderIcon(Refresh)" @click="resetForm(formRef)">{{ $t('buttons.reset') }}</el-button>
@ -109,22 +89,10 @@ onMounted(() => {
</template>
<template #operation="{ row }">
<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.delete)"
:title="`${$t('delete')} ${row.typeName}?`"
@confirm="onDelete(row)"
>
<el-popconfirm v-if="hasAuth(auth.delete)" :title="`${$t('delete')} ${row.typeName}?`" @confirm="onDelete(row)">
<template #reference>
<el-button :icon="useRenderIcon(Delete)" :size="size" class="reset-margin" link type="primary">
{{ $t('delete') }}

View File

@ -109,24 +109,13 @@ onBeforeUnmount(() => {
<el-form ref="ruleFormRef" :model="ruleForm" :rules="emailRules" size="large">
<Motion :delay="100">
<el-form-item prop="username">
<el-input
v-model="ruleForm.username"
:placeholder="t('login.username')"
:prefix-icon="useRenderIcon(User)"
clearable
/>
<el-input v-model="ruleForm.username" :placeholder="t('login.username')" :prefix-icon="useRenderIcon(User)" clearable />
</el-form-item>
</Motion>
<Motion :delay="150">
<el-form-item prop="password">
<el-input
v-model="ruleForm.password"
:placeholder="t('login.password')"
:prefix-icon="useRenderIcon(Lock)"
clearable
show-password
/>
<el-input v-model="ruleForm.password" :placeholder="t('login.password')" :prefix-icon="useRenderIcon(Lock)" clearable show-password />
</el-form-item>
</Motion>
@ -150,9 +139,7 @@ onBeforeUnmount(() => {
</template>
</el-input>
<el-checkbox v-model="userStore.isRemembered">
<el-text size="small" type="primary">
{{ userStore.readMeDay }}天免登录(邮箱验证码随便输入,后端校验验证码已注释)
</el-text>
<el-text size="small" type="primary">{{ userStore.readMeDay }}天免登录(邮箱验证码随便输入,后端校验验证码已注释)</el-text>
</el-checkbox>
</el-form-item>
</Motion>

View File

@ -69,28 +69,15 @@ onBeforeUnmount(() => {
<el-form ref="ruleFormRef" :model="ruleForm" :rules="formRules" size="large">
<Motion>
<el-form-item prop="username">
<el-input
v-model="ruleForm.username"
:placeholder="t('login.username')"
:prefix-icon="useRenderIcon(User)"
clearable
/>
<el-input v-model="ruleForm.username" :placeholder="t('login.username')" :prefix-icon="useRenderIcon(User)" clearable />
</el-form-item>
</Motion>
<Motion :delay="150">
<el-form-item prop="password">
<el-input
v-model="ruleForm.password"
:placeholder="t('login.password')"
:prefix-icon="useRenderIcon(Lock)"
clearable
show-password
/>
<el-input v-model="ruleForm.password" :placeholder="t('login.password')" :prefix-icon="useRenderIcon(Lock)" clearable show-password />
<el-checkbox v-model="userStore.isRemembered">
<el-text size="small" type="primary">
{{ userStore.readMeDay }}天免登录(邮箱验证码随便输入,后端校验验证码已注释)
</el-text>
<el-text size="small" type="primary">{{ userStore.readMeDay }}天免登录(邮箱验证码随便输入,后端校验验证码已注释)</el-text>
</el-checkbox>
</el-form-item>
</Motion>

View File

@ -35,19 +35,11 @@ onMounted(() => {
<img :src="bg" alt="" class="wave" />
<div class="flex-c absolute right-5 top-3">
<!-- 主题 -->
<el-switch
v-model="dataTheme"
:active-icon="dayIcon"
:inactive-icon="darkIcon"
inline-prompt
@change="dataThemeChange"
/>
<el-switch v-model="dataTheme" :active-icon="dayIcon" :inactive-icon="darkIcon" inline-prompt @change="dataThemeChange" />
<!-- 国际化 -->
<el-dropdown trigger="click">
<globalization
class="hover:text-primary hover:!bg-[transparent] w-[20px] h-[20px] ml-1.5 cursor-pointer outline-none duration-300"
/>
<globalization class="hover:text-primary hover:!bg-[transparent] w-[20px] h-[20px] ml-1.5 cursor-pointer outline-none duration-300" />
<template #dropdown>
<el-dropdown-menu class="translation">
<el-dropdown-item

View File

@ -1,13 +1,6 @@
<script lang="ts" setup>
import { onMounted, ref } from 'vue';
import {
columns,
markAsAllRead,
markAsRead,
onDelete,
onSearch,
selectIds,
} from '@/views/message-manger/message-detail/utils';
import { columns, markAsAllRead, markAsRead, onDelete, onSearch, selectIds } from '@/views/message-manger/message-detail/utils';
import PureTableBar from '@/components/TableBar/src/bar';
import PureTable from '@pureadmin/table';
import Delete from '@iconify-icons/ep/delete';
@ -53,39 +46,19 @@ onMounted(() => {
<template>
<div class="main">
<PureTableBar
:columns="columns"
@fullscreen="tableRef.setAdaptive()"
@refresh="onSearch((route.params as any).messageType)"
>
<PureTableBar :columns="columns" @fullscreen="tableRef.setAdaptive()" @refresh="onSearch((route.params as any).messageType)">
<template #title>
<el-segmented
v-model="messageUserStore.form.status"
:options="isReadStatus"
@change="onSearch((route.params as any).messageType)"
/>
<el-segmented v-model="messageUserStore.form.status" :options="isReadStatus" @change="onSearch((route.params as any).messageType)" />
</template>
<template #buttons>
<!-- 删除按钮 -->
<el-button
:disabled="!(selectIds.length > 0)"
:icon="useRenderIcon(Delete)"
plain
type="danger"
@click="onDelete"
>
<el-button :disabled="!(selectIds.length > 0)" :icon="useRenderIcon(Delete)" plain type="danger" @click="onDelete">
{{ $t('delete') }}
</el-button>
<!-- 标为已读 -->
<el-button
:disabled="!(selectIds.length > 0)"
:icon="useRenderIcon('octicon:read-24')"
plain
type="primary"
@click="markAsRead"
>
<el-button :disabled="!(selectIds.length > 0)" :icon="useRenderIcon('octicon:read-24')" plain type="primary" @click="markAsRead">
{{ $t('markAsRead') }}
</el-button>

View File

@ -28,10 +28,5 @@ const onUploadImg = async (files: any, callback: any) => {
</script>
<template>
<MdEditor
v-model="formState.content"
:showToolbarName="true"
style="height: calc(100vh - 150px)"
@onUploadImg="onUploadImg"
/>
<MdEditor v-model="formState.content" :showToolbarName="true" style="height: calc(100vh - 150px)" @onUploadImg="onUploadImg" />
</template>

View File

@ -79,12 +79,7 @@ onMounted(() => {
<!-- 消息类型 -->
<el-form-item :label="$t('messageType')" prop="messageTypeId">
<el-select
v-model="formState.messageTypeId"
:placeholder="`${$t('select')}${$t('messageType')}`"
clearable
filterable
>
<el-select v-model="formState.messageTypeId" :placeholder="`${$t('select')}${$t('messageType')}`" clearable filterable>
<el-option
v-for="(item, index) in messageTypeStore.allMessageTypeList"
:key="index"
@ -141,14 +136,7 @@ onMounted(() => {
<!-- 封面内容 -->
<el-form-item :label="$t('cover')" prop="cover">
<el-upload
:auto-upload="true"
:before-upload="beforeUpload"
:http-request="onUpload"
:show-file-list="false"
accept="image/*"
drag
>
<el-upload :auto-upload="true" :before-upload="beforeUpload" :http-request="onUpload" :show-file-list="false" accept="image/*" drag>
<el-image v-if="coverUrl" :src="coverUrl" fit="cover" lazy>
<template #placeholder>
<ImageLoading />
@ -163,26 +151,12 @@ onMounted(() => {
<!-- 简介 -->
<el-form-item :label="$t('summary')" prop="summary">
<el-input
v-model="formState.summary"
:autosize="{ minRows: 3, maxRows: 6 }"
maxlength="200"
minlength="10"
show-word-limit
type="textarea"
/>
<el-input v-model="formState.summary" :autosize="{ minRows: 3, maxRows: 6 }" maxlength="200" minlength="10" show-word-limit type="textarea" />
</el-form-item>
<!-- 消息等级 -->
<el-form-item :label="$t('level')" prop="level">
<el-select
v-model="formState.level"
:placeholder="$t('select') + $t('level')"
clearable
filterable
remote
remote-show-suffix
>
<el-select v-model="formState.level" :placeholder="$t('select') + $t('level')" clearable filterable remote remote-show-suffix>
<el-option v-for="item in messageLevel" :key="item" :label="$t(item)" :value="item" />
</el-select>
</el-form-item>

View File

@ -1,13 +1,6 @@
<script lang="ts" setup>
import { onMounted, ref } from 'vue';
import {
auth,
columns,
onDeleteBatch,
onSearch,
selectIds,
updateMarkMessageReceived,
} from '@/views/message-manger/message-received/utils';
import { auth, columns, onDeleteBatch, onSearch, selectIds, updateMarkMessageReceived } from '@/views/message-manger/message-received/utils';
import PureTableBar from '@/components/TableBar/src/bar';
import PureTable from '@pureadmin/table';
import Delete from '@iconify-icons/ep/delete';
@ -63,30 +56,15 @@ onMounted(() => {
<template>
<div class="main">
<ReAuth :value="auth.query">
<el-form
ref="formRef"
:inline="true"
:model="messageReceivedStore.form"
class="search-form bg-bg_color w-[99/100] pl-8 pt-[12px] overflow-auto"
>
<el-form ref="formRef" :inline="true" :model="messageReceivedStore.form" class="search-form bg-bg_color w-[99/100] pl-8 pt-[12px] overflow-auto">
<!-- 消息标题 -->
<el-form-item :label="$t('title')" prop="title">
<el-input
v-model="messageReceivedStore.form.title"
:placeholder="`${$t('input')}${$t('title')}`"
class="!w-[180px]"
clearable
/>
<el-input v-model="messageReceivedStore.form.title" :placeholder="`${$t('input')}${$t('title')}`" class="!w-[180px]" clearable />
</el-form-item>
<!-- 发送人昵称 -->
<el-form-item :label="$t('sendNickname')" prop="sendNickname">
<el-input
v-model="messageReceivedStore.form.sendNickname"
:placeholder="`${$t('input')}${$t('sendNickname')}`"
class="!w-[180px]"
clearable
/>
<el-input v-model="messageReceivedStore.form.sendNickname" :placeholder="`${$t('input')}${$t('sendNickname')}`" class="!w-[180px]" clearable />
</el-form-item>
<!-- 消息类型 -->
@ -110,72 +88,32 @@ onMounted(() => {
<!-- 编辑器类型 -->
<el-form-item :label="$t('editorType')" prop="editorType">
<el-select
v-model="messageReceivedStore.form.editorType"
:placeholder="`${$t('select')}${$t('editorType')}`"
class="!w-[180px]"
clearable
filterable
>
<el-option
v-for="(item, index) in ['rich', 'markdown']"
:key="index"
:label="item"
:navigationBar="false"
:value="item"
/>
<el-select v-model="messageReceivedStore.form.editorType" :placeholder="`${$t('select')}${$t('editorType')}`" class="!w-[180px]" clearable filterable>
<el-option v-for="(item, index) in ['rich', 'markdown']" :key="index" :label="item" :navigationBar="false" :value="item" />
</el-select>
</el-form-item>
<!-- 消息等级 -->
<el-form-item :label="$t('level')" prop="level">
<el-select
v-model="messageReceivedStore.form.level"
:placeholder="$t('level')"
class="!w-[180px]"
clearable
filterable
remote
remote-show-suffix
>
<el-select v-model="messageReceivedStore.form.level" :placeholder="$t('level')" class="!w-[180px]" clearable filterable remote remote-show-suffix>
<el-option v-for="item in messageLevel" :key="item" :label="$t(item)" :value="item" />
</el-select>
</el-form-item>
<!-- 消息等级简介 -->
<el-form-item :label="$t('extra')" prop="extra">
<el-input
v-model="messageReceivedStore.form.extra"
class="!w-[180px]"
maxlength="20"
minlength="10"
show-word-limit
type="text"
/>
<el-input v-model="messageReceivedStore.form.extra" class="!w-[180px]" maxlength="20" minlength="10" show-word-limit type="text" />
</el-form-item>
<!-- 0:未读 1:已读 -->
<el-form-item :label="$t('status')" prop="status">
<el-select
v-model="messageReceivedStore.form.status"
:placeholder="$t('status')"
class="!w-[180px]"
clearable
filterable
remote
remote-show-suffix
>
<el-select v-model="messageReceivedStore.form.status" :placeholder="$t('status')" class="!w-[180px]" clearable filterable remote remote-show-suffix>
<el-option v-for="(item, index) in isReadStatus" :key="index" :label="item.label" :value="item.value" />
</el-select>
</el-form-item>
<el-form-item>
<el-button
:icon="useRenderIcon('ri:search-line')"
:loading="messageReceivedStore.loading"
type="primary"
@click="onSearch"
>
<el-button :icon="useRenderIcon('ri:search-line')" :loading="messageReceivedStore.loading" type="primary" @click="onSearch">
{{ $t('search') }}
</el-button>
<el-button :icon="useRenderIcon(Refresh)" @click="resetForm(formRef)">{{ $t('buttons.reset') }}</el-button>
@ -210,14 +148,7 @@ onMounted(() => {
</el-button>
<!-- 批量删除按钮 -->
<el-button
v-if="hasAuth(auth.delete)"
:disabled="!(selectIds.length > 0)"
:icon="useRenderIcon(Delete)"
plain
type="danger"
@click="onDeleteBatch"
>
<el-button v-if="hasAuth(auth.delete)" :disabled="!(selectIds.length > 0)" :icon="useRenderIcon(Delete)" plain type="danger" @click="onDeleteBatch">
{{ $t('delete_batches') }}
</el-button>
</template>

View File

@ -21,11 +21,7 @@ export const columns: TableColumnList = [
prop: 'editorType',
minWidth: 130,
formatter({ editorType }) {
return editorType === 'rich' ? (
<ElText type={'info'}>{editorType}</ElText>
) : (
<ElText type={'warning'}>{editorType}</ElText>
);
return editorType === 'rich' ? <ElText type={'info'}>{editorType}</ElText> : <ElText type={'warning'}>{editorType}</ElText>;
},
},
// 封面

Some files were not shown because too many files have changed in this diff Show More