style: 格式化代码
This commit is contained in:
parent
ac5c738267
commit
a0a6165ee3
|
@ -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:对象的属性需要加引号才添加;)
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
||||
// 单独处理自定义请求/响应回调
|
||||
|
|
|
@ -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>;
|
||||
|
||||
|
|
|
@ -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' } });
|
||||
};
|
||||
|
||||
/** 系统文件管理---删除系统文件 */
|
||||
|
|
|
@ -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' } });
|
||||
};
|
||||
|
||||
// ------------------------------------------------
|
||||
|
|
|
@ -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' } });
|
||||
};
|
||||
|
|
|
@ -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' } });
|
||||
};
|
||||
|
||||
/** 权限---获取所有权限 */
|
||||
|
|
|
@ -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获取所有角色 */
|
||||
|
|
|
@ -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' } });
|
||||
};
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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)) {
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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' }}
|
||||
|
|
|
@ -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">
|
||||
|
|
|
@ -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`以及默认的 `取消` 和 `确定` 按钮 */
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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]';
|
||||
|
||||
/**
|
||||
* * 拖拽列样式
|
||||
|
|
|
@ -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 />
|
||||
|
|
|
@ -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"');
|
||||
}
|
||||
},
|
||||
};
|
||||
|
|
|
@ -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';
|
||||
|
|
|
@ -84,12 +84,4 @@ const frameLoadingOptions: Array<OptionsType> = [
|
|||
},
|
||||
];
|
||||
|
||||
export {
|
||||
menuTypeOptions,
|
||||
fixedTagOptions,
|
||||
showLinkOptions,
|
||||
keepAliveOptions,
|
||||
hiddenTagOptions,
|
||||
showParentOptions,
|
||||
frameLoadingOptions,
|
||||
};
|
||||
export { menuTypeOptions, fixedTagOptions, showLinkOptions, keepAliveOptions, hiddenTagOptions, showParentOptions, frameLoadingOptions };
|
||||
|
|
|
@ -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);'}`,
|
||||
];
|
||||
});
|
||||
|
||||
|
|
|
@ -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" />
|
||||
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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">
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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') }}
|
||||
|
|
|
@ -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">
|
||||
<!-- 菜单搜索 -->
|
||||
|
|
|
@ -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))" />
|
||||
|
|
|
@ -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>
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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` 主题色 */
|
||||
|
|
|
@ -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;
|
||||
});
|
||||
|
|
|
@ -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">
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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';
|
||||
|
|
|
@ -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';
|
||||
|
|
|
@ -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';
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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';
|
||||
|
|
|
@ -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';
|
||||
|
|
|
@ -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';
|
||||
|
||||
|
|
|
@ -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';
|
||||
|
|
|
@ -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';
|
||||
|
||||
/**
|
||||
|
|
|
@ -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: {
|
||||
|
|
|
@ -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';
|
||||
|
|
|
@ -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({
|
||||
|
|
|
@ -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';
|
||||
|
|
|
@ -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);
|
||||
},
|
||||
},
|
||||
});
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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';
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 } : {});
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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>
|
||||
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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') }}
|
||||
|
|
|
@ -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,
|
||||
},
|
||||
|
|
|
@ -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)">
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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 />
|
||||
|
|
|
@ -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') }}
|
||||
|
|
|
@ -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>
|
||||
|
||||
|
|
|
@ -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>
|
||||
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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') }}
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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') }}
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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>
|
||||
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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
Loading…
Reference in New Issue