mirror of https://github.com/jeecgboot/jeecg-boot
【v3.8.3】前端小改动汇总集合
parent
d76842ae07
commit
4f46213df6
|
@ -1,10 +1,10 @@
|
|||
JeecgBoot 企业级低代码开发平台
|
||||
===============
|
||||
当前最新版本: 3.8.2(预计发布时间:2025-08-04)
|
||||
当前最新版本: 3.8.3(预计发布时间:2025-09-22)
|
||||
|
||||
[](https://github.com/zhangdaiscott/jeecg-boot/blob/master/LICENSE)
|
||||
[](http://jeecg.com/aboutusIndex)
|
||||
[](https://github.com
|
||||
[](https://github.com
|
||||
/zhangdaiscott/jeecg-boot)
|
||||
[](https://github.com/zhangdaiscott/jeecg-boot)
|
||||
[](https://github.com/zhangdaiscott/jeecg-boot)
|
||||
|
|
|
@ -32,6 +32,7 @@ export function wrapperEnv(envConf: Recordable): ViteEnv {
|
|||
try {
|
||||
realName = JSON.parse(realName.replace(/'/g, '"'));
|
||||
} catch (error) {
|
||||
console.log("PARSE VITE PROXY ERROR:", error);
|
||||
realName = '';
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,10 @@
|
|||
import { defHttp } from '/@/utils/http/axios';
|
||||
import { getMenuListResultModel } from './model/menuModel';
|
||||
import { useUserStoreWithOut } from '@/store/modules/user';
|
||||
import { setAuthCache } from '@/utils/auth';
|
||||
import { TOKEN_KEY } from '@/enums/cacheEnum';
|
||||
import { router } from '@/router';
|
||||
import { PageEnum } from '@/enums/pageEnum';
|
||||
|
||||
enum Api {
|
||||
GetMenuList = '/sys/permission/getUserPermissionByToken',
|
||||
|
@ -28,7 +33,21 @@ export const getMenuList = () => {
|
|||
* @description: 获取后台菜单权限和按钮权限
|
||||
*/
|
||||
export function getBackMenuAndPerms() {
|
||||
return defHttp.get({ url: Api.GetMenuList });
|
||||
return defHttp.get({ url: Api.GetMenuList }).catch((e) => {
|
||||
// Token过期失效,直接跳转登录页面 2025-09-08 scott
|
||||
if (e && (e.message.includes('timeout') || e.message.includes('401'))) {
|
||||
const userStore = useUserStoreWithOut();
|
||||
userStore.setToken('');
|
||||
setAuthCache(TOKEN_KEY, null);
|
||||
router.push({
|
||||
path: PageEnum.BASE_LOGIN,
|
||||
query: {
|
||||
// 传入当前的路由,登录成功后跳转到当前路由
|
||||
redirect: router.currentRoute.value.fullPath,
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -81,13 +81,12 @@ export function phoneLoginApi(params: LoginParams, mode: ErrorMessageMode = 'mod
|
|||
export function getUserInfo() {
|
||||
return defHttp.get<GetUserInfoModel>({ url: Api.GetUserInfo }, {}).catch((e) => {
|
||||
// update-begin--author:zyf---date:20220425---for:【VUEN-76】捕获接口超时异常,跳转到登录界面
|
||||
// Token过期失效,直接跳转登录页面
|
||||
if (e && (e.message.includes('timeout') || e.message.includes('401'))) {
|
||||
//接口不通时跳转到登录界面
|
||||
const userStore = useUserStoreWithOut();
|
||||
userStore.setToken('');
|
||||
setAuthCache(TOKEN_KEY, null);
|
||||
|
||||
// update-begin-author:sunjianlei date:20230306 for: 修复登录成功后,没有正确重定向的问题
|
||||
router.push({
|
||||
path: PageEnum.BASE_LOGIN,
|
||||
query: {
|
||||
|
@ -95,8 +94,6 @@ export function getUserInfo() {
|
|||
redirect: router.currentRoute.value.fullPath,
|
||||
}
|
||||
});
|
||||
// update-end-author:sunjianlei date:20230306 for: 修复登录成功后,没有正确重定向的问题
|
||||
|
||||
}
|
||||
// update-end--author:zyf---date:20220425---for:【VUEN-76】捕获接口超时异常,跳转到登录界面
|
||||
});
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 2.1 KiB |
Binary file not shown.
After Width: | Height: | Size: 1.5 KiB |
|
@ -3,6 +3,8 @@
|
|||
v-bind="attrs_"
|
||||
v-model:value="state"
|
||||
:options="getOptions"
|
||||
show-search
|
||||
:filter-option="filterOption"
|
||||
@change="handleChange"
|
||||
@dropdownVisibleChange="handleFetch"
|
||||
@popupScroll="handlePopupScroll"
|
||||
|
@ -152,7 +154,14 @@
|
|||
watchEffect(() => {
|
||||
props.value && handleFetch();
|
||||
});
|
||||
|
||||
/**
|
||||
* 筛选流程
|
||||
* @param input
|
||||
* @param option
|
||||
*/
|
||||
const filterOption = (input: string, option: any) => {
|
||||
return option.value.toLowerCase().indexOf(input.toLowerCase()) >= 0 || option.label.indexOf(input) >= 0;
|
||||
};
|
||||
async function fetch() {
|
||||
const api = props.api;
|
||||
if (!api || !isFunction(api)) return;
|
||||
|
@ -240,7 +249,7 @@
|
|||
}
|
||||
}
|
||||
// update-end--author:liusq---date:20250407---for:【QQYUN-11831】ApiSelect 分页下拉方案 #7883
|
||||
return { state, attrs_, attrs, getOptions, loading, t, handleFetch, handleChange, handlePopupScroll };
|
||||
return { state, attrs_, attrs, getOptions, loading, t, handleFetch, handleChange, handlePopupScroll,filterOption };
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
|
|
@ -492,7 +492,6 @@
|
|||
|
||||
const showSuffix = !!suffix;
|
||||
const getSuffix = isFunction(suffix) ? suffix(unref(getValues)) : suffix;
|
||||
|
||||
return (
|
||||
<Form.Item
|
||||
name={field}
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
@change="onChange"
|
||||
@search="onSearch"
|
||||
:tree-checkable="treeCheckAble"
|
||||
:tagRender="tagRender"
|
||||
>
|
||||
<template #[name]="data" v-for="name in slotNamesGroup" :key="name">
|
||||
<slot :name="name" v-bind="data"></slot>
|
||||
|
@ -63,6 +64,10 @@
|
|||
treeCheckAble: propTypes.bool.def(false),
|
||||
//update-end---author:wangshuai date: 20230202 for: 新增是否有复选框
|
||||
hiddenNodeKey: propTypes.string.def(''),
|
||||
//update-begin---author:wangshuai---date:2025-09-06---for: 多选时渲染tag文本,为空不渲染,不支持单选---
|
||||
//多选时渲染tag文本
|
||||
tagRender: propTypes.func,
|
||||
//update-end---author:wangshuai---date:2025-09-06---for:多选时渲染tag文本,为空不渲染,不支持单选---
|
||||
});
|
||||
const attrs = useAttrs();
|
||||
const { t } = useI18n();
|
||||
|
|
|
@ -0,0 +1,96 @@
|
|||
<template>
|
||||
<div>
|
||||
<svg
|
||||
class="svg-company"
|
||||
v-if="orgCategory && (orgCategory === '1' || orgCategory === '4')"
|
||||
viewBox="0 0 1024 1024"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="256"
|
||||
height="256"
|
||||
>
|
||||
<path
|
||||
d="M234.9 226.9c0-25.9 25.1-46.9 56-46.9h226.9c30.5 0 55.3 21.1 55.3 46.9v580.9h40V340.2h132.5c25.9 0 46.9 21.1 46.9 46.9v413.5h40V387.2c0-47.9-39-86.9-86.9-86.9H613v-73.4c0-23.7-10.2-45.8-28.7-62.3-17.9-15.9-41.5-24.7-66.6-24.7H290.9c-52.9 0-96 39-96 86.9v580.9h40V226.9zM145.8 841.2h734.9v40H145.8z"
|
||||
fill="#333333"
|
||||
p-id="10104"
|
||||
></path>
|
||||
<path
|
||||
d="M286.9 354.1h124.7v40H286.9zM448.1 353.9h63.2v40h-63.2zM286.9 489.1h124.7v40H286.9zM448.1 488.9h63.2v40h-63.2zM286.9 616.6h124.7v40H286.9zM448.1 616.3h63.2v40h-63.2zM638.5 433.1h71v40h-71zM730.2 433h36v40h-36zM638.5 557.9h71v40h-71zM730.2 557.7h36v40h-36zM638.5 684.7h71v40h-71zM730.2 684.5h36v40h-36z"
|
||||
fill="#333333"
|
||||
></path>
|
||||
</svg>
|
||||
<svg class="svg-depart" v-if="orgCategory === '2'" viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" width="256" height="256">
|
||||
<path
|
||||
d="M192 384H64V64h320v320H256v256h128v128h384V512h-128V192h320v320h-128v320H384v128H64v-320h128V384z m128 320H128v192h192v-192z m576-448h-192v192h192V256zM320 128H128v192h192V128z"
|
||||
p-id="8946"
|
||||
></path>
|
||||
</svg>
|
||||
<svg
|
||||
class="svg-post"
|
||||
v-if="orgCategory === '3'"
|
||||
viewBox="0 0 1024 1024"
|
||||
version="1.1"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
p-id="11309"
|
||||
width="256"
|
||||
height="256"
|
||||
>
|
||||
<path
|
||||
d="M866.346667 89.6H207.573333C167.253333 89.6 134.4 122.453333 134.4 162.773333v146.346667h64V162.773333c0-5.12 4.266667-9.173333 9.173333-9.173333h658.773334c5.12 0 9.173333 4.053333 9.173333 9.173333v699.946667c0 5.12-4.053333 9.173333-9.173333 9.173333H207.573333c-5.12 0-9.173333-4.053333-9.173333-9.173333v-144h-64v144c0 40.32 32.853333 73.173333 73.173333 73.173333h658.773334c40.32 0 73.173333-32.853333 73.173333-73.173333V162.773333c0-40.32-32.853333-73.173333-73.173333-73.173333z"
|
||||
p-id="11310"
|
||||
></path>
|
||||
<path
|
||||
d="M134.4 428.16h64V597.333333h-64zM120.96 400.64h82.346667c17.706667 0 32-14.293333 32-32s-14.293333-32-32-32H120.96c-17.706667 0-32 14.293333-32 32s14.506667 32 32 32zM233.386667 657.493333c0-17.706667-14.293333-32-32-32H119.04c-17.706667 0-32 14.293333-32 32s14.293333 32 32 32h82.346667c17.706667 0 32-14.293333 32-32zM384.213333 655.146667l146.346667 139.306666c6.186667 5.973333 14.08 8.746667 21.973333 8.746667s15.786667-2.986667 21.973334-8.746667l148.053333-139.306666c8.746667-8.106667 12.16-20.48 8.746667-32l-64.853334-228.053334 39.68-122.666666c3.2-9.813333 1.493333-20.48-4.48-28.586667s-15.573333-13.226667-25.813333-13.226667H428.586667a31.872 31.872 0 0 0-30.293334 41.813334l40.96 126.933333-63.786666 224c-3.2 11.306667 0.213333 23.68 8.746666 31.786667z m168.533334 72.32l-110.506667-105.173334 56.96-199.893333h108.373333l56.96 199.893333-111.786666 105.173334z m78.933333-432.64l-19.413333 60.16h-120.32l-19.413334-60.16h159.146667z"
|
||||
p-id="11311"
|
||||
></path>
|
||||
</svg>
|
||||
<span :title="title">{{ title }}</span>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { defineProps } from 'vue';
|
||||
const props = defineProps({
|
||||
orgCategory: String,
|
||||
title: String,
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped lang="less">
|
||||
.svg-company {
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
position: relative;
|
||||
top: 2px;
|
||||
right: 2px;
|
||||
}
|
||||
.svg-depart,
|
||||
.svg-post {
|
||||
width: 14px;
|
||||
height: 16px;
|
||||
position: relative;
|
||||
top: 3px;
|
||||
right: 2px;
|
||||
}
|
||||
html[data-theme='light'] {
|
||||
.svg-post{
|
||||
path { fill: #333333; }
|
||||
}
|
||||
.svg-company{
|
||||
path { fill: #333333; }
|
||||
}
|
||||
.svg-depart{
|
||||
path { fill: #333333; }
|
||||
}
|
||||
}
|
||||
html[data-theme='dark'] {
|
||||
.svg-post{
|
||||
path { fill: #ffffff; }
|
||||
}
|
||||
.svg-company{
|
||||
path { fill: #ffffff; }
|
||||
}
|
||||
.svg-depart{
|
||||
path { fill: #ffffff; }
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -171,6 +171,7 @@
|
|||
component: (hasCustomApi.value && !props.customApiJInput) ? 'Input' : 'JInput',
|
||||
},
|
||||
],
|
||||
autoSubmitOnEnter: true
|
||||
};
|
||||
//定义表格列
|
||||
const columns = [
|
||||
|
|
|
@ -382,6 +382,9 @@
|
|||
getSize: () => {
|
||||
return unref(getBindValues).size as SizeType;
|
||||
},
|
||||
// update-begin--author:liaozhiyang---date:20250904---for:【QQYUN-13558】erp风格主表在5条数据时也有滚动条
|
||||
getBindValuesRef: () => getBindValues,
|
||||
// update-end--author:liaozhiyang---date:20250904---for:【QQYUN-13558】erp风格主表在5条数据时也有滚动条
|
||||
};
|
||||
createTableContext({ ...tableAction, wrapRef, getBindValues });
|
||||
|
||||
|
|
|
@ -7,12 +7,12 @@
|
|||
<template v-else>
|
||||
<Tooltip v-if="action.tooltip" v-bind="getTooltip(action.tooltip)">
|
||||
<PopConfirmButton v-bind="action">
|
||||
<Icon :icon="action.icon" :class="{ 'mr-1': !!action.label }" v-if="action.icon" :color="action.iconColor"/>
|
||||
<Icon :icon="action.icon" :class="{ 'mr-1': !!action.label }" v-if="action.icon" />
|
||||
<template v-if="action.label">{{ action.label }}</template>
|
||||
</PopConfirmButton>
|
||||
</Tooltip>
|
||||
<PopConfirmButton v-else v-bind="action">
|
||||
<Icon :icon="action.icon" :class="{ 'mr-1': !!action.label }" v-if="action.icon" :color="action.iconColor"/>
|
||||
<Icon :icon="action.icon" :class="{ 'mr-1': !!action.label }" v-if="action.icon" />
|
||||
<template v-if="action.label">{{ action.label }}</template>
|
||||
</PopConfirmButton>
|
||||
</template>
|
||||
|
|
|
@ -121,6 +121,7 @@ export interface TableActionType {
|
|||
getShowPagination: () => boolean;
|
||||
setCacheColumnsByField?: (dataIndex: string | undefined, value: BasicColumn) => void;
|
||||
getColumnsRef: () => ComputedRef<BasicColumn[]>;
|
||||
getBindValuesRef: () => ComputedRef<any>;
|
||||
}
|
||||
|
||||
export interface FetchSetting {
|
||||
|
|
|
@ -129,7 +129,7 @@
|
|||
}
|
||||
|
||||
function getMyAvatar(){
|
||||
return userInfo.avatar;
|
||||
return getFileAccessHttpUrl(userInfo.avatar);
|
||||
}
|
||||
|
||||
// 获取头像
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
<upload-chunk ref="uploadRef" :visible="uploadVisible" @select="selectFirstFile"></upload-chunk>
|
||||
</div>
|
||||
<UserSelectModal rowKey="username" @register="registerModal" @selected="setValue" :multi="false"></UserSelectModal>
|
||||
<a-modal v-model:open="visibleEmoji" :footer="null" wrapClassName="emoji-modal" :closable="false" :width="490">
|
||||
<a-modal v-model:open="visibleEmoji" :footer="null" wrapClassName="emoji-modal" :closable="false" :width="460">
|
||||
<template #title>
|
||||
<span></span>
|
||||
</template>
|
||||
|
@ -235,7 +235,7 @@
|
|||
}
|
||||
|
||||
const pickerStyles = {
|
||||
width: '490px'
|
||||
width: '460px'
|
||||
/* height: '350px',
|
||||
top: '0px',
|
||||
left: '-75px',
|
||||
|
|
|
@ -16,10 +16,7 @@ interface ListPageOptions {
|
|||
// 样式作用域范围
|
||||
designScope?: string;
|
||||
// 【必填】表格参数配置
|
||||
tableProps: TableProps & {
|
||||
// 添加 defSort 类型定义
|
||||
defSort?: DefSort;
|
||||
};
|
||||
tableProps: TableProps;
|
||||
// 是否分页
|
||||
pagination?: boolean;
|
||||
// 导出配置
|
||||
|
@ -49,11 +46,6 @@ interface IDoRequestOptions {
|
|||
clearSelection?: boolean;
|
||||
}
|
||||
|
||||
interface DefSort {
|
||||
column: string;
|
||||
order: 'asc' | 'desc';
|
||||
}
|
||||
|
||||
/**
|
||||
* listPage页面公共方法
|
||||
*
|
||||
|
@ -93,17 +85,8 @@ export function useListPage(options: ListPageOptions) {
|
|||
//update-end-author:taoyan date:20220507 for: erp代码生成 子表 导出报错,原因未知-
|
||||
|
||||
//update-begin-author:liusq date:20230410 for:[/issues/409]导出功能没有按排序结果导出,设置导出默认排序,创建时间倒序
|
||||
// 获取表格的默认排序
|
||||
const { defSort } = options?.tableProps ?? {};
|
||||
if (defSort && !paramsForm?.column) {
|
||||
// 使用类型断言确保 defSort 类型正确
|
||||
Object.assign(paramsForm, {
|
||||
column: (defSort as DefSort).column,
|
||||
order: (defSort as DefSort).order,
|
||||
});
|
||||
} else if (!paramsForm?.column) {
|
||||
// 如果没有默认排序,则使用创建时间倒序
|
||||
Object.assign(paramsForm, { column: 'createTime', order: 'desc' });
|
||||
if(!paramsForm?.column){
|
||||
Object.assign(paramsForm,{column:'createTime',order:'desc'});
|
||||
}
|
||||
//update-begin-author:liusq date:20230410 for: [/issues/409]导出功能没有按排序结果导出,设置导出默认排序,创建时间倒序
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<BasicModal v-bind="$attrs" @register="registerModal" :title="title" @ok="handleSubmit" width="600px">
|
||||
<BasicModal v-bind="$attrs" @register="registerModal" :title="title" @ok="handleSubmit" width="500px" :bodyStyle="{ padding: '20px 40px 20px 20px'}">
|
||||
<BasicForm @register="registerForm" />
|
||||
</BasicModal>
|
||||
</template>
|
||||
|
|
|
@ -35,7 +35,7 @@
|
|||
// components
|
||||
import { Dropdown, Menu } from 'ant-design-vue';
|
||||
|
||||
import { defineComponent, computed, ref, nextTick } from 'vue';
|
||||
import { defineComponent, computed, ref } from 'vue';
|
||||
|
||||
import { SITE_URL } from '/@/settings/siteSetting';
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@ import { PAGE_NOT_FOUND_ROUTE, REDIRECT_ROUTE } from '/@/router/routes/basic';
|
|||
import { mainOutRoutes } from './mainOut';
|
||||
import { PageEnum } from '/@/enums/pageEnum';
|
||||
import { t } from '/@/hooks/web/useI18n';
|
||||
import { LAYOUT } from '/@/router/constant';
|
||||
|
||||
const modules = import.meta.glob('./modules/**/*.ts', { eager: true });
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@ import { merge, random } from 'lodash-es';
|
|||
import { isArray } from '/@/utils/is';
|
||||
import { FormSchema } from '/@/components/Form';
|
||||
import { reactive } from "vue";
|
||||
import { getTenantId, getToken } from "/@/utils/auth";
|
||||
import { getTenantId, getToken, getAuthCache, setAuthCache } from "/@/utils/auth";
|
||||
import { useUserStoreWithOut } from "/@/store/modules/user";
|
||||
import dayjs from 'dayjs';
|
||||
import Big from 'big.js';
|
||||
|
@ -609,3 +609,28 @@ export function freezeDeep(obj: Recordable | Recordable[]) {
|
|||
}
|
||||
return obj
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取父级名称
|
||||
*
|
||||
* @param orgCode 当前部门的code
|
||||
* @param label 当前默认显示的值
|
||||
* @param depId depId
|
||||
* @return 部门名称
|
||||
*/
|
||||
export async function getDepartPathNameByOrgCode(orgCode, label, depId){
|
||||
let key:any = "DEPARTNAME" + depId + orgCode;
|
||||
let authCache = getAuthCache(key);
|
||||
if (authCache) {
|
||||
return authCache;
|
||||
}
|
||||
if (orgCode) {
|
||||
depId = "";
|
||||
}
|
||||
let result = await defHttp.get({ url: "/sys/sysDepart/getDepartPathNameByOrgCode", params:{ orgCode: orgCode, depId: depId } }, { isTransformResponse: false });
|
||||
if (result.success) {
|
||||
setAuthCache(key,result.result);
|
||||
return result.result;
|
||||
}
|
||||
return label;
|
||||
}
|
||||
|
|
|
@ -39,7 +39,7 @@ export default class signMd5Utils {
|
|||
//update-end---author:wangshuai---date:2024-04-16---for:【QQYUN-9005】发送短信加签---
|
||||
let requestBody = this.sortAsc(jsonObj);
|
||||
delete requestBody._t;
|
||||
console.log('sign requestBody:', requestBody);
|
||||
// console.log('sign requestBody:', requestBody);
|
||||
return md5(JSON.stringify(requestBody) + signatureSecret).toUpperCase();
|
||||
}
|
||||
|
||||
|
|
|
@ -58,6 +58,9 @@
|
|||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<a v-if="noticeFiles.length > 1" :href="downLoadFiles + '?id=' + content.id + '&token=' + getToken()" target="_blank" style="margin: 15px 6px; color: #5ac0fa">
|
||||
<download-outlined class="item-icon" style="margin-right: 5px" /><span>批量下载所有附件</span>
|
||||
</a>
|
||||
</template>
|
||||
</BasicModal>
|
||||
</template>
|
||||
|
@ -72,15 +75,21 @@
|
|||
import { getFileAccessHttpUrl } from '@/utils/common/compUtils';
|
||||
import { useGlobSetting } from '@/hooks/setting';
|
||||
import { encryptByBase64 } from '@/utils/cipher';
|
||||
import { getToken } from '@/utils/auth';
|
||||
const router = useRouter();
|
||||
const glob = useGlobSetting();
|
||||
const isUpdate = ref(true);
|
||||
const content = ref<any>({});
|
||||
const noticeFiles = ref([]);
|
||||
/**
|
||||
* 下载文件路径
|
||||
*/
|
||||
const downLoadFiles = `${glob.domainUrl}/sys/annountCement/downLoadFiles`;
|
||||
const emit = defineEmits(['close', 'register']);
|
||||
//表单赋值
|
||||
const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
|
||||
isUpdate.value = !!data?.isUpdate;
|
||||
noticeFiles.value = [];
|
||||
if (unref(isUpdate)) {
|
||||
//data.record.msgContent = '<p>2323</p><input onmouseover=alert(1)>xss test';
|
||||
//update-begin-author:taoyan date:2022-7-14 for: VUEN-1702 【禁止问题】sql注入漏洞
|
||||
|
@ -194,6 +203,24 @@
|
|||
padding: 0;
|
||||
}
|
||||
}
|
||||
.ant-card-meta-detail {
|
||||
display: flex !important ;
|
||||
justify-content: center !important;
|
||||
align-items: center !important;
|
||||
flex-direction: column !important;
|
||||
}
|
||||
.ant-card-meta-title {
|
||||
font-size: 22px !important;
|
||||
color: rgba(51, 51, 51, 0.88);
|
||||
font-weight: 600;
|
||||
font-size: 16px;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
.ant-card .ant-card-meta-description {
|
||||
color: rgba(51, 51, 51, 0.45);
|
||||
}
|
||||
`;
|
||||
frameDoc.head.appendChild(style);
|
||||
|
||||
|
@ -273,8 +300,8 @@
|
|||
|
||||
.print-btn {
|
||||
position: absolute;
|
||||
top: 20px;
|
||||
right: 20px;
|
||||
top: 80px;
|
||||
right: 40px;
|
||||
cursor: pointer;
|
||||
color: #a3a3a5;
|
||||
z-index: 999;
|
||||
|
|
|
@ -78,4 +78,4 @@ export const deleteThirdAppConfig = (params, handleSuccess) => {
|
|||
return defHttp.delete({ url: Api.deleteThirdAppConfig, params }, { joinParamsToUrl: true }).then(() => {
|
||||
handleSuccess();
|
||||
});
|
||||
};
|
||||
};
|
|
@ -335,7 +335,7 @@
|
|||
searchParams.realname = options[0].label;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function openSelectPerson(){
|
||||
openModal(true, {})
|
||||
}
|
||||
|
|
|
@ -161,7 +161,7 @@ export function useSysMessage(setLocaleText) {
|
|||
}
|
||||
}
|
||||
return '去处理'
|
||||
}else{
|
||||
} else {
|
||||
return '查看详情'
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,6 +28,9 @@
|
|||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<a v-if="noticeFiles.length > 1" :href="downLoadFiles + '?id=' + noticeId + '&token=' + getToken()" target="_blank" style="margin: 15px 6px;color: #5ac0fa;">
|
||||
<download-outlined class="item-icon" style="margin-right: 5px" /><span>批量下载所有附件</span>
|
||||
</a>
|
||||
</template>
|
||||
</BasicModal>
|
||||
</template>
|
||||
|
@ -40,16 +43,25 @@
|
|||
import { DownloadOutlined, EyeOutlined, PaperClipOutlined } from '@ant-design/icons-vue';
|
||||
import { encryptByBase64 } from '@/utils/cipher';
|
||||
import { useGlobSetting } from '@/hooks/setting';
|
||||
import { getToken } from "@/utils/auth";
|
||||
const glob = useGlobSetting();
|
||||
// 获取props
|
||||
defineProps({
|
||||
frameSrc: propTypes.string.def(''),
|
||||
});
|
||||
/**
|
||||
* 下载文件路径
|
||||
*/
|
||||
const downLoadFiles = `${glob.domainUrl}/sys/annountCement/downLoadFiles`;
|
||||
|
||||
//附件内容
|
||||
const noticeFiles = ref([]);
|
||||
//数据ID
|
||||
const noticeId = ref('');
|
||||
//表单赋值
|
||||
const [registerModal] = useModalInner((data) => {
|
||||
noticeFiles.value = [];
|
||||
noticeId.value = data.record.id;
|
||||
if (data.record?.files && data.record?.files.length > 0) {
|
||||
noticeFiles.value = data.record.files.split(',').map((item) => {
|
||||
return {
|
||||
|
@ -96,8 +108,8 @@
|
|||
<style scoped lang="less">
|
||||
.print-btn {
|
||||
position: absolute;
|
||||
top: 20px;
|
||||
right: 20px;
|
||||
top: 80px;
|
||||
right: 40px;
|
||||
cursor: pointer;
|
||||
color: #a3a3a5;
|
||||
z-index: 999;
|
||||
|
|
|
@ -52,6 +52,13 @@
|
|||
...data.record,
|
||||
});
|
||||
record.value = data.record;
|
||||
} else {
|
||||
// update-begin--author:liaozhiyang---date:20250807---for:【JHHB-128】转公告
|
||||
//表单赋值
|
||||
await setFieldsValue({
|
||||
...data.record,
|
||||
});
|
||||
// update-end--author:liaozhiyang---date:20250807---for:【JHHB-128】转公告
|
||||
}
|
||||
});
|
||||
//设置标题
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
</div>
|
||||
</template>
|
||||
<script lang="ts" name="system-notice" setup>
|
||||
import { ref } from 'vue';
|
||||
import { ref, onMounted } from 'vue';
|
||||
import { BasicTable, TableAction } from '/@/components/Table';
|
||||
import { useModal } from '/@/components/Modal';
|
||||
import NoticeModal from './NoticeModal.vue';
|
||||
|
@ -40,6 +40,9 @@
|
|||
import { columns, searchFormSchema } from './notice.data';
|
||||
import { getList, deleteNotice, batchDeleteNotice,editIzTop, getExportUrl, getImportUrl, doReleaseData, doReovkeData } from './notice.api';
|
||||
import { useListPage } from '/@/hooks/system/useListPage';
|
||||
import { useAppStore } from '/@/store/modules/app';
|
||||
|
||||
const appStore = useAppStore();
|
||||
const glob = useGlobSetting();
|
||||
const [registerModal, { openModal }] = useModal();
|
||||
const [register, { openModal: openDetail }] = useModal();
|
||||
|
@ -71,9 +74,10 @@
|
|||
/**
|
||||
* 新增事件
|
||||
*/
|
||||
function handleAdd() {
|
||||
function handleAdd(record = {}) {
|
||||
openModal(true, {
|
||||
isUpdate: false,
|
||||
record,
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -192,4 +196,15 @@
|
|||
},
|
||||
];
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
// update-begin--author:liaozhiyang---date:20250807---for:【JHHB-128】转公告
|
||||
const params = appStore.getMessageHrefParams;
|
||||
if (params?.add) {
|
||||
delete params.add;
|
||||
handleAdd(params);
|
||||
appStore.setMessageHrefParams('');
|
||||
}
|
||||
// update-begin--author:liaozhiyang---date:20250807---for:【JHHB-128】转公告
|
||||
});
|
||||
</script>
|
||||
|
|
|
@ -12,9 +12,7 @@ enum Api {
|
|||
releaseData = '/sys/annountCement/doReleaseData',
|
||||
reovkeData = '/sys/annountCement/doReovkeData',
|
||||
editIzTop = '/sys/annountCement/editIzTop',
|
||||
|
||||
addVisitsNum = '/sys/annountCement/addVisitsNumber',
|
||||
|
||||
tempList = '/sys/message/sysMessageTemplate/list',
|
||||
}
|
||||
|
||||
|
@ -88,12 +86,6 @@ export const addVisitsNum = (params) => defHttp.get({ url: Api.addVisitsNum, par
|
|||
* @param id
|
||||
*/
|
||||
export const queryById = (params) => defHttp.get({ url: Api.queryById, params }, { isTransformResponse: false });
|
||||
/**
|
||||
* 发起流程
|
||||
* import { startProcess } from '/@/api/common/api';
|
||||
* @param params
|
||||
*/
|
||||
export const startProcess = (params) => defHttp.post({ url: Api.startProcess, params }, { isTransformResponse: false });
|
||||
/**
|
||||
* 查询模板列表
|
||||
* @param params
|
||||
|
|
|
@ -3,7 +3,10 @@
|
|||
<template #title>
|
||||
角色权限配置
|
||||
<a-dropdown>
|
||||
<Icon icon="ant-design:more-outlined" class="more-icon" />
|
||||
<a-button class="more-icon">
|
||||
更多操作
|
||||
<Icon icon="ant-design:down-outlined" size="14px" style="position: relative;top: 1px;right: 5px"></Icon>
|
||||
</a-button>
|
||||
<template #overlay>
|
||||
<a-menu @click="treeMenuClick">
|
||||
<a-menu-item key="checkAll">选择全部</a-menu-item>
|
||||
|
@ -294,9 +297,9 @@
|
|||
border-bottom: 1px solid #f0f0f0;
|
||||
}
|
||||
.more-icon {
|
||||
font-size: 20px !important;
|
||||
/* font-size: 20px !important;
|
||||
color: black;
|
||||
display: inline-flex;
|
||||
display: inline-flex;*/
|
||||
float: right;
|
||||
margin-right: 2px;
|
||||
cursor: pointer;
|
||||
|
|
|
@ -57,7 +57,14 @@ export const searchUserFormSchema: FormSchema[] = [
|
|||
field: 'username',
|
||||
label: '用户账号',
|
||||
component: 'Input',
|
||||
colProps: { span: 12 },
|
||||
colProps: { span: 8 },
|
||||
labelWidth: 74,
|
||||
},
|
||||
{
|
||||
field: 'realname',
|
||||
label: '用户名称',
|
||||
component: 'Input',
|
||||
colProps: { span: 8 },
|
||||
labelWidth: 74,
|
||||
},
|
||||
];
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
@change="updateAvatar"
|
||||
width="80"
|
||||
/>
|
||||
<div class="account-right">
|
||||
<div class="account-right border-bottom">
|
||||
<div v-if="!isEdit">
|
||||
<span class="font-size-17 account-name">{{ userInfo.realname }}</span>
|
||||
<a-tooltip content="编辑姓名">
|
||||
|
@ -27,7 +27,7 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="account-data">
|
||||
<div class="account-data border-bottom">
|
||||
<!-- 详细资料 -->
|
||||
<div class="account-detail">
|
||||
<div class="font-size-15 font-bold font-color-gray" style="margin-bottom: 16px">详细资料</div>
|
||||
|
@ -61,6 +61,47 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="account-data">
|
||||
<!-- 个性签名 -->
|
||||
<div class="account-detail">
|
||||
<div class="font-size-15 font-bold font-color-gray" style="margin-bottom: 16px">个性签名</div>
|
||||
<div class="font-size-13 flex">
|
||||
<span class="gray-75 item-label">签名</span>
|
||||
<a-upload
|
||||
accept="jpg,jpeg,png"
|
||||
:max-count="1"
|
||||
:multiple="false"
|
||||
name = "file"
|
||||
:headers="uploadHeader"
|
||||
:action="uploadUrl"
|
||||
v-model:fileList="uploadFileList"
|
||||
@beforeUpload="beforeUpload"
|
||||
@change="handleChange"
|
||||
list-type="picture-card"
|
||||
@preview="handlePreview"
|
||||
>
|
||||
<div v-if="uploadVisible">
|
||||
<UploadOutlined></UploadOutlined>
|
||||
<div class="ant-upload-text">上传</div>
|
||||
</div>
|
||||
</a-upload>
|
||||
<a-modal :width="500" :open="previewVisible" :footer="null" @cancel="handleCancel">
|
||||
<img alt="example" style="width: 100%" :src="previewImage" />
|
||||
</a-modal>
|
||||
</div>
|
||||
<div style="font-size: 12px;color:#93a6aa" class="margin-bottom-10">
|
||||
<p>建议上传尺寸为200*80,大小不超过1M且格式为png或jpeg的图片</p>
|
||||
<p>生成签名方法一:手写扫描进行上传。</p>
|
||||
<p>生成签名方法二:使用在线转换,生成后进行上传。
|
||||
<a href="http://www.diyiziti.com/qianming" target="_blank">http://www.diyiziti.com/qianming</a>
|
||||
</p>
|
||||
</div>
|
||||
<div class="margin-bottom-10 font-size-13 flex" style="margin-top: 10px">
|
||||
<span class="gray-75 item-label">开启状态</span>
|
||||
<a-switch v-model:checked="userInfo.signEnable" :checkedValue="1" :unCheckedValue="0" @change="handleEnableSignChange"></a-switch>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<UserAccountModal @register="registerModal" @success="getUserDetail"></UserAccountModal>
|
||||
</template>
|
||||
|
@ -73,7 +114,7 @@ import headerImg from '/@/assets/images/header.jpg';
|
|||
import { defHttp } from '/@/utils/http/axios';
|
||||
import { useUserStore } from '/@/store/modules/user';
|
||||
import { uploadImg } from '/@/api/sys/upload';
|
||||
import { getFileAccessHttpUrl } from '/@/utils/common/compUtils';
|
||||
import { getFileAccessHttpUrl, getRandom } from '/@/utils/common/compUtils';
|
||||
import dayjs from 'dayjs';
|
||||
import { ajaxGetDictItems, getDictItemsByCode, initDictOptions } from '/@/utils/dict';
|
||||
import { userEdit, getUserData, queryNameByCodes } from './UserSetting.api';
|
||||
|
@ -81,6 +122,10 @@ import UserAccountModal from './commponents/UserAccountModal.vue';
|
|||
import { useModal } from '/@/components/Modal';
|
||||
import { cloneDeep } from 'lodash-es';
|
||||
import { useDesign } from '/@/hooks/web/useDesign';
|
||||
import { getToken } from "@/utils/auth";
|
||||
import { uploadUrl } from "@/api/common/api";
|
||||
import { UploadOutlined } from "@ant-design/icons-vue";
|
||||
|
||||
//TODO 当字典租户隔离时,数据会查不到,默认一个
|
||||
const sexOption = getDictItemsByCode("sex") || [{text:'男',value:'1'},{text:'女',value:'2'}];
|
||||
const { createMessage } = useMessage();
|
||||
|
@ -97,6 +142,26 @@ const [registerModal, { openModal }] = useModal();
|
|||
const avatar = computed(() => {
|
||||
return getFileAccessHttpUrl(userInfo.value.avatar) || headerImg;
|
||||
});
|
||||
//headers
|
||||
const uploadHeader = computed(() => {
|
||||
let headers = {};
|
||||
headers['X-Access-Token'] = getToken();
|
||||
return headers;
|
||||
});
|
||||
const { createMessage: $message } = useMessage();
|
||||
//上传列表
|
||||
const uploadFileList = ref<any>([]);
|
||||
//计算是否可以继续上传
|
||||
const uploadVisible = computed(() => {
|
||||
if(!uploadFileList){
|
||||
return true;
|
||||
}
|
||||
return uploadFileList.value.length < 1;
|
||||
});
|
||||
//图片预览
|
||||
const previewVisible = ref<boolean>(false);
|
||||
//图片预览路径
|
||||
const previewImage = ref<string>('');
|
||||
|
||||
/**
|
||||
* 更新用户头像
|
||||
|
@ -183,6 +248,7 @@ function openEditModal() {
|
|||
* 获取用户信息
|
||||
*/
|
||||
function getUserDetail() {
|
||||
uploadFileList.value = [];
|
||||
getUserData().then((async res => {
|
||||
if (res.success) {
|
||||
if (res.result) {
|
||||
|
@ -190,6 +256,20 @@ function getUserDetail() {
|
|||
res.result.birthday = getBirthDay(res.result.birthday);
|
||||
res.result.createTimeText = getDiffDay(res.result.createTime);
|
||||
userInfo.value = res.result;
|
||||
if(userInfo.value.sign){
|
||||
let sign = userInfo.value.sign;
|
||||
let url = getFileAccessHttpUrl(sign);
|
||||
uploadFileList.value.push({
|
||||
uid: getRandom(10),
|
||||
name: getFileName(sign),
|
||||
status: 'done',
|
||||
url: url,
|
||||
response: {
|
||||
status: 'history',
|
||||
message: sign,
|
||||
},
|
||||
})
|
||||
}
|
||||
} else {
|
||||
userInfo.value = {};
|
||||
}
|
||||
|
@ -211,6 +291,112 @@ function getDiffDay(date) {
|
|||
totalDays = Math.floor(diffDate / (1000 * 3600 * 24)) // 向下取整
|
||||
return totalDays+" 天";
|
||||
}
|
||||
|
||||
/**
|
||||
* 上传图片之前进行验证
|
||||
*
|
||||
* @param file
|
||||
*/
|
||||
function beforeUpload({ file }) {
|
||||
const isJpgOrPng = file.type === "image/jpeg" || file.type === "image/png" || file.type === "image/jpg";
|
||||
if (!isJpgOrPng) {
|
||||
$message.error("上传文件格式只能是jpg/png");
|
||||
return false;
|
||||
}
|
||||
const isLimit = file.size / 1024 / 1024 < 1;
|
||||
if (!isLimit) {
|
||||
$message.error("上传图片大小不能超过 1MB!");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 上传成功事件
|
||||
*/
|
||||
function handleChange({ file, fileList }) {
|
||||
if (file.status === 'error') {
|
||||
createMessage.error(`${file.name} 上传失败.`);
|
||||
}
|
||||
if (file.status === 'done' && file.response.success === false) {
|
||||
const failIndex = uploadFileList.value.findIndex((item) => item.uid === file.uid);
|
||||
if (failIndex != -1) {
|
||||
uploadFileList.value.splice(failIndex, 1);
|
||||
}
|
||||
createMessage.warning(file.response.message);
|
||||
return;
|
||||
}
|
||||
if (file.status != 'uploading') {
|
||||
fileList.forEach((file) => {
|
||||
if (file.status === 'done') {
|
||||
//上传成功事件
|
||||
uploadSuccess(file.response.message);
|
||||
}
|
||||
});
|
||||
if (file.status === 'removed') {
|
||||
handleDelete();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 移除
|
||||
*/
|
||||
function handleDelete() {
|
||||
updateUser({ sign: "", id: userInfo.value.id },"删除个性签名成功")
|
||||
}
|
||||
|
||||
/**
|
||||
* 上传成功事件
|
||||
* @param url
|
||||
*/
|
||||
function uploadSuccess(url) {
|
||||
updateUser({ sign: url, id: userInfo.value.id },"上传个性签名成功")
|
||||
}
|
||||
|
||||
function updateUser(params,message) {
|
||||
userEdit(params).then((res) => {
|
||||
if(res.success){
|
||||
createMessage.success(message);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 图片预览
|
||||
* @param file
|
||||
*/
|
||||
function handlePreview(file) {
|
||||
previewImage.value = file.url || file.thumbUrl;
|
||||
previewVisible.value = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取文件名
|
||||
* @param path
|
||||
*/
|
||||
function getFileName(path) {
|
||||
if (path.lastIndexOf('\\') >= 0) {
|
||||
let reg = new RegExp('\\\\', 'g');
|
||||
path = path.replace(reg, '/');
|
||||
}
|
||||
return path.substring(path.lastIndexOf('/') + 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* 图片预览关闭
|
||||
*/
|
||||
function handleCancel() {
|
||||
previewVisible.value = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 个性签名开启状态更新
|
||||
*/
|
||||
function handleEnableSignChange() {
|
||||
updateUser({ signEnable: userInfo.value.signEnable, id: userInfo.value.id },"修改成功")
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
getUserDetail();
|
||||
});
|
||||
|
@ -347,6 +533,19 @@ onMounted(async () => {
|
|||
.font-size-13 {
|
||||
font-size: 13px;
|
||||
}
|
||||
.ant-upload-select,.ant-upload-list-item-container{
|
||||
width: 200px !important;
|
||||
height: 80px !important;
|
||||
}
|
||||
.ant-upload-list-item-thumbnail .ant-upload-list-item-image {
|
||||
object-fit: cover !important;
|
||||
}
|
||||
p{
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
.border-bottom{
|
||||
border-bottom: 1px solid @border-color-base;
|
||||
}
|
||||
}
|
||||
// update-end-author:liusq date:20230625 for: [issues/563]暗色主题部分失效
|
||||
</style>
|
||||
|
|
|
@ -43,7 +43,7 @@ export default ({ command, mode }: ConfigEnv): UserConfig => {
|
|||
// ----- [end] 【JEECG作为乾坤子应用】 -----
|
||||
|
||||
console.log('[init] Start Port: ', VITE_PORT);
|
||||
console.log('[init] Vite Proxy Config: ', VITE_PROXY);
|
||||
console.debug('[init] Vite Proxy Config: ', VITE_PROXY);
|
||||
|
||||
|
||||
return {
|
||||
|
|
Loading…
Reference in New Issue