From cb44316d3975af52a3a9af824094b844dd7df874 Mon Sep 17 00:00:00 2001
From: longz <longzhaoz@qq.com>
Date: 星期二, 26 五月 2026 11:34:49 +0800
Subject: [PATCH] fix
---
backend/src/main/java/com/sinata/appointment/service/StaffManageApplicationService.java | 120 +++++++--
yuyueMiniProgram/src/pages/review/index.vue | 3
frontend-admin/src/views/StaffGroupsView.vue | 95 +++++--
yuyueMiniProgram/src/pages/visitRecord/index.vue | 34 ++
frontend-admin/src/views/StaffEmployeesView.vue | 24 +
frontend-admin/src/views/DashboardView.vue | 7
frontend-admin/src/views/ExportView.vue | 12
yuyueMiniProgram/.env.development | 2
frontend-admin/src/views/PassAreasView.vue | 62 +++-
frontend-admin/src/views/AppointmentListView.vue | 21 +
frontend-admin/src/views/UsersView.vue | 41 ++
yuyueMiniProgram/src/pages/reviewDetail/index.vue | 13
backend/src/main/java/com/sinata/appointment/service/MiniApprovalDetailApplicationService.java | 5
frontend-admin/src/views/DeptManageView.vue | 4
frontend-admin/src/views/LoginView.vue | 2
frontend-admin/src/views/RegionLocalUnitsView.vue | 66 +++-
frontend-admin/src/views/RolesView.vue | 36 ++
backend/src/main/java/com/sinata/appointment/config/LocalFileUploadProperties.java | 4
frontend-admin/src/views/VisitorInfoView.vue | 24 +
yuyueMiniProgram/.env.production | 2
frontend-admin/src/views/ApprovalTodoView.vue | 12
frontend-admin/src/views/StaffGroupDetailView.vue | 10
frontend-admin/src/views/VisitReasonsSettingsView.vue | 84 ++++--
23 files changed, 513 insertions(+), 170 deletions(-)
diff --git a/backend/src/main/java/com/sinata/appointment/config/LocalFileUploadProperties.java b/backend/src/main/java/com/sinata/appointment/config/LocalFileUploadProperties.java
index bc82bc5..9114f13 100644
--- a/backend/src/main/java/com/sinata/appointment/config/LocalFileUploadProperties.java
+++ b/backend/src/main/java/com/sinata/appointment/config/LocalFileUploadProperties.java
@@ -6,10 +6,10 @@
@Component
public class LocalFileUploadProperties {
- @Value("${file-upload-path:D:/tmp/}")
+ @Value("${file-upload-path}")
private String fileUploadPath;
- @Value("${picture-server-address:http://192.168.110.149:81/}")
+ @Value("${picture-server-address}")
private String pictureServerAddress;
public String getFileUploadPath() {
diff --git a/backend/src/main/java/com/sinata/appointment/service/MiniApprovalDetailApplicationService.java b/backend/src/main/java/com/sinata/appointment/service/MiniApprovalDetailApplicationService.java
index d5706ac..ac8b3ad 100644
--- a/backend/src/main/java/com/sinata/appointment/service/MiniApprovalDetailApplicationService.java
+++ b/backend/src/main/java/com/sinata/appointment/service/MiniApprovalDetailApplicationService.java
@@ -5,6 +5,7 @@
import com.fasterxml.jackson.databind.ObjectMapper;
import com.sinata.appointment.config.MiniStpUtil;
import com.sinata.appointment.constants.AppointmentBizConstants;
+import com.sinata.appointment.constants.AppointmentOrderStatus;
import com.sinata.appointment.constants.ApprovalNodeCode;
import com.sinata.appointment.constants.ApprovalTaskStatus;
import com.sinata.appointment.constants.BizErrorCode;
@@ -148,6 +149,10 @@
vo.setApprovalStatusText("已查看");
return;
}
+ if (AppointmentOrderStatus.CANCELLED.equals(order.getStatus())) {
+ vo.setApprovalStatusText("已取消");
+ return;
+ }
if (ApprovalTaskStatus.APPROVED.equals(currentUserTask.getTaskStatus())) {
vo.setApprovalStatusText("已同意");
return;
diff --git a/backend/src/main/java/com/sinata/appointment/service/StaffManageApplicationService.java b/backend/src/main/java/com/sinata/appointment/service/StaffManageApplicationService.java
index 0cf356b..d32cee1 100644
--- a/backend/src/main/java/com/sinata/appointment/service/StaffManageApplicationService.java
+++ b/backend/src/main/java/com/sinata/appointment/service/StaffManageApplicationService.java
@@ -45,6 +45,7 @@
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
+import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
@@ -476,11 +477,13 @@
.eq(SysDept::getStatus, 1)
.orderByAsc(SysDept::getSortOrder)
.orderByAsc(SysDept::getId));
- List<String> deptNames =
+ Map<Long, String> deptPathById = buildDeptPathById(depts);
+ List<String> deptPaths =
depts.stream()
- .map(SysDept::getDeptName)
+ .map(SysDept::getId)
+ .map(deptPathById::get)
.filter(StringUtils::hasText)
- .map(String::trim)
+ .distinct()
.toList();
List<String> groupNames = loadActiveGroupNames();
@@ -489,8 +492,8 @@
ex.setRealName("张三");
ex.setStaffNo("EMP001");
ex.setMobile("13800138000");
- if (!deptNames.isEmpty()) {
- ex.setDept(deptNames.get(0));
+ if (!deptPaths.isEmpty()) {
+ ex.setDept(deptPaths.get(0));
}
ex.setPosition("员工");
if (!groupNames.isEmpty()) {
@@ -510,12 +513,12 @@
EasyExcel.writerSheet("员工导入")
.head(StaffImportExcelRow.class)
.registerWriteHandler(
- new StaffTemplateDropdownHandler(deptNames, groupNames))
+ new StaffTemplateDropdownHandler(deptPaths, groupNames))
.build();
writer.write(demo, dataSheet);
var dictSheet = EasyExcel.writerSheet("字典").needHead(false).build();
- writer.write(buildDictRows(deptNames, groupNames), dictSheet);
+ writer.write(buildDictRows(deptPaths, groupNames), dictSheet);
} finally {
writer.finish();
}
@@ -531,15 +534,22 @@
vo.getErrors().add("文件为空");
return vo;
}
- Map<String, Long> deptNameToId = new HashMap<>();
+ Map<String, Long> deptPathToId = new HashMap<>();
+ Map<String, List<Long>> deptNameToIds = new HashMap<>();
List<SysDept> depts =
sysDeptMapper.selectList(
new LambdaQueryWrapper<SysDept>()
.eq(SysDept::getDelFlag, 0)
.eq(SysDept::getStatus, 1));
+ Map<Long, String> deptPathById = buildDeptPathById(depts);
for (SysDept d : depts) {
+ String path = deptPathById.get(d.getId());
+ if (StringUtils.hasText(path)) {
+ deptPathToId.put(path.trim(), d.getId());
+ }
if (StringUtils.hasText(d.getDeptName())) {
- deptNameToId.put(d.getDeptName().trim(), d.getId());
+ String deptName = d.getDeptName().trim();
+ deptNameToIds.computeIfAbsent(deptName, k -> new ArrayList<>()).add(d.getId());
}
}
@@ -551,7 +561,7 @@
public void invoke(StaffImportExcelRow row, AnalysisContext context) {
rowIndex++;
try {
- handleImportRow(rowIndex, row, deptNameToId);
+ handleImportRow(rowIndex, row, deptPathToId, deptNameToIds);
vo.setSuccess(vo.getSuccess() + 1);
} catch (StopRowException ignored) {
} catch (BizException e) {
@@ -574,7 +584,11 @@
return vo;
}
- private void handleImportRow(int lineNo, StaffImportExcelRow row, Map<String, Long> deptNameToId) {
+ private void handleImportRow(
+ int lineNo,
+ StaffImportExcelRow row,
+ Map<String, Long> deptPathToId,
+ Map<String, List<Long>> deptNameToIds) {
String name = row.getRealName() == null ? "" : row.getRealName().trim();
String staffNo = row.getStaffNo() == null ? "" : row.getStaffNo().trim();
String mobile = row.getMobile() == null ? "" : row.getMobile().trim();
@@ -595,7 +609,7 @@
throw new BizException(BizErrorCode.AUTH_INVALID_CREDENTIALS, "员工姓名、联系方式、所属部门不能为空");
}
- Long deptId = parseDeptId(dept, deptNameToId);
+ Long deptId = parseDeptId(dept, deptPathToId, deptNameToIds);
boolean leader = parseDeptLeader(position);
StaffCreateRequest req = new StaffCreateRequest();
@@ -614,11 +628,11 @@
private static final class StopRowException extends RuntimeException {}
- private static List<List<String>> buildDictRows(List<String> deptNames, List<String> groupNames) {
- int max = Math.max(Math.max(deptNames.size(), groupNames.size()), 2);
+ private static List<List<String>> buildDictRows(List<String> deptPaths, List<String> groupNames) {
+ int max = Math.max(Math.max(deptPaths.size(), groupNames.size()), 2);
List<List<String>> rows = new ArrayList<>();
for (int i = 0; i < max; i++) {
- String dept = i < deptNames.size() ? deptNames.get(i) : "";
+ String dept = i < deptPaths.size() ? deptPaths.get(i) : "";
String pos = i == 0 ? "部门负责人" : (i == 1 ? "员工" : "");
String grp = i < groupNames.size() ? groupNames.get(i) : "";
rows.add(java.util.Arrays.asList(dept, pos, grp));
@@ -638,11 +652,11 @@
}
private static final class StaffTemplateDropdownHandler implements SheetWriteHandler {
- private final List<String> deptNames;
+ private final List<String> deptPaths;
private final List<String> groupNames;
- private StaffTemplateDropdownHandler(List<String> deptNames, List<String> groupNames) {
- this.deptNames = deptNames != null ? deptNames : List.of();
+ private StaffTemplateDropdownHandler(List<String> deptPaths, List<String> groupNames) {
+ this.deptPaths = deptPaths != null ? deptPaths : List.of();
this.groupNames = groupNames != null ? groupNames : List.of();
}
@@ -651,10 +665,10 @@
Sheet sheet = writeSheetHolder.getSheet();
Workbook wb = writeWorkbookHolder.getWorkbook();
- if (!deptNames.isEmpty()) {
+ if (!deptPaths.isEmpty()) {
Name deptRange = wb.createName();
deptRange.setNameName("dept_list");
- deptRange.setRefersToFormula("字典!$A$1:$A$" + deptNames.size());
+ deptRange.setRefersToFormula("字典!$A$1:$A$" + deptPaths.size());
}
Name posRange = wb.createName();
posRange.setNameName("pos_list");
@@ -669,7 +683,7 @@
int startRow = 1;
int endRow = 500;
- if (!deptNames.isEmpty()) {
+ if (!deptPaths.isEmpty()) {
DataValidationConstraint deptConstraint = helper.createFormulaListConstraint("dept_list");
CellRangeAddressList deptAddr = new CellRangeAddressList(startRow, endRow, 3, 3);
DataValidation dvDept = helper.createValidation(deptConstraint, deptAddr);
@@ -693,7 +707,8 @@
}
}
- private static Long parseDeptId(String dept, Map<String, Long> deptNameToId) {
+ private static Long parseDeptId(
+ String dept, Map<String, Long> deptPathToId, Map<String, List<Long>> deptNameToIds) {
if (!StringUtils.hasText(dept)) {
return null;
}
@@ -702,11 +717,64 @@
return Long.parseLong(t);
} catch (Exception ignored) {
}
- Long id = deptNameToId.get(t);
- if (id == null) {
- throw new BizException(BizErrorCode.AUTH_INVALID_CREDENTIALS, "所属部门不存在: " + t);
+ Long pathMatchedId = deptPathToId.get(t);
+ if (pathMatchedId != null) {
+ return pathMatchedId;
}
- return id;
+ List<Long> nameMatchedIds = deptNameToIds.getOrDefault(t, List.of());
+ if (nameMatchedIds.size() == 1) {
+ return nameMatchedIds.get(0);
+ }
+ if (nameMatchedIds.size() > 1) {
+ throw new BizException(
+ BizErrorCode.AUTH_INVALID_CREDENTIALS,
+ "所属部门名称重复,请使用全路径(示例:A公司/财务部): " + t);
+ }
+ throw new BizException(BizErrorCode.AUTH_INVALID_CREDENTIALS, "所属部门不存在: " + t);
+ }
+
+ private static Map<Long, String> buildDeptPathById(List<SysDept> depts) {
+ if (depts == null || depts.isEmpty()) {
+ return Map.of();
+ }
+ Map<Long, SysDept> byId = new LinkedHashMap<>();
+ for (SysDept dept : depts) {
+ byId.put(dept.getId(), dept);
+ }
+ Map<Long, String> cache = new HashMap<>();
+ for (SysDept dept : depts) {
+ resolveDeptPath(dept.getId(), byId, cache, new HashSet<>());
+ }
+ return cache;
+ }
+
+ private static String resolveDeptPath(
+ Long deptId,
+ Map<Long, SysDept> byId,
+ Map<Long, String> cache,
+ Set<Long> visiting) {
+ if (deptId == null || deptId <= 0) {
+ return "";
+ }
+ String cached = cache.get(deptId);
+ if (cached != null) {
+ return cached;
+ }
+ SysDept current = byId.get(deptId);
+ if (current == null) {
+ return "";
+ }
+ String self = StringUtils.hasText(current.getDeptName()) ? current.getDeptName().trim() : "";
+ Long parentId = current.getParentId();
+ if (parentId == null || parentId <= 0 || parentId.equals(deptId) || !visiting.add(deptId)) {
+ cache.put(deptId, self);
+ return self;
+ }
+ String parentPath = resolveDeptPath(parentId, byId, cache, visiting);
+ visiting.remove(deptId);
+ String path = StringUtils.hasText(parentPath) ? (parentPath + "/" + self) : self;
+ cache.put(deptId, path);
+ return path;
}
private static boolean parseDeptLeader(String position) {
diff --git a/frontend-admin/src/views/AppointmentListView.vue b/frontend-admin/src/views/AppointmentListView.vue
index 6fe53d6..09b7439 100644
--- a/frontend-admin/src/views/AppointmentListView.vue
+++ b/frontend-admin/src/views/AppointmentListView.vue
@@ -79,7 +79,8 @@
<el-button v-permission="'appointments:export'" type="primary" plain :loading="exporting" @click="exportExcel">导出</el-button>
</div>
- <el-table :data="rows" v-loading="loading" stripe border :max-height="tableMaxHeight">
+ <div class="table-wrap">
+ <el-table :data="rows" v-loading="loading" stripe border height="100%">
<el-table-column label="序号" width="68" type="index" :index="indexMethod" />
<el-table-column prop="visitTypeText" label="来访类型" width="110" />
<el-table-column prop="visitedUserName" label="被访人" width="110" show-overflow-tooltip />
@@ -109,7 +110,8 @@
<el-button v-permission="'appointments:detail'" type="primary" link @click="openDetail(row)">详情</el-button>
</template>
</el-table-column>
- </el-table>
+ </el-table>
+ </div>
<div class="pager-wrap">
<div class="pager-total">共 {{ total }} 条</div>
@@ -335,7 +337,6 @@
const size = ref(10);
const total = ref(0);
const rows = ref<AppointmentRow[]>([]);
-const tableMaxHeight = computed(() => (rows.value.length > 10 ? 560 : undefined));
const visitDateRange = ref<string[]>([]);
const deptOptions = ref<DeptOption[]>([]);
@@ -708,6 +709,8 @@
display: flex;
flex-direction: column;
gap: 12px;
+ height: calc(100vh - 170px);
+ min-height: calc(100vh - 170px);
}
.search-card,
@@ -766,12 +769,23 @@
.table-card {
padding: 14px 16px 12px;
+ display: flex;
+ flex-direction: column;
+ flex: 1;
+ min-height: 0;
+ overflow: hidden;
}
.table-toolbar {
display: flex;
justify-content: flex-start;
margin-bottom: 12px;
+ flex: none;
+}
+
+.table-wrap {
+ flex: 1;
+ min-height: 0;
}
.pager-wrap {
@@ -779,6 +793,7 @@
justify-content: space-between;
align-items: center;
margin-top: 14px;
+ flex: none;
}
.pager-total {
diff --git a/frontend-admin/src/views/ApprovalTodoView.vue b/frontend-admin/src/views/ApprovalTodoView.vue
index 0843696..c6c7ad7 100644
--- a/frontend-admin/src/views/ApprovalTodoView.vue
+++ b/frontend-admin/src/views/ApprovalTodoView.vue
@@ -24,11 +24,13 @@
<div class="pager">
<el-pagination
background
- layout="total, prev, pager, next"
+ layout="total, sizes, prev, pager, next"
:current-page="page"
:page-size="size"
+ :page-sizes="[10, 20, 50, 100]"
:total="total"
@current-change="handlePageChange"
+ @size-change="handleSizeChange"
/>
</div>
</div>
@@ -52,7 +54,7 @@
const loading = ref(false);
const rows = ref<OpLogRow[]>([]);
const page = ref(1);
-const size = ref(20);
+const size = ref(10);
const total = ref(0);
function formatTime(v: unknown) {
@@ -96,6 +98,12 @@
load();
}
+function handleSizeChange(nextSize: number) {
+ size.value = nextSize;
+ page.value = 1;
+ load();
+}
+
onMounted(load);
</script>
diff --git a/frontend-admin/src/views/DashboardView.vue b/frontend-admin/src/views/DashboardView.vue
index 8b2a962..1063476 100644
--- a/frontend-admin/src/views/DashboardView.vue
+++ b/frontend-admin/src/views/DashboardView.vue
@@ -257,6 +257,11 @@
function getLineChartOption(): EChartsOption {
const rows = cappedTrend.value;
+ const today = formatDate(new Date());
+ const inProgressSeries = rows.map((item) => {
+ const value = Number(item.inProgressCount) || 0;
+ return item.statDate > today ? 0 : value;
+ });
return {
color: ["#45c36c", "#5269FF", "#ff6a4d", "#ffc24b"],
tooltip: {
@@ -312,7 +317,7 @@
smooth: true,
showSymbol: true,
symbolSize: 6,
- data: rows.map(item => Number(item.inProgressCount) || 0),
+ data: inProgressSeries,
label: { show: true, position: "top", fontSize: 11, fontWeight: 600, color: "#5269FF" },
},
{
diff --git a/frontend-admin/src/views/DeptManageView.vue b/frontend-admin/src/views/DeptManageView.vue
index 6afb4e0..2ea82db 100644
--- a/frontend-admin/src/views/DeptManageView.vue
+++ b/frontend-admin/src/views/DeptManageView.vue
@@ -343,4 +343,8 @@
.tree-sel {
width: 100%;
}
+
+:deep(.table-ops .el-button) {
+ font-size: 14px;
+}
</style>
diff --git a/frontend-admin/src/views/ExportView.vue b/frontend-admin/src/views/ExportView.vue
index cbf1789..e9b8ff1 100644
--- a/frontend-admin/src/views/ExportView.vue
+++ b/frontend-admin/src/views/ExportView.vue
@@ -32,11 +32,13 @@
<div class="pager">
<el-pagination
background
- layout="total, prev, pager, next"
+ layout="total, sizes, prev, pager, next"
:current-page="page"
:page-size="size"
+ :page-sizes="[10, 20, 50, 100]"
:total="total"
@current-change="handlePageChange"
+ @size-change="handleSizeChange"
/>
</div>
</div>
@@ -63,7 +65,7 @@
const loading = ref(false);
const rows = ref<OpLogRow[]>([]);
const page = ref(1);
-const size = ref(20);
+const size = ref(10);
const total = ref(0);
function formatTime(v: unknown) {
@@ -107,6 +109,12 @@
load();
}
+function handleSizeChange(nextSize: number) {
+ size.value = nextSize;
+ page.value = 1;
+ load();
+}
+
onMounted(load);
</script>
diff --git a/frontend-admin/src/views/LoginView.vue b/frontend-admin/src/views/LoginView.vue
index dc8c9e2..594c7ee 100644
--- a/frontend-admin/src/views/LoginView.vue
+++ b/frontend-admin/src/views/LoginView.vue
@@ -4,7 +4,7 @@
<div class="bg-glow bg-glow-right"></div>
<el-card class="card" shadow="never">
- <h2 class="title">运维运营管理平台</h2>
+ <h2 class="title">宇通行管理平台</h2>
<p class="subtitle">安全、高效地处理预约、审批与接待流程</p>
<el-form :model="form" label-position="top" class="login-form" @submit.prevent="onSubmit">
diff --git a/frontend-admin/src/views/PassAreasView.vue b/frontend-admin/src/views/PassAreasView.vue
index 2924323..1dac9f7 100644
--- a/frontend-admin/src/views/PassAreasView.vue
+++ b/frontend-admin/src/views/PassAreasView.vue
@@ -14,36 +14,40 @@
<el-button @click="resetSearch">重置</el-button>
</el-form-item>
<el-form-item class="push-right">
- <el-button type="success" @click="openCreate">添加区域</el-button>
+ <el-button type="primary" @click="openCreate">添加区域</el-button>
</el-form-item>
</el-form>
- <el-table :data="rows" v-loading="loading" stripe border>
- <el-table-column label="序号" width="64" type="index" :index="indexMethod" />
- <el-table-column prop="areaName" label="区域名称" min-width="140" show-overflow-tooltip />
- <el-table-column prop="areaDesc" label="区域说明" min-width="180" show-overflow-tooltip />
- <el-table-column label="创建时间" width="170">
- <template #default="{ row }">{{ formatTime(row.createTime) }}</template>
- </el-table-column>
- <el-table-column label="操作" width="220" fixed="right">
- <template #default="{ row }">
- <div class="table-ops">
- <el-button type="primary" link @click="openEdit(row)">编辑</el-button>
- <el-button v-if="!isSubMode" type="primary" link @click="goSub(row)">子区域管理</el-button>
- <el-button type="primary" link @click="confirmDelete(row)">删除</el-button>
- </div>
- </template>
- </el-table-column>
- </el-table>
+ <div class="table-wrap">
+ <el-table :data="rows" v-loading="loading" stripe border height="100%">
+ <el-table-column label="序号" width="64" type="index" :index="indexMethod" />
+ <el-table-column prop="areaName" label="区域名称" min-width="140" show-overflow-tooltip />
+ <el-table-column prop="areaDesc" label="区域说明" min-width="180" show-overflow-tooltip />
+ <el-table-column label="创建时间" width="170">
+ <template #default="{ row }">{{ formatTime(row.createTime) }}</template>
+ </el-table-column>
+ <el-table-column label="操作" width="220" fixed="right">
+ <template #default="{ row }">
+ <div class="table-ops">
+ <el-button type="primary" link @click="openEdit(row)">编辑</el-button>
+ <el-button v-if="!isSubMode" type="primary" link @click="goSub(row)">子区域管理</el-button>
+ <el-button type="primary" link @click="confirmDelete(row)">删除</el-button>
+ </div>
+ </template>
+ </el-table-column>
+ </el-table>
+ </div>
<el-pagination
- class="pager"
+ class="main-pager"
background
- layout="prev, pager, next"
+ layout="sizes, prev, pager, next"
:total="total"
:page-size="size"
+ :page-sizes="[10, 20, 50, 100]"
v-model:current-page="page"
@current-change="load"
+ @size-change="onSizeChange"
/>
<el-dialog v-model="dlg" :title="dlgTitle" width="520px" destroy-on-close @closed="onDlgClosed">
@@ -187,6 +191,12 @@
}
function doSearch() {
+ page.value = 1;
+ load();
+}
+
+function onSizeChange(nextSize: number) {
+ size.value = nextSize;
page.value = 1;
load();
}
@@ -337,6 +347,10 @@
<style scoped>
.page {
padding: 0;
+ display: flex;
+ flex-direction: column;
+ height: calc(100vh - 190px);
+ min-height: 420px;
}
.sub-hdr {
display: flex;
@@ -351,13 +365,19 @@
.search-form {
margin-bottom: 12px;
flex-wrap: wrap;
+ flex: none;
}
.push-right {
margin-left: auto;
}
-.pager {
+.table-wrap {
+ flex: 1;
+ min-height: 0;
+}
+.main-pager {
margin-top: 12px;
justify-content: flex-end;
+ flex: none;
}
.fullw {
width: 100%;
diff --git a/frontend-admin/src/views/RegionLocalUnitsView.vue b/frontend-admin/src/views/RegionLocalUnitsView.vue
index 22306e0..4a37298 100644
--- a/frontend-admin/src/views/RegionLocalUnitsView.vue
+++ b/frontend-admin/src/views/RegionLocalUnitsView.vue
@@ -9,33 +9,37 @@
<el-button @click="resetSearch">重置</el-button>
</el-form-item>
<el-form-item class="push-right">
- <el-button type="success" @click="openCreate">添加属地单位</el-button>
+ <el-button type="primary" @click="openCreate">添加属地单位</el-button>
</el-form-item>
</el-form>
- <el-table :data="rows" v-loading="loading" stripe border>
- <el-table-column label="序号" width="64" type="index" :index="indexMethod" />
- <el-table-column prop="unitName" label="单位名称" min-width="140" show-overflow-tooltip />
- <el-table-column prop="approverSummary" label="审批人员" min-width="160" show-overflow-tooltip />
- <el-table-column prop="remark" label="备注" min-width="120" show-overflow-tooltip />
- <el-table-column label="操作" width="140" fixed="right">
- <template #default="{ row }">
- <div class="table-ops">
- <el-button type="primary" link @click="openEdit(row)">编辑</el-button>
- <el-button type="primary" link @click="confirmDelete(row)">删除</el-button>
- </div>
- </template>
- </el-table-column>
- </el-table>
+ <div class="table-wrap">
+ <el-table :data="rows" v-loading="loading" stripe border height="100%">
+ <el-table-column label="序号" width="64" type="index" :index="indexMethod" />
+ <el-table-column prop="unitName" label="单位名称" min-width="140" show-overflow-tooltip />
+ <el-table-column prop="approverSummary" label="审批人员" min-width="160" show-overflow-tooltip />
+ <el-table-column prop="remark" label="备注" min-width="120" show-overflow-tooltip />
+ <el-table-column label="操作" width="140" fixed="right">
+ <template #default="{ row }">
+ <div class="table-ops">
+ <el-button type="primary" link @click="openEdit(row)">编辑</el-button>
+ <el-button type="primary" link @click="confirmDelete(row)">删除</el-button>
+ </div>
+ </template>
+ </el-table-column>
+ </el-table>
+ </div>
<el-pagination
- class="pager"
+ class="main-pager"
background
- layout="prev, pager, next"
+ layout="sizes, prev, pager, next"
:total="total"
:page-size="size"
+ :page-sizes="[10, 20, 50, 100]"
v-model:current-page="page"
@current-change="load"
+ @size-change="onMainSizeChange"
/>
<el-dialog v-model="dlg" :title="dlgTitle" width="720px" destroy-on-close>
@@ -156,11 +160,13 @@
<el-pagination
class="pager"
background
- layout="prev, pager, next"
+ layout="sizes, prev, pager, next"
:total="pickerTotal"
:page-size="pickerSize"
+ :page-sizes="[10, 20, 50, 100]"
v-model:current-page="pickerPage"
@current-change="loadPicker"
+ @size-change="onPickerSizeChange"
/>
<template #footer>
@@ -244,6 +250,12 @@
function resetSearch() {
filters.unitName = "";
+ page.value = 1;
+ load();
+}
+
+function onMainSizeChange(nextSize: number) {
+ size.value = nextSize;
page.value = 1;
load();
}
@@ -476,6 +488,12 @@
loadPicker();
}
+function onPickerSizeChange(nextSize: number) {
+ pickerSize.value = nextSize;
+ pickerPage.value = 1;
+ loadPicker();
+}
+
function pickerParams() {
return {
page: pickerPage.value,
@@ -547,19 +565,29 @@
<style scoped>
.page {
padding: 0;
+ display: flex;
+ flex-direction: column;
+ height: calc(100vh - 190px);
+ min-height: 420px;
}
.search-form {
margin-bottom: 12px;
display: flex;
flex-wrap: wrap;
align-items: center;
+ flex: none;
}
.push-right {
margin-left: auto;
}
-.pager {
+.table-wrap {
+ flex: 1;
+ min-height: 0;
+}
+.main-pager {
margin-top: 12px;
justify-content: flex-end;
+ flex: none;
}
.member-actions {
display: flex;
diff --git a/frontend-admin/src/views/RolesView.vue b/frontend-admin/src/views/RolesView.vue
index bfcb9ba..22d6c7a 100644
--- a/frontend-admin/src/views/RolesView.vue
+++ b/frontend-admin/src/views/RolesView.vue
@@ -1,5 +1,5 @@
<template>
- <div>
+ <div class="page">
<el-form :inline="true" class="search-form" @submit.prevent="doSearch">
<el-form-item label="角色名称">
<el-input v-model="filters.roleName" placeholder="请输入角色名称" clearable style="width: 160px" />
@@ -9,11 +9,12 @@
<el-button @click="resetSearch">重置</el-button>
</el-form-item>
<el-form-item class="push-right">
- <el-button v-permission="'sys:roles:create'" type="success" @click="goCreate">新增</el-button>
+ <el-button v-permission="'sys:roles:create'" type="primary" @click="goCreate">新增</el-button>
</el-form-item>
</el-form>
- <el-table :data="rows" v-loading="loading" stripe>
+ <div class="table-wrap">
+ <el-table :data="rows" v-loading="loading" stripe height="100%">
<el-table-column label="序号" width="64" type="index" :index="indexMethod" />
<el-table-column prop="roleName" label="角色名称" min-width="140" show-overflow-tooltip />
<el-table-column label="关联账号数" width="120" align="center">
@@ -42,16 +43,19 @@
</div>
</template>
</el-table-column>
- </el-table>
+ </el-table>
+ </div>
<el-pagination
- class="pager"
+ class="main-pager"
background
- layout="prev, pager, next"
+ layout="sizes, prev, pager, next"
:total="total"
:page-size="size"
+ :page-sizes="[10, 20, 50, 100]"
v-model:current-page="page"
@current-change="load"
+ @size-change="onSizeChange"
/>
</div>
</template>
@@ -124,6 +128,12 @@
load();
}
+function onSizeChange(nextSize: number) {
+ size.value = nextSize;
+ page.value = 1;
+ load();
+}
+
function goCreate() {
router.push({ name: "role-create" });
}
@@ -165,12 +175,24 @@
flex-wrap: wrap;
align-items: center;
gap: 4px 0;
+ flex: none;
}
.push-right {
margin-left: auto;
}
-.pager {
+.page {
+ display: flex;
+ flex-direction: column;
+ height: calc(100vh - 190px);
+ min-height: 420px;
+}
+.table-wrap {
+ flex: 1;
+ min-height: 0;
+}
+.main-pager {
margin-top: 12px;
justify-content: flex-end;
+ flex: none;
}
</style>
diff --git a/frontend-admin/src/views/StaffEmployeesView.vue b/frontend-admin/src/views/StaffEmployeesView.vue
index d28c859..a25c362 100644
--- a/frontend-admin/src/views/StaffEmployeesView.vue
+++ b/frontend-admin/src/views/StaffEmployeesView.vue
@@ -103,7 +103,8 @@
<el-button v-permission="'sys:staff:create'" type="primary" @click="openCreate">添加</el-button>
</div>
- <el-table :data="rows" v-loading="loading" stripe border class="staff-table">
+ <div class="staff-table-wrap">
+ <el-table :data="rows" v-loading="loading" stripe border class="staff-table" height="100%">
<el-table-column label="姓名" min-width="130">
<template #default="{ row }">
<div class="person-cell">
@@ -150,7 +151,8 @@
</div>
</template>
</el-table-column>
- </el-table>
+ </el-table>
+ </div>
<div class="pager-wrap">
<div class="pager-total">共 {{ total }} 条</div>
@@ -159,7 +161,7 @@
layout="sizes, prev, pager, next"
:total="total"
:page-size="size"
- :page-sizes="[10, 16, 20, 50, 100]"
+ :page-sizes="[10, 20, 50, 100]"
v-model:current-page="page"
@current-change="load"
@size-change="onSizeChange"
@@ -261,7 +263,7 @@
const avatarUploading = ref(false);
const rows = ref<StaffRow[]>([]);
const page = ref(1);
-const size = ref(16);
+const size = ref(10);
const total = ref(0);
const deptTree = ref<DeptTree[]>([]);
const deptOptions = ref<DeptTree[]>([]);
@@ -610,6 +612,7 @@
display: grid;
grid-template-columns: 250px minmax(0, 1fr);
gap: 12px;
+ height: calc(100vh - 170px);
min-height: calc(100vh - 170px);
}
@@ -631,6 +634,7 @@
flex-direction: column;
gap: 12px;
min-width: 0;
+ min-height: 0;
}
.panel-title {
@@ -710,6 +714,11 @@
.table-card {
padding: 14px 16px 12px;
+ display: flex;
+ flex-direction: column;
+ flex: 1;
+ min-height: 0;
+ overflow: hidden;
}
.table-toolbar {
@@ -718,6 +727,12 @@
align-items: center;
gap: 12px;
margin-bottom: 12px;
+ flex: none;
+}
+
+.staff-table-wrap {
+ flex: 1;
+ min-height: 0;
}
.toolbar-left {
@@ -748,6 +763,7 @@
justify-content: space-between;
align-items: center;
margin-top: 14px;
+ flex: none;
}
.pager-total {
diff --git a/frontend-admin/src/views/StaffGroupDetailView.vue b/frontend-admin/src/views/StaffGroupDetailView.vue
index 83f80cf..b8c5061 100644
--- a/frontend-admin/src/views/StaffGroupDetailView.vue
+++ b/frontend-admin/src/views/StaffGroupDetailView.vue
@@ -113,11 +113,13 @@
<el-pagination
class="pager"
background
- layout="prev, pager, next"
+ layout="sizes, prev, pager, next"
:total="pickerTotal"
:page-size="pickerSize"
+ :page-sizes="[10, 20, 50, 100]"
v-model:current-page="pickerPage"
@current-change="loadPicker"
+ @size-change="onPickerSizeChange"
/>
<template #footer>
@@ -330,6 +332,12 @@
loadPicker();
}
+function onPickerSizeChange(nextSize: number) {
+ pickerSize.value = nextSize;
+ pickerPage.value = 1;
+ loadPicker();
+}
+
function clearPickerSelection() {
pickedMap.value = new Map();
pickerTableRef.value?.clearSelection?.();
diff --git a/frontend-admin/src/views/StaffGroupsView.vue b/frontend-admin/src/views/StaffGroupsView.vue
index 2676df4..7a42879 100644
--- a/frontend-admin/src/views/StaffGroupsView.vue
+++ b/frontend-admin/src/views/StaffGroupsView.vue
@@ -12,38 +12,42 @@
<el-button @click="resetSearch">重置</el-button>
</el-form-item>
<el-form-item class="push-right">
- <el-button type="success" @click="openCreate">新建分组</el-button>
+ <el-button type="primary" @click="openCreate">新建分组</el-button>
</el-form-item>
</el-form>
- <el-table :data="rows" v-loading="loading" stripe>
- <el-table-column label="序号" width="64" type="index" :index="indexMethod" />
- <el-table-column prop="groupName" label="分组名称" min-width="140" show-overflow-tooltip />
- <el-table-column prop="leaderName" label="负责人" width="110" show-overflow-tooltip />
- <el-table-column prop="leaderMobileMasked" label="联系电话" width="140" />
- <el-table-column prop="memberCount" label="绑定人员数量" width="120" />
- <el-table-column label="创建时间" width="170">
- <template #default="{ row }">{{ formatTime(row.createTime) }}</template>
- </el-table-column>
- <el-table-column label="操作" width="240" fixed="right">
- <template #default="{ row }">
- <div class="table-ops">
- <el-button type="primary" link @click="goDetail(row)">详情</el-button>
- <el-button type="primary" link @click="openEdit(row)">编辑</el-button>
- <el-button type="primary" link @click="confirmDelete(row)">删除</el-button>
- </div>
- </template>
- </el-table-column>
- </el-table>
+ <div class="table-wrap">
+ <el-table :data="rows" v-loading="loading" stripe height="100%">
+ <el-table-column label="序号" width="64" type="index" :index="indexMethod" />
+ <el-table-column prop="groupName" label="分组名称" min-width="140" show-overflow-tooltip />
+ <el-table-column prop="leaderName" label="负责人" width="110" show-overflow-tooltip />
+ <el-table-column prop="leaderMobileMasked" label="联系电话" width="140" />
+ <el-table-column prop="memberCount" label="绑定人员数量" width="120" />
+ <el-table-column label="创建时间" width="170">
+ <template #default="{ row }">{{ formatTime(row.createTime) }}</template>
+ </el-table-column>
+ <el-table-column label="操作" width="240" fixed="right">
+ <template #default="{ row }">
+ <div class="table-ops">
+ <el-button type="primary" link @click="goDetail(row)">详情</el-button>
+ <el-button type="primary" link @click="openEdit(row)">编辑</el-button>
+ <el-button type="primary" link @click="confirmDelete(row)">删除</el-button>
+ </div>
+ </template>
+ </el-table-column>
+ </el-table>
+ </div>
<el-pagination
- class="pager"
+ class="main-pager"
background
- layout="prev, pager, next"
+ layout="sizes, prev, pager, next"
:total="total"
:page-size="size"
+ :page-sizes="[10, 20, 50, 100]"
v-model:current-page="page"
@current-change="load"
+ @size-change="onMainSizeChange"
/>
<el-dialog v-model="dlg" :title="dlgTitle" width="860px" destroy-on-close class="group-dialog">
@@ -60,7 +64,12 @@
<template #label>
<span class="req-label">负责人</span>
</template>
- <el-select v-model="form.leaderMpUserId" placeholder="请选择负责人" class="fullw">
+ <el-select
+ v-model="form.leaderMpUserId"
+ placeholder="请选择负责人"
+ class="fullw"
+ @visible-change="onLeaderVisibleChange"
+ >
<el-option
v-for="m in memberList"
:key="m.id"
@@ -172,11 +181,13 @@
<el-pagination
class="pager"
background
- layout="prev, pager, next"
+ layout="sizes, prev, pager, next"
:total="pickerTotal"
:page-size="pickerSize"
+ :page-sizes="[10, 20, 50, 100]"
v-model:current-page="pickerPage"
@current-change="loadPicker"
+ @size-change="onPickerSizeChange"
/>
<template #footer>
@@ -273,6 +284,12 @@
function resetSearch() {
filters.groupName = "";
filters.leaderMobile = "";
+ page.value = 1;
+ load();
+}
+
+function onMainSizeChange(nextSize: number) {
+ size.value = nextSize;
page.value = 1;
load();
}
@@ -411,6 +428,16 @@
membersMap.value.delete(id);
}
+function onLeaderVisibleChange(visible: boolean) {
+ if (!visible) {
+ return;
+ }
+ if (memberList.value.length > 0) {
+ return;
+ }
+ ElMessage.warning("请先选择人员,再从已有人员列表中选择负责人");
+}
+
async function submitForm() {
if (!form.groupName.trim()) {
ElMessage.warning("请填写分组名称");
@@ -524,6 +551,12 @@
loadPicker();
}
+function onPickerSizeChange(nextSize: number) {
+ pickerSize.value = nextSize;
+ pickerPage.value = 1;
+ loadPicker();
+}
+
function pickerParams() {
return {
page: pickerPage.value,
@@ -608,13 +641,25 @@
<style scoped>
.search-form {
margin-bottom: 12px;
+ flex: none;
}
.push-right {
margin-left: auto;
}
-.pager {
+.page {
+ display: flex;
+ flex-direction: column;
+ height: calc(100vh - 190px);
+ min-height: 420px;
+}
+.table-wrap {
+ flex: 1;
+ min-height: 0;
+}
+.main-pager {
margin-top: 12px;
justify-content: flex-end;
+ flex: none;
}
.member-actions {
display: flex;
diff --git a/frontend-admin/src/views/UsersView.vue b/frontend-admin/src/views/UsersView.vue
index 632597f..b518c0b 100644
--- a/frontend-admin/src/views/UsersView.vue
+++ b/frontend-admin/src/views/UsersView.vue
@@ -1,5 +1,5 @@
<template>
- <div>
+ <div class="page">
<h2 class="page-title">平台管理员</h2>
<el-form :inline="true" class="search-form" @submit.prevent="doSearch">
<el-form-item label="姓名">
@@ -34,11 +34,12 @@
<el-button @click="resetSearch">重置</el-button>
</el-form-item>
<el-form-item class="push-right">
- <el-button v-permission="'sys:users:create'" type="success" @click="openCreate">新增管理员</el-button>
+ <el-button v-permission="'sys:users:create'" type="primary" @click="openCreate">新增管理员</el-button>
</el-form-item>
</el-form>
- <el-table :data="rows" v-loading="loading" stripe>
+ <div class="table-wrap">
+ <el-table :data="rows" v-loading="loading" stripe height="100%">
<el-table-column label="序号" width="64" :index="indexMethod" type="index" />
<el-table-column prop="realName" label="姓名" width="100" show-overflow-tooltip />
<el-table-column prop="username" label="登录账号" width="120" show-overflow-tooltip />
@@ -107,16 +108,19 @@
</div>
</template>
</el-table-column>
- </el-table>
+ </el-table>
+ </div>
<el-pagination
- class="pager"
+ class="main-pager"
background
- layout="prev, pager, next"
+ layout="sizes, prev, pager, next"
:total="total"
:page-size="size"
+ :page-sizes="[10, 20, 50, 100]"
v-model:current-page="page"
@current-change="load"
+ @size-change="onSizeChange"
/>
<!-- 新增 -->
@@ -162,7 +166,7 @@
<el-option
v-for="r in roles"
:key="r.id"
- :label="`${r.roleName} (${r.roleCode})`"
+ :label="r.roleName"
:value="r.id"
/>
</el-select>
@@ -217,7 +221,7 @@
<el-option
v-for="r in roles"
:key="r.id"
- :label="`${r.roleName} (${r.roleCode})`"
+ :label="r.roleName"
:value="r.id"
/>
</el-select>
@@ -389,6 +393,12 @@
filters.mobile = "";
filters.roleId = undefined;
filters.status = undefined;
+ page.value = 1;
+ load();
+}
+
+function onSizeChange(nextSize: number) {
+ size.value = nextSize;
page.value = 1;
load();
}
@@ -659,19 +669,32 @@
font-weight: 700;
}
+.page {
+ display: flex;
+ flex-direction: column;
+ height: calc(100vh - 190px);
+ min-height: 420px;
+}
+
.search-form {
margin-bottom: 12px;
display: flex;
flex-wrap: wrap;
align-items: center;
gap: 4px 0;
+ flex: none;
}
.push-right {
margin-left: auto;
}
-.pager {
+.table-wrap {
+ flex: 1;
+ min-height: 0;
+}
+.main-pager {
margin-top: 12px;
justify-content: flex-end;
+ flex: none;
}
.avatar-upload-row {
diff --git a/frontend-admin/src/views/VisitReasonsSettingsView.vue b/frontend-admin/src/views/VisitReasonsSettingsView.vue
index 3a13545..ab1d91d 100644
--- a/frontend-admin/src/views/VisitReasonsSettingsView.vue
+++ b/frontend-admin/src/views/VisitReasonsSettingsView.vue
@@ -5,46 +5,50 @@
<el-button v-permission="'config:visit-reasons:create'" type="primary" @click="openCreate">新增</el-button>
</div>
- <el-table :data="rows" v-loading="loading" stripe border>
- <el-table-column label="序号" width="72" type="index" :index="indexMethod" />
- <el-table-column prop="reasonName" label="来访事由" min-width="220" show-overflow-tooltip />
- <el-table-column label="创建时间" width="180">
- <template #default="{ row }">{{ formatTime(row.createTime) }}</template>
- </el-table-column>
- <el-table-column label="操作" width="160" fixed="right">
- <template #default="{ row }">
- <div class="table-ops">
- <el-button
- v-if="!isOtherReason(row)"
- v-permission="'config:visit-reasons:update'"
- type="primary"
- link
- @click="openEdit(row)"
- >
- 编辑
- </el-button>
- <el-button
- v-if="!isOtherReason(row)"
- v-permission="'config:visit-reasons:delete'"
- type="primary"
- link
- @click="confirmDelete(row)"
- >
- 删除
- </el-button>
- </div>
- </template>
- </el-table-column>
- </el-table>
+ <div class="table-wrap">
+ <el-table :data="rows" v-loading="loading" stripe border height="100%">
+ <el-table-column label="序号" width="72" type="index" :index="indexMethod" />
+ <el-table-column prop="reasonName" label="来访事由" min-width="220" show-overflow-tooltip />
+ <el-table-column label="创建时间" width="180">
+ <template #default="{ row }">{{ formatTime(row.createTime) }}</template>
+ </el-table-column>
+ <el-table-column label="操作" width="160" fixed="right">
+ <template #default="{ row }">
+ <div class="table-ops">
+ <el-button
+ v-if="!isOtherReason(row)"
+ v-permission="'config:visit-reasons:update'"
+ type="primary"
+ link
+ @click="openEdit(row)"
+ >
+ 编辑
+ </el-button>
+ <el-button
+ v-if="!isOtherReason(row)"
+ v-permission="'config:visit-reasons:delete'"
+ type="primary"
+ link
+ @click="confirmDelete(row)"
+ >
+ 删除
+ </el-button>
+ </div>
+ </template>
+ </el-table-column>
+ </el-table>
+ </div>
<el-pagination
class="pager"
background
- layout="prev, pager, next"
+ layout="sizes, prev, pager, next"
:total="total"
:page-size="size"
+ :page-sizes="[10, 20, 50, 100]"
v-model:current-page="page"
@current-change="load"
+ @size-change="onSizeChange"
/>
<el-dialog v-model="dlg" :title="dlgTitle" width="460px" destroy-on-close>
@@ -133,6 +137,12 @@
dlg.value = true;
}
+function onSizeChange(nextSize: number) {
+ size.value = nextSize;
+ page.value = 1;
+ load();
+}
+
function openEdit(row: Row) {
if (isOtherReason(row)) {
return;
@@ -200,12 +210,17 @@
<style scoped>
.page {
padding: 0;
+ display: flex;
+ flex-direction: column;
+ height: calc(100vh - 190px);
+ min-height: 420px;
}
.header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 12px;
+ flex: none;
}
.section-title {
font-size: 16px;
@@ -215,8 +230,13 @@
border-left: 3px solid #409eff;
color: #303133;
}
+.table-wrap {
+ flex: 1;
+ min-height: 0;
+}
.pager {
margin-top: 12px;
justify-content: flex-end;
+ flex: none;
}
</style>
diff --git a/frontend-admin/src/views/VisitorInfoView.vue b/frontend-admin/src/views/VisitorInfoView.vue
index f586186..4e857cc 100644
--- a/frontend-admin/src/views/VisitorInfoView.vue
+++ b/frontend-admin/src/views/VisitorInfoView.vue
@@ -48,7 +48,8 @@
导出 Excel
</el-button>
</div>
- <el-table :data="rows" v-loading="loading" stripe border>
+ <div class="table-wrap">
+ <el-table :data="rows" v-loading="loading" stripe border height="100%">
<el-table-column label="序号" width="68" type="index" :index="indexMethod" />
<el-table-column prop="userName" label="用户" min-width="120" show-overflow-tooltip />
<el-table-column prop="gender" label="性别" width="88" align="center" />
@@ -87,7 +88,8 @@
</div>
</template>
</el-table-column>
- </el-table>
+ </el-table>
+ </div>
<div class="pager-wrap">
<div class="pager-total">共 {{ total }} 条</div>
@@ -96,7 +98,7 @@
layout="sizes, prev, pager, next"
:total="total"
:page-size="size"
- :page-sizes="[10, 16, 20, 50, 100]"
+ :page-sizes="[10, 20, 50, 100]"
v-model:current-page="page"
@current-change="load"
@size-change="onSizeChange"
@@ -174,7 +176,7 @@
const auth = useAuthStore();
const rows = ref<VisitorRow[]>([]);
const page = ref(1);
-const size = ref(16);
+const size = ref(10);
const total = ref(0);
const registerDateRange = ref<string[]>([]);
const dlg = ref(false);
@@ -414,6 +416,8 @@
display: flex;
flex-direction: column;
gap: 12px;
+ height: calc(100vh - 170px);
+ min-height: calc(100vh - 170px);
}
.search-card,
@@ -471,12 +475,23 @@
.table-card {
padding: 14px 16px 12px;
+ display: flex;
+ flex-direction: column;
+ flex: 1;
+ min-height: 0;
+ overflow: hidden;
}
.table-toolbar {
display: flex;
justify-content: flex-end;
margin-bottom: 12px;
+ flex: none;
+}
+
+.table-wrap {
+ flex: 1;
+ min-height: 0;
}
.pager-wrap {
@@ -484,6 +499,7 @@
justify-content: space-between;
align-items: center;
margin-top: 14px;
+ flex: none;
}
.pager-total {
diff --git a/yuyueMiniProgram/.env.development b/yuyueMiniProgram/.env.development
index 458d440..3358710 100644
--- a/yuyueMiniProgram/.env.development
+++ b/yuyueMiniProgram/.env.development
@@ -2,7 +2,7 @@
# 在开发模式下使用 (npm run dev)
# API 基础 URL - 开发环境
-VITE_API_BASE_URL=http://221.182.45.100:8880
+VITE_API_BASE_URL=https://yts.hongyu.com
# 环境名称
VITE_ENV_NAME=development
diff --git a/yuyueMiniProgram/.env.production b/yuyueMiniProgram/.env.production
index c69dc2a..97b8511 100644
--- a/yuyueMiniProgram/.env.production
+++ b/yuyueMiniProgram/.env.production
@@ -2,7 +2,7 @@
# 在生产构建时使用 (npm run build)
# API 基础 URL - 生产环境
-VITE_API_BASE_URL=http://221.182.45.100:8880
+VITE_API_BASE_URL=https://yts.hongyu.com
# 环境名称
VITE_ENV_NAME=production
diff --git a/yuyueMiniProgram/src/pages/review/index.vue b/yuyueMiniProgram/src/pages/review/index.vue
index d561c10..dd3ea61 100644
--- a/yuyueMiniProgram/src/pages/review/index.vue
+++ b/yuyueMiniProgram/src/pages/review/index.vue
@@ -294,9 +294,10 @@
.sort((left, right) => NODE_CODE_ORDER[left.nodeCode] - NODE_CODE_ORDER[right.nodeCode])
const rejectedAnchorIndex = findRejectedAnchorIndex(rows)
return rows.map((node, index) => {
+ const hiddenAfterRejected = rejectedAnchorIndex >= 0 && index > rejectedAnchorIndex
return {
title: stripBracketSuffix(node.nodeName) || NODE_CODE_TITLE[node.nodeCode] || node.nodeCode,
- time: formatFlowTime(findNodeActionUser(node)?.actionTime),
+ time: hiddenAfterRejected ? '' : formatFlowTime(findNodeActionUser(node)?.actionTime),
status: mapApprovalStepStatus(node, rejectedAnchorIndex, index),
} satisfies ApprovalStepItem
})
diff --git a/yuyueMiniProgram/src/pages/reviewDetail/index.vue b/yuyueMiniProgram/src/pages/reviewDetail/index.vue
index 5682bc5..fb9e0d9 100644
--- a/yuyueMiniProgram/src/pages/reviewDetail/index.vue
+++ b/yuyueMiniProgram/src/pages/reviewDetail/index.vue
@@ -919,7 +919,8 @@
<!-- 状态图标(右上角绝对定位) -->
<view class="absolute right-[24rpx] z-20 pointer-events-none" :style="{ top: (statusBarHeight + navBarHeight) - 5 + 'px' }">
- <image v-if="overallStatus === 'passReview'" src="/static/review/passReview.png" class="w-[156rpx] h-[156rpx]" mode="aspectFit" />
+ <image v-if="overallStatus === 'underReview'" src="/static/review/underReview.png" class="w-[156rpx] h-[156rpx]" mode="aspectFit" />
+ <image v-else-if="overallStatus === 'passReview'" src="/static/review/passReview.png" class="w-[156rpx] h-[156rpx]" mode="aspectFit" />
<image v-else-if="overallStatus === 'refueReview'" src="/static/review/refueReview.png" class="w-[156rpx] h-[156rpx]" mode="aspectFit" />
<image v-else-if="overallStatus === 'cancelReview'" src="/static/review/cancelReview.png" class="w-[156rpx] h-[156rpx]" mode="aspectFit" />
</view>
@@ -1070,7 +1071,7 @@
</template>
<!-- 其他属地单位领导审批 专属字段 -->
- <template v-if="currentReviewNode === '其他属地单位领导审批'">
+ <template v-if="currentReviewNode === '其他属地单位领导审批' && canApprove">
<view class="flex flex-col pt-[8rpx] pb-[16rpx]">
<view class="flex items-center h-[96rpx] border-b1 relative">
<view class="flex items-center shrink-0">
@@ -1133,11 +1134,11 @@
<view class="flex items-center">
<text class="text-[28rpx] font-medium" :class="['completed', 'rejected'].includes(item.status) ? 'text-[#B3B3B3]' : 'text-[#333333]'">{{ item.title }}</text>
<!-- 或签/会签/成签标签 -->
- <view v-if="item.signType === 'or'" class="ml-[12rpx] w-[64rpx] h-[32rpx] rounded-[16rpx] bg-[#F0F6FF] flex items-center justify-center box-border">
- <text class="text-[#0068FF] text-[20rpx]">或签</text>
+ <view v-if="item.signType === 'or'" class="ml-[6rpx] w-[78rpx] h-[32rpx] rounded-[16rpx] bg-[#F0F6FF] flex items-center justify-center box-border">
+ <text class="text-[#0068FF] text-[26rpx]">或签</text>
</view>
- <view v-if="item.signType === 'and'" class="ml-[12rpx] w-[64rpx] h-[32rpx] rounded-[16rpx] bg-[#F0F6FF] flex items-center justify-center box-border">
- <text class="text-[#0068FF] text-[20rpx]">会签</text>
+ <view v-if="item.signType === 'and'" class="ml-[6rpx] w-[78rpx] h-[32rpx] rounded-[16rpx] bg-[#F0F6FF] flex items-center justify-center box-border">
+ <text class="text-[#0068FF] text-[26rpx]">会签</text>
</view>
<view v-if="!item.signType && item.title === '部门负责人审批'" class="ml-[12rpx] w-[64rpx] h-[32rpx] rounded-[16rpx] bg-[#F0F6FF] flex items-center justify-center box-border">
<text class="text-[#0068FF] text-[20rpx]">成签</text>
diff --git a/yuyueMiniProgram/src/pages/visitRecord/index.vue b/yuyueMiniProgram/src/pages/visitRecord/index.vue
index 2487399..b0e02a6 100644
--- a/yuyueMiniProgram/src/pages/visitRecord/index.vue
+++ b/yuyueMiniProgram/src/pages/visitRecord/index.vue
@@ -1,5 +1,5 @@
<script setup lang="ts">
-import { onLoad } from '@dcloudio/uni-app'
+import { onLoad, onPullDownRefresh } from '@dcloudio/uni-app'
import { fetchVisitRecords } from '@/api/appointment'
import type { MiniVisitRecordItem } from '@/types/appointment'
import { normalizeVisitReasonText } from '@/utils/visitReason'
@@ -38,6 +38,7 @@
const dateValue = ref('')
const showDatePicker = ref(false)
const loading = ref(false)
+const refreshing = ref(false)
const records = ref<VisitRecordCard[]>([])
const pageTitle = ref(props.title || '来访记录')
@@ -178,6 +179,19 @@
void loadRecords()
}
+async function handlePullRefresh() {
+ if (refreshing.value) {
+ return
+ }
+ refreshing.value = true
+ try {
+ await loadRecords()
+ }
+ finally {
+ refreshing.value = false
+ }
+}
+
updateDateColumns()
onLoad((options) => {
@@ -188,6 +202,15 @@
onShow(() => {
void loadRecords()
+})
+
+onPullDownRefresh(async () => {
+ try {
+ await loadRecords()
+ }
+ finally {
+ uni.stopPullDownRefresh()
+ }
})
</script>
@@ -247,7 +270,14 @@
<view :style="{ height: (statusBarHeight + navBarHeight + uni.upx2px(144)) + 'px' }" class="shrink-0" />
<view class="relative z-10 px-[24rpx] flex-1 flex flex-col min-h-0 box-border pt-[16rpx]">
- <scroll-view scroll-y class="flex-1 min-h-0" :show-scrollbar="false">
+ <scroll-view
+ scroll-y
+ class="flex-1 min-h-0"
+ :show-scrollbar="false"
+ refresher-enabled
+ :refresher-triggered="refreshing"
+ @refresherrefresh="handlePullRefresh"
+ >
<view class="pb-[48rpx]">
<view v-for="item in records" :key="item.id" class="bg-white rounded-[8rpx] shadow-[0_4rpx_8rpx_rgba(6,47,108,0.1608)] mb-[24rpx] px-[40rpx]">
<view class="flex items-center h-[96rpx]">
--
Gitblit v1.7.1