Merge branch 'master' of gitee.com:lab1024/smart-admin

This commit is contained in:
kkaiyun 2023-05-09 17:50:10 +08:00
commit 361b1fd60f
21 changed files with 259 additions and 91 deletions

View File

@ -4,8 +4,8 @@
**我们开源一套漂亮的代码和一套整洁的代码规范**,让大家在这浮躁的代码世界里感受到一股把代码写好的清流!同时又让开发者节省大量的时间,减少加班,快乐工作,保持谦逊,保持学习,**热爱代码,更热爱生活!** **我们开源一套漂亮的代码和一套整洁的代码规范**,让大家在这浮躁的代码世界里感受到一股把代码写好的清流!同时又让开发者节省大量的时间,减少加班,快乐工作,保持谦逊,保持学习,**热爱代码,更热爱生活!**
在线预览:[https://preview.smartadmin.1024lab.net](https://preview.smartadmin.1024lab.net) 在线预览:[https://preview.smartadmin.vip](https://preview.smartadmin.vip)
部署文档:[https://smartadmin.1024lab.net](https://smartadmin.1024lab.net) 官方文档:[https://smartadmin.vip](https://smartadmin.vip)
### 理念与思想 ### 理念与思想

View File

@ -203,11 +203,11 @@
</dependency> </dependency>
<!-- sax 读取时候用到的 --> <!-- sax 读取时候用到的 -->
<dependency> <!-- <dependency>-->
<groupId>xerces</groupId> <!-- <groupId>xerces</groupId>-->
<artifactId>xercesImpl</artifactId> <!-- <artifactId>xercesImpl</artifactId>-->
<version>${xerces.version}</version> <!-- <version>${xerces.version}</version>-->
</dependency> <!-- </dependency>-->
<dependency> <dependency>
<groupId>org.apache.poi</groupId> <groupId>org.apache.poi</groupId>
<artifactId>poi-scratchpad</artifactId> <artifactId>poi-scratchpad</artifactId>

View File

@ -112,7 +112,6 @@ public class NoticeController {
// --------------------- 员工查看 通知公告 ------------------------- // --------------------- 员工查看 通知公告 -------------------------
@ApiOperation("【员工】通知公告-查看详情 @author 卓大") @ApiOperation("【员工】通知公告-查看详情 @author 卓大")
@GetMapping("/oa/notice/employee/view/{noticeId}") @GetMapping("/oa/notice/employee/view/{noticeId}")
@RepeatSubmit
public ResponseDTO<NoticeDetailVO> view(@PathVariable Long noticeId, HttpServletRequest request) { public ResponseDTO<NoticeDetailVO> view(@PathVariable Long noticeId, HttpServletRequest request) {
return noticeEmployeeService.view( return noticeEmployeeService.view(
SmartRequestUtil.getRequestUserId(), SmartRequestUtil.getRequestUserId(),
@ -124,14 +123,12 @@ public class NoticeController {
@ApiOperation("【员工】通知公告-查询全部 @author 卓大") @ApiOperation("【员工】通知公告-查询全部 @author 卓大")
@PostMapping("/oa/notice/employee/query") @PostMapping("/oa/notice/employee/query")
@RepeatSubmit
public ResponseDTO<PageResult<NoticeEmployeeVO>> queryEmployeeNotice(@RequestBody @Valid NoticeEmployeeQueryForm noticeEmployeeQueryForm) { public ResponseDTO<PageResult<NoticeEmployeeVO>> queryEmployeeNotice(@RequestBody @Valid NoticeEmployeeQueryForm noticeEmployeeQueryForm) {
return noticeEmployeeService.queryList(SmartRequestUtil.getRequestUserId(), noticeEmployeeQueryForm); return noticeEmployeeService.queryList(SmartRequestUtil.getRequestUserId(), noticeEmployeeQueryForm);
} }
@ApiOperation("【员工】通知公告-查询 查看记录 @author 卓大") @ApiOperation("【员工】通知公告-查询 查看记录 @author 卓大")
@PostMapping("/oa/notice/employee/queryViewRecord") @PostMapping("/oa/notice/employee/queryViewRecord")
@RepeatSubmit
public ResponseDTO<PageResult<NoticeViewRecordVO>> queryViewRecord(@RequestBody @Valid NoticeViewRecordQueryForm noticeViewRecordQueryForm) { public ResponseDTO<PageResult<NoticeViewRecordVO>> queryViewRecord(@RequestBody @Valid NoticeViewRecordQueryForm noticeViewRecordQueryForm) {
return ResponseDTO.ok(noticeEmployeeService.queryViewRecord(noticeViewRecordQueryForm)); return ResponseDTO.ok(noticeEmployeeService.queryViewRecord(noticeViewRecordQueryForm));
} }

View File

@ -111,17 +111,17 @@ public class EmployeeService {
*/ */
public synchronized ResponseDTO<String> addEmployee(EmployeeAddForm employeeAddForm) { public synchronized ResponseDTO<String> addEmployee(EmployeeAddForm employeeAddForm) {
// 校验名称是否重复 // 校验名称是否重复
EmployeeEntity employeeEntity = employeeDao.getByLoginName(employeeAddForm.getLoginName(), false); EmployeeEntity employeeEntity = employeeDao.getByLoginName(employeeAddForm.getLoginName(), null);
if (null != employeeEntity) { if (null != employeeEntity) {
return ResponseDTO.userErrorParam("登录名重复"); return ResponseDTO.userErrorParam("登录名重复");
} }
// 校验姓名是否重复 // 校验姓名是否重复
employeeEntity = employeeDao.getByActualName(employeeAddForm.getActualName(), false); employeeEntity = employeeDao.getByActualName(employeeAddForm.getActualName(), null);
if (null != employeeEntity) { if (null != employeeEntity) {
return ResponseDTO.userErrorParam("姓名重复"); return ResponseDTO.userErrorParam("姓名重复");
} }
// 校验电话是否存在 // 校验电话是否存在
employeeEntity = employeeDao.getByPhone(employeeAddForm.getPhone(), false); employeeEntity = employeeDao.getByPhone(employeeAddForm.getPhone(), null);
if (null != employeeEntity) { if (null != employeeEntity) {
return ResponseDTO.userErrorParam("手机号已存在"); return ResponseDTO.userErrorParam("手机号已存在");
} }
@ -166,17 +166,17 @@ public class EmployeeService {
} }
EmployeeEntity existEntity = employeeDao.getByLoginName(employeeUpdateForm.getLoginName(), false); EmployeeEntity existEntity = employeeDao.getByLoginName(employeeUpdateForm.getLoginName(), null);
if (null != existEntity && !Objects.equals(existEntity.getEmployeeId(), employeeId)) { if (null != existEntity && !Objects.equals(existEntity.getEmployeeId(), employeeId)) {
return ResponseDTO.userErrorParam("登录名重复"); return ResponseDTO.userErrorParam("登录名重复");
} }
existEntity = employeeDao.getByPhone(employeeUpdateForm.getPhone(), false); existEntity = employeeDao.getByPhone(employeeUpdateForm.getPhone(), null);
if (null != existEntity && !Objects.equals(existEntity.getEmployeeId(), employeeId)) { if (null != existEntity && !Objects.equals(existEntity.getEmployeeId(), employeeId)) {
return ResponseDTO.userErrorParam("手机号已存在"); return ResponseDTO.userErrorParam("手机号已存在");
} }
existEntity = employeeDao.getByActualName(employeeUpdateForm.getActualName(), false); existEntity = employeeDao.getByActualName(employeeUpdateForm.getActualName(), null);
if (null != existEntity && !Objects.equals(existEntity.getEmployeeId(), employeeId)) { if (null != existEntity && !Objects.equals(existEntity.getEmployeeId(), employeeId)) {
return ResponseDTO.userErrorParam("姓名重复"); return ResponseDTO.userErrorParam("姓名重复");
} }

View File

@ -261,6 +261,7 @@ public class LoginService {
private void saveLogoutLog(RequestUser requestUser, String ip, String userAgent) { private void saveLogoutLog(RequestUser requestUser, String ip, String userAgent) {
LoginLogEntity loginEntity = LoginLogEntity.builder() LoginLogEntity loginEntity = LoginLogEntity.builder()
.userId(requestUser.getUserId()) .userId(requestUser.getUserId())
.userType(requestUser.getUserType().getValue())
.userName(requestUser.getUserName()) .userName(requestUser.getUserName())
.userAgent(userAgent) .userAgent(userAgent)
.loginIp(ip) .loginIp(ip)

View File

@ -184,10 +184,10 @@
</dependency> </dependency>
<!-- sax 读取时候用到的 --> <!-- sax 读取时候用到的 -->
<dependency> <!-- <dependency>-->
<groupId>xerces</groupId> <!-- <groupId>xerces</groupId>-->
<artifactId>xercesImpl</artifactId> <!-- <artifactId>xercesImpl</artifactId>-->
</dependency> <!-- </dependency>-->
<dependency> <dependency>
<groupId>org.apache.poi</groupId> <groupId>org.apache.poi</groupId>
<artifactId>poi-scratchpad</artifactId> <artifactId>poi-scratchpad</artifactId>

View File

@ -149,7 +149,7 @@ public abstract class CodeGenerateBaseVariableService {
*/ */
protected String getJavaPackageName(String javaType) { protected String getJavaPackageName(String javaType) {
if ("BigDecimal".equals(javaType)) { if ("BigDecimal".equals(javaType)) {
return "import java.math.BigDecimal"; return "import java.math.BigDecimal;";
} else if ("LocalDate".equals(javaType)) { } else if ("LocalDate".equals(javaType)) {
return "import java.time.LocalDate;"; return "import java.time.LocalDate;";
} else if ("LocalDateTime".equals(javaType)) { } else if ("LocalDateTime".equals(javaType)) {

View File

@ -230,6 +230,13 @@ public class FileService {
* @throws IOException * @throws IOException
*/ */
public ResponseEntity<Object> downloadByFileKey(String fileKey, String userAgent) { public ResponseEntity<Object> downloadByFileKey(String fileKey, String userAgent) {
FileVO fileVO = fileDao.getByFileKey(fileKey);
if (fileVO == null) {
HttpHeaders heads = new HttpHeaders();
heads.add(HttpHeaders.CONTENT_TYPE, "text/html;charset=UTF-8");
return new ResponseEntity<>("文件不存在:" + fileKey, heads, HttpStatus.OK);
}
// 根据文件服务类 获取对应文件服务 查询 url // 根据文件服务类 获取对应文件服务 查询 url
ResponseDTO<FileDownloadVO> responseDTO = fileStorageService.fileDownload(fileKey); ResponseDTO<FileDownloadVO> responseDTO = fileStorageService.fileDownload(fileKey);
if (!responseDTO.getOk()) { if (!responseDTO.getOk()) {
@ -237,15 +244,17 @@ public class FileService {
heads.add(HttpHeaders.CONTENT_TYPE, "text/html;charset=UTF-8"); heads.add(HttpHeaders.CONTENT_TYPE, "text/html;charset=UTF-8");
return new ResponseEntity<>(responseDTO.getMsg() + "" + fileKey, heads, HttpStatus.OK); return new ResponseEntity<>(responseDTO.getMsg() + "" + fileKey, heads, HttpStatus.OK);
} }
// 设置下载头
HttpHeaders heads = new HttpHeaders();
heads.add(HttpHeaders.CONTENT_TYPE, "application/octet-stream; charset=utf-8");
// 设置对应浏览器的文件名称编码
FileDownloadVO fileDownloadVO = responseDTO.getData(); FileDownloadVO fileDownloadVO = responseDTO.getData();
FileMetadataVO metadata = fileDownloadVO.getMetadata(); FileMetadataVO metadata = fileDownloadVO.getMetadata();
String fileName = null != metadata ? metadata.getFileName() : fileKey.substring(fileKey.lastIndexOf("/"));
fileName = fileStorageService.getDownloadFileNameByUA(fileName, userAgent); // 设置下载头
heads.add(HttpHeaders.CONTENT_DISPOSITION, "attachment;filename=" + fileName); HttpHeaders heads = new HttpHeaders();
heads.add(HttpHeaders.CONTENT_LENGTH, String.valueOf(metadata.getFileSize()));
heads.add(HttpHeaders.CONTENT_TYPE, "application/octet-stream; charset=utf-8");
heads.add(HttpHeaders.CONTENT_DISPOSITION, "attachment;filename=" + fileStorageService.getDownloadFileNameByUA(fileVO.getFileName(), userAgent));
// 返回给前端
ResponseEntity<Object> responseEntity = new ResponseEntity<>(fileDownloadVO.getData(), heads, HttpStatus.OK); ResponseEntity<Object> responseEntity = new ResponseEntity<>(fileDownloadVO.getData(), heads, HttpStatus.OK);
return responseEntity; return responseEntity;
} }

View File

@ -5,6 +5,7 @@ import net.lab1024.sa.common.common.code.SystemErrorCode;
import net.lab1024.sa.common.common.code.UserErrorCode; import net.lab1024.sa.common.common.code.UserErrorCode;
import net.lab1024.sa.common.common.domain.ResponseDTO; import net.lab1024.sa.common.common.domain.ResponseDTO;
import net.lab1024.sa.common.module.support.file.domain.vo.FileDownloadVO; import net.lab1024.sa.common.module.support.file.domain.vo.FileDownloadVO;
import net.lab1024.sa.common.module.support.file.domain.vo.FileMetadataVO;
import net.lab1024.sa.common.module.support.file.domain.vo.FileUploadVO; import net.lab1024.sa.common.module.support.file.domain.vo.FileUploadVO;
import net.lab1024.sa.common.module.support.config.ConfigKeyEnum; import net.lab1024.sa.common.module.support.config.ConfigKeyEnum;
import net.lab1024.sa.common.module.support.config.ConfigService; import net.lab1024.sa.common.module.support.config.ConfigService;
@ -119,6 +120,13 @@ public class FileStorageLocalServiceImpl implements IFileStorageService {
byte[] buffer = FileCopyUtils.copyToByteArray(in); byte[] buffer = FileCopyUtils.copyToByteArray(in);
FileDownloadVO fileDownloadVO = new FileDownloadVO(); FileDownloadVO fileDownloadVO = new FileDownloadVO();
fileDownloadVO.setData(buffer); fileDownloadVO.setData(buffer);
FileMetadataVO fileMetadataDTO = new FileMetadataVO();
fileMetadataDTO.setFileName(localFile.getName());
fileMetadataDTO.setFileSize(localFile.length());
fileMetadataDTO.setFileFormat(FilenameUtils.getExtension(localFile.getName()));
fileDownloadVO.setMetadata(fileMetadataDTO);
return ResponseDTO.ok(fileDownloadVO); return ResponseDTO.ok(fileDownloadVO);
} catch (IOException e) { } catch (IOException e) {
log.error("文件下载-发生异常:", e); log.error("文件下载-发生异常:", e);

View File

@ -60,16 +60,24 @@ public class RepeatSubmitAspect {
if (timeStamp != null) { if (timeStamp != null) {
Method method = ((MethodSignature) point.getSignature()).getMethod(); Method method = ((MethodSignature) point.getSignature()).getMethod();
RepeatSubmit annotation = method.getAnnotation(RepeatSubmit.class); RepeatSubmit annotation = method.getAnnotation(RepeatSubmit.class);
// 说明注解去掉了
if (annotation != null) {
return point.proceed();
}
int interval = Math.min(annotation.value(), RepeatSubmit.MAX_INTERVAL); int interval = Math.min(annotation.value(), RepeatSubmit.MAX_INTERVAL);
if (System.currentTimeMillis() < timeStamp + interval) { if (System.currentTimeMillis() < timeStamp + interval) {
// 提交频繁 // 提交频繁
return ResponseDTO.error(UserErrorCode.REPEAT_SUBMIT); return ResponseDTO.error(UserErrorCode.REPEAT_SUBMIT);
} }
} }
Object obj = null; Object obj = null;
try { try {
obj = point.proceed(); // 先给 ticket 设置在执行中
this.repeatSubmitTicket.putTicket(ticket); this.repeatSubmitTicket.putTicket(ticket);
obj = point.proceed();
} catch (Throwable throwable) { } catch (Throwable throwable) {
log.error("", throwable); log.error("", throwable);
throw throwable; throw throwable;

View File

@ -10,19 +10,14 @@
:title="form.$!{primaryKeyFieldName} ? '编辑' : '添加'" :title="form.$!{primaryKeyFieldName} ? '编辑' : '添加'"
width="$!{insertAndUpdate.width}" width="$!{insertAndUpdate.width}"
:visible="visibleFlag" :visible="visibleFlag"
@close="onClose" @cancel="onClose"
:maskClosable="false" :maskClosable="false"
:destroyOnClose="true" :destroyOnClose="true"
> >
<a-form ref="formRef" :model="form" :rules="rules" :label-col="{ span: 5 }" > <a-form ref="formRef" :model="form" :rules="rules" :label-col="{ span: 5 }" >
#if($insertAndUpdate.countPerLine > 1) #if($insertAndUpdate.countPerLine == 1)
<a-row> <a-row>
#end
#foreach ($field in $formFields) #foreach ($field in $formFields)
#if($insertAndUpdate.countPerLine > 1)
#set($span=24 / $!insertAndUpdate.countPerLine )
<a-col :span="$!{span}">
#end
#if($field.frontComponent == "Input") #if($field.frontComponent == "Input")
<a-form-item label="$!{field.label}" name="${field.fieldName}"> <a-form-item label="$!{field.label}" name="${field.fieldName}">
<a-input style="width: 100%" v-model:value="form.${field.fieldName}" placeholder="$!{field.label}" /> <a-input style="width: 100%" v-model:value="form.${field.fieldName}" placeholder="$!{field.label}" />
@ -75,9 +70,68 @@
</a-form-item> </a-form-item>
#end #end
#end #end
</a-row>
#end
#if($insertAndUpdate.countPerLine > 1) #if($insertAndUpdate.countPerLine > 1)
</a-col>
<a-row> <a-row>
#set($span=24 / $!insertAndUpdate.countPerLine )
#foreach ($field in $formFields)
<a-col :span="$!{span}">
#if($field.frontComponent == "Input")
<a-form-item label="$!{field.label}" name="${field.fieldName}">
<a-input style="width: 100%" v-model:value="form.${field.fieldName}" placeholder="$!{field.label}" />
</a-form-item>
#end
#if($field.frontComponent == "InputNumber")
<a-form-item label="$!{field.label}" name="${field.fieldName}">
<a-input-number style="width: 100%" v-model:value="form.${field.fieldName}" placeholder="$!{field.label}" />
</a-form-item>
#end
#if($field.frontComponent == "Textarea")
<a-form-item label="$!{field.label}" name="${field.fieldName}">
<a-textarea style="width: 100%" v-model:value="form.${field.fieldName}" placeholder="$!{field.label}" />
</a-form-item>
#end
#if($field.frontComponent == "BooleanSelect")
<a-form-item label="$!{field.label}" name="${field.fieldName}">
<BooleanSelect v-model:value="form.${field.fieldName}" style="width: 100%" />
</a-form-item>
#end
#if($field.frontComponent == "SmartEnumSelect")
<a-form-item label="$codeGeneratorTool.removeEnumDesc($!{field.label})" name="${field.fieldName}">
<SmartEnumSelect width="100%" v-model:value="form.${field.fieldName}" enumName="$!{field.upperUnderscoreEnum}" placeholder="$codeGeneratorTool.removeEnumDesc($!{field.label})"/>
</a-form-item>
#end
#if($field.frontComponent == "DictSelect")
<a-form-item label="$codeGeneratorTool.removeEnumDesc($!{field.label})" name="${field.fieldName}">
<DictSelect width="100%" v-model:value="form.${field.fieldName}" keyCode="$!{field.dict}" placeholder="$!{field.label}"/>
</a-form-item>
#end
#if($field.frontComponent == "Date")
<a-form-item label="$!{field.label}" name="${field.fieldName}">
<a-date-picker valueFormat="YYYY-MM-DD" v-model:value="form.$!{field.fieldName}" style="width: 100%" placeholder="$!{field.label}"/>
</a-form-item>
#end
#if($field.frontComponent == "DateTime")
<a-form-item label="$!{field.label}" name="${field.fieldName}">
<a-date-picker show-time valueFormat="YYYY-MM-DD HH:mm:ss" v-model:value="form.$!{field.fieldName}" style="width: 100%" placeholder="$!{field.label}" />
</a-form-item>
#end
#if($field.frontComponent == "Upload")
<a-form-item label="$!{field.label}" name="${field.fieldName}">
<FileUpload
:defaultFileList="form.$!{field.fieldName}"
:folder="FILE_FOLDER_TYPE_ENUM.COMMON.value"
buttonText="上传 $!{field.label}"
listType="text"
@change="e => form.$!{field.fieldName} = e"
/>
</a-form-item>
#end
</a-col>
#end
</a-row>
#end #end
</a-form> </a-form>

View File

@ -3,7 +3,7 @@ spring:
datasource: datasource:
url: jdbc:p6spy:mysql://127.0.0.1:3306/smart_admin_v2?autoReconnect=true&useServerPreparedStmts=false&rewriteBatchedStatements=true&characterEncoding=UTF-8&useSSL=false&allowMultiQueries=true&serverTimezone=Asia/Shanghai url: jdbc:p6spy:mysql://127.0.0.1:3306/smart_admin_v2?autoReconnect=true&useServerPreparedStmts=false&rewriteBatchedStatements=true&characterEncoding=UTF-8&useSSL=false&allowMultiQueries=true&serverTimezone=Asia/Shanghai
username: root username: root
password: Zhuoda123456 password: Xxxx1024
initial-size: 2 initial-size: 2
min-idle: 2 min-idle: 2
max-active: 10 max-active: 10
@ -16,7 +16,7 @@ spring:
username: druid username: druid
password: 1024 password: 1024
login: login:
enabled: true enabled: false
method: method:
pointcut: net.lab1024.sa..*Service.* pointcut: net.lab1024.sa..*Service.*
@ -89,9 +89,9 @@ file:
local: local:
path: ${localPath:/home}/smart_admin_v2/upload/ path: ${localPath:/home}/smart_admin_v2/upload/
cloud: cloud:
region: oss-cn-qingdao region: oss-cn-hangzhou
endpoint: oss-cn-qingdao.aliyuncs.com endpoint: oss-cn-hangzhou.aliyuncs.com
bucket-name: common-sit bucket-name: 1024lab-smart-admin
access-key: access-key:
secret-key: secret-key:
url: url:
@ -127,8 +127,8 @@ access-control-allow-origin: '*'
# 心跳配置 # 心跳配置
heart-beat: heart-beat:
interval-seconds: 60 interval-seconds: 300
# 热加载配置 # 热加载配置
reload: reload:
interval-seconds: 60 interval-seconds: 300

View File

@ -46,14 +46,15 @@
//退 //退
async function onLogout() { async function onLogout() {
localClear();
clearAllCoolies();
useUserStore().logout();
try { try {
await loginApi.logout(); await loginApi.logout();
} catch (e) { } catch (e) {
smartSentry.captureError(e); smartSentry.captureError(e);
} finally { } finally {
localClear();
clearAllCoolies();
useUserStore().logout();
location.reload(); location.reload();
} }
} }

View File

@ -22,7 +22,7 @@
<template #icon> <template #icon>
<component :is="$antIcons[item.icon]" /> <component :is="$antIcons[item.icon]" />
</template> </template>
{{ item.menuName }} {{ menuNameAdapter(item.menuName) }}
</a-menu-item> </a-menu-item>
</template> </template>
</template> </template>
@ -64,6 +64,11 @@
return parentMenuList.value.map((e) => e.name); return parentMenuList.value.map((e) => e.name);
}); });
//
function menuNameAdapter(name){
return name.substr(0,2);
}
// //
watch( watch(
currentRoute, currentRoute,

View File

@ -77,34 +77,34 @@
// ------------------ -------------------------- // ------------------ --------------------------
let feedbackMessageList = ref([]); let feedbackMessageList = ref([]);
onMounted(() => { onMounted(() => {
// //
queryFeedbackList(); queryFeedbackList();
scroll(); //
scheduleShowFeedback();
}); });
let scrollInterval = null; let scheduleShowInterval = null;
let swiper = 1; let scheduleShowIndex = 0;
function scroll() { function scheduleShowFeedback() {
if (scrollInterval != null) { if (scheduleShowInterval != null) {
return; return;
} }
scrollInterval = setInterval(() => { scheduleShowInterval = setInterval(() => {
if (currentPage >= pages) { if (feedbackList.length == 0) {
currentPage = 1;
}
if (pages == 0 || feedbackList.length == 0) {
return; return;
} }
let initValue = (currentPage - 1) * 2;
feedbackMessageList.value[0] = feedbackList[initValue]; //
if (feedbackList[initValue + 1]) { for (let i = 0; i < 2; i++) {
feedbackMessageList.value[1] = feedbackList[initValue + 1]; if (scheduleShowIndex >= feedbackList.length) {
scheduleShowIndex = 0;
} }
swiper = currentPage - 1; feedbackMessageList.value[i] = feedbackList[scheduleShowIndex];
currentPage++; scheduleShowIndex++;
}, 2000); }
}, 3000);
} }
// //
@ -121,7 +121,7 @@
}; };
let result = await feedbackApi.queryFeedback(param); let result = await feedbackApi.queryFeedback(param);
feedbackList = result.data.list; feedbackList = result.data.list;
pages = Math.ceil(result.data.total / 2); pages = Math.ceil(feedbackList.length / 2);
} catch (e) { } catch (e) {
smartSentry.captureError(e); smartSentry.captureError(e);
} }

View File

@ -103,6 +103,17 @@
const helpDocFlag = computed(() => useAppConfigStore().$state.helpDocFlag); const helpDocFlag = computed(() => useAppConfigStore().$state.helpDocFlag);
// //
const footerFlag = computed(() => useAppConfigStore().$state.footerFlag); const footerFlag = computed(() => useAppConfigStore().$state.footerFlag);
//
const dueHeight = computed(() => {
let due = 40;
if (useAppConfigStore().$state.pageTagFlag) {
due = due + 40;
}
if (useAppConfigStore().$state.footerFlag) {
due = due + 40;
}
return due;
});
// //
const collapsed = ref(false); const collapsed = ref(false);
@ -222,10 +233,11 @@
} }
.admin-layout-content { .admin-layout-content {
background-color: inherit;
min-height: auto; min-height: auto;
position: relative; position: relative;
padding: 10px 10px 0px 10px; padding: 10px 10px 0px 10px;
height: v-bind('pageTagFlag ? "calc(100% - 80px)": "calc(100% - 40px)"'); height: calc(100% - v-bind(dueHeight)px);
overflow-x: hidden; overflow-x: hidden;
} }
} }

View File

@ -97,6 +97,17 @@
const helpDocFlag = computed(() => useAppConfigStore().$state.helpDocFlag); const helpDocFlag = computed(() => useAppConfigStore().$state.helpDocFlag);
// //
const footerFlag = computed(() => useAppConfigStore().$state.footerFlag); const footerFlag = computed(() => useAppConfigStore().$state.footerFlag);
//
const dueHeight = computed(() => {
let due = 40;
if (useAppConfigStore().$state.pageTagFlag) {
due = due + 40;
}
if (useAppConfigStore().$state.footerFlag) {
due = due + 40;
}
return due;
});
// //
const collapsed = ref(false); const collapsed = ref(false);
@ -223,11 +234,12 @@
} }
.admin-layout-content { .admin-layout-content {
background-color: inherit;
min-height: auto; min-height: auto;
position: relative; position: relative;
overflow-x: hidden; overflow-x: hidden;
padding: 10px 10px 0px 10px; padding: 10px 10px 0px 10px;
height: v-bind('pageTagFlag ? "calc(100% - 80px)": "calc(100% - 40px)"'); height: calc(100% - v-bind(dueHeight)px);
} }
} }

View File

@ -0,0 +1,30 @@
/**
* 计算表格自适应高度
*
* @param {*} heightRef
* @param {*} removeRefArray
* @param {*} extraRemoveHeight
* @returns
*/
import { useAppConfigStore } from '../store/modules/system/app-config';
export function calcTableHeight(heightRef, removeRefArray, extraRemoveHeight) {
let removeHeight = 0;
if (removeRefArray && removeRefArray.length > 0) {
for (const item of removeRefArray) {
removeHeight = removeHeight + item.value.$el.offsetHeight;
}
}
let due = 40;
if (useAppConfigStore().$state.pageTagFlag) {
due = due + 40;
}
if (useAppConfigStore().$state.footerFlag) {
due = due + 40;
}
removeHeight = removeHeight + extraRemoveHeight + due;
heightRef.value = document.querySelector('#smartAdminLayoutContent').offsetHeight - removeHeight;
}

View File

@ -8,7 +8,7 @@
* @Copyright 1024创新实验室 https://1024lab.net Since 2012 * @Copyright 1024创新实验室 https://1024lab.net Since 2012
--> -->
<template> <template>
<a-form class="smart-query-form" v-privilege="'loginLog:query'"> <a-form class="smart-query-form" v-privilege="'loginLog:query'" ref="queryFormRef">
<a-row class="smart-query-form-row"> <a-row class="smart-query-form-row">
<a-form-item label="用户名称" class="smart-query-form-item"> <a-form-item label="用户名称" class="smart-query-form-item">
<a-input style="width: 300px" v-model:value="queryForm.userName" placeholder="用户名称" /> <a-input style="width: 300px" v-model:value="queryForm.userName" placeholder="用户名称" />
@ -40,10 +40,19 @@
</a-form> </a-form>
<a-card size="small" :bordered="false" :hoverable="true"> <a-card size="small" :bordered="false" :hoverable="true">
<a-row justify="end"> <a-row justify="end" ref="tableOperatorRef">
<TableOperator class="smart-margin-bottom5" v-model="columns" :tableId="TABLE_ID_CONST.SUPPORT.LOGIN_LOG" :refresh="ajaxQuery" /> <TableOperator class="smart-margin-bottom5" v-model="columns" :tableId="TABLE_ID_CONST.SUPPORT.LOGIN_LOG" :refresh="ajaxQuery" />
</a-row> </a-row>
<a-table size="small" :dataSource="tableData" :columns="columns" bordered rowKey="loginLogId" :pagination="false" :loading="tableLoading"> <a-table
size="small"
:dataSource="tableData"
:columns="columns"
bordered
rowKey="loginLogId"
:pagination="false"
:loading="tableLoading"
:scroll="{ y: scrollY }"
>
<template #bodyCell="{ text, record, column }"> <template #bodyCell="{ text, record, column }">
<template v-if="column.dataIndex === 'loginResult'"> <template v-if="column.dataIndex === 'loginResult'">
<template v-if="text === LOGIN_RESULT_ENUM.LOGIN_SUCCESS.value"> <template v-if="text === LOGIN_RESULT_ENUM.LOGIN_SUCCESS.value">
@ -85,7 +94,7 @@
</a-card> </a-card>
</template> </template>
<script setup> <script setup>
import { onMounted, reactive, ref } from 'vue'; import { onMounted, onUnmounted, reactive, ref } from 'vue';
import { PAGE_SIZE_OPTIONS } from '/@/constants/common-const'; import { PAGE_SIZE_OPTIONS } from '/@/constants/common-const';
import { defaultTimeRanges } from '/@/lib/default-time-ranges'; import { defaultTimeRanges } from '/@/lib/default-time-ranges';
import uaparser from 'ua-parser-js'; import uaparser from 'ua-parser-js';
@ -94,6 +103,7 @@
import { smartSentry } from '/@/lib/smart-sentry'; import { smartSentry } from '/@/lib/smart-sentry';
import TableOperator from '/@/components/support/table-operator/index.vue'; import TableOperator from '/@/components/support/table-operator/index.vue';
import { TABLE_ID_CONST } from '/@/constants/support/table-id-const'; import { TABLE_ID_CONST } from '/@/constants/support/table-id-const';
import { calcTableHeight } from '/@/lib/table-auto-height';
const columns = ref([ const columns = ref([
{ {
@ -190,5 +200,23 @@
} }
} }
onMounted(ajaxQuery); // ----------------- --------------------
const scrollY = ref(100);
const tableOperatorRef = ref();
const queryFormRef = ref();
function autoCalcTableHeight() {
calcTableHeight(scrollY, [tableOperatorRef, queryFormRef], 10);
}
window.addEventListener('resize', autoCalcTableHeight);
onMounted(() => {
ajaxQuery();
autoCalcTableHeight();
});
onUnmounted(() => {
window.removeEventListener('resize', autoCalcTableHeight);
});
</script> </script>

View File

@ -201,6 +201,9 @@
try { try {
params.departmentId = props.departmentId; params.departmentId = props.departmentId;
let res = await employeeApi.queryEmployee(params); let res = await employeeApi.queryEmployee(params);
for (const item of res.data.list) {
item.roleNameList = _.join(item.roleNameList,',');
}
tableData.value = res.data.list; tableData.value = res.data.list;
total.value = res.data.total; total.value = res.data.total;
// //