-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+ 查询条件
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -38,10 +88,11 @@
import { useForm } from '@/components/core/schema-form';
import { getEditFormSchema } from './formSchemas';
import { useRoute } from 'vue-router';
- import { onMounted, ref } from 'vue';
- import { findOneById } from '@/api/knowledgeBase';
+ import { onMounted, ref, computed, watch } from 'vue';
+ import { findOneById, fetchKnowledgeBasePageList } from '@/api/knowledgeBase';
import { SvgIcon } from '@/components/basic/svg-icon';
import { stateTypeList } from './data';
+ import { LeftOutlined, RightOutlined, SearchOutlined } from '@ant-design/icons-vue';
const route = useRoute();
const editorOptions = ref({
theme: 'snow',
@@ -66,7 +117,47 @@
const current = ref(0);
- const { id } = route.query;
+ // 当前 id(用于 watch)
+ const currentId = ref
(route.query.id as string | undefined);
+
+ // 上一页和下一页的 id
+ const prevId = ref(null);
+ const nextId = ref(null);
+
+ // 查询参数(排除id)- 直接从 route.query 获取,确保响应式更新
+ const queryParams = computed(() => {
+ const params: Record = {};
+ Object.keys(route.query).forEach((key) => {
+ // 排除 id 参数
+ if (
+ key !== 'id' &&
+ route.query[key] !== undefined &&
+ route.query[key] !== null &&
+ route.query[key] !== ''
+ ) {
+ params[key] = String(route.query[key]);
+ }
+ });
+ return params;
+ });
+
+ // 是否有查询参数
+ const hasQueryParams = computed(() => {
+ return Object.keys(queryParams.value).length > 0;
+ });
+
+ // 格式化日期范围显示
+ const formatDateRange = (dateStr: string) => {
+ if (!dateStr) return '';
+ // 如果是逗号分隔的日期范围
+ if (dateStr.includes(',')) {
+ const dates = dateStr.split(',');
+ if (dates.length === 2) {
+ return `${dates[0]} 至 ${dates[1]}`;
+ }
+ }
+ return dateStr;
+ };
const [SchemaForm, formRef] = useForm({
labelWidth: 150,
@@ -81,35 +172,232 @@
disabled: true,
});
- onMounted(async () => {
- loading.value = true;
- const res = await findOneById({ id: id as string });
- loading.value = false;
-
- if (res?.files && Array.isArray(res.files) && res.files.length) {
- res.files = res.files.map((e) => {
- return {
- name: e.originalFilename,
- url: e.url,
- id: e.id,
- };
+ // 获取列表数据,找到当前记录的位置
+ const loadListData = async () => {
+ try {
+ // 构建查询参数
+ const searchParams: any = {
+ current: 1,
+ size: 1000, // 获取足够多的数据以便查找
+ };
+
+ // 处理查询参数 - 从 route.query 直接获取,确保获取到最新的查询参数
+ const currentQuery = route.query;
+ if (currentQuery.title) {
+ searchParams.title = String(currentQuery.title);
+ }
+ if (currentQuery.description) {
+ searchParams.description = String(currentQuery.description);
+ }
+ if (currentQuery.createTime) {
+ const dateStr = String(currentQuery.createTime);
+ if (dateStr.includes(',')) {
+ const dates = dateStr.split(',');
+ if (dates.length === 2) {
+ searchParams.startDate = dates[0];
+ searchParams.endDate = dates[1];
+ }
+ }
+ }
+
+ // 添加其他可能的查询参数
+ Object.keys(currentQuery).forEach((key) => {
+ if (key !== 'id' && key !== 'title' && key !== 'description' && key !== 'createTime') {
+ const value = currentQuery[key];
+ if (value !== undefined && value !== null && value !== '') {
+ searchParams[key] = String(value);
+ }
+ }
});
+
+ console.log('加载列表数据,查询参数:', searchParams);
+ const res = await fetchKnowledgeBasePageList(searchParams);
+ const list = res.data?.records || [];
+ console.log('获取到的列表数据,总数:', list.length);
+
+ // 找到当前记录在列表中的位置
+ const currentIdValue = currentId.value || (route.query.id as string);
+ const currentIndex = list.findIndex((item: any) => item.id == currentIdValue);
+ console.log('当前记录索引:', currentIndex, '当前ID:', currentIdValue);
+
+ if (currentIndex !== -1) {
+ // 设置上一页和下一页的 id
+ prevId.value = currentIndex > 0 ? list[currentIndex - 1].id : null;
+ nextId.value = currentIndex < list.length - 1 ? list[currentIndex + 1].id : null;
+ console.log('上一页ID:', prevId.value, '下一页ID:', nextId.value);
+ } else {
+ // 如果找不到当前记录,清空上一页和下一页
+ prevId.value = null;
+ nextId.value = null;
+ console.warn('未找到当前记录在列表中');
+ }
+ } catch (error) {
+ console.error('获取列表数据失败:', error);
+ prevId.value = null;
+ nextId.value = null;
}
+ };
- if (res.historys && Array.isArray(res.historys) && res.historys.length) {
- historyList.value = res.historys.map((e) => {
- return {
- state: e.state,
- remark: `${e.createUserName}于${e.createTime} : ${e.remark}`,
- title: stateTypeList.find((item) => item.value === e.state)?.label,
- };
- });
+ // 加载详情数据
+ const loadDetailData = async (targetId: string) => {
+ if (!targetId) {
+ return;
}
- current.value = res?.state;
+ currentId.value = targetId;
+ loading.value = true;
+
+ try {
+ const res = await findOneById({ id: targetId });
+
+ if (res?.files && Array.isArray(res.files) && res.files.length) {
+ res.files = res.files.map((e) => {
+ return {
+ name: e.originalFilename,
+ url: e.url,
+ id: e.id,
+ };
+ });
+ }
+
+ if (res.historys && Array.isArray(res.historys) && res.historys.length) {
+ historyList.value = res.historys.map((e) => {
+ return {
+ state: e.state,
+ remark: `${e.createUserName}于${e.createTime} : ${e.remark}`,
+ title: stateTypeList.find((item) => item.value === e.state)?.label,
+ };
+ });
+ } else {
+ historyList.value = [];
+ }
+
+ current.value = res?.state;
- formRef?.setFieldsValue(res);
- formRef?.clearValidate();
+ formRef?.setFieldsValue(res);
+ formRef?.clearValidate();
+
+ // 重新加载列表数据以更新上一页和下一页
+ await loadListData();
+ } catch (error) {
+ console.error('加载详情数据失败:', error);
+ } finally {
+ loading.value = false;
+ }
+ };
+
+ // 跳转到上一页
+ const handlePrev = () => {
+ if (prevId.value) {
+ loadDetailData(prevId.value);
+ }
+ };
+
+ // 跳转到下一页
+ const handleNext = () => {
+ if (nextId.value) {
+ loadDetailData(nextId.value);
+ }
+ };
+
+ onMounted(async () => {
+ const currentIdValue = route.query.id as string;
+ if (!currentIdValue) {
+ console.warn('未找到 id 参数');
+ return;
+ }
+ await loadDetailData(currentIdValue);
});
+
+ // 监听路由变化,重新加载数据(用于从外部路由跳转过来的情况)
+ watch(
+ () => route.query.id,
+ async (newId) => {
+ if (newId && newId !== currentId.value) {
+ await loadDetailData(newId as string);
+ }
+ },
+ );
-
+
diff --git a/src/views/question/knowledge/index.vue b/src/views/question/knowledge/index.vue
index e94ac8a..903681c 100644
--- a/src/views/question/knowledge/index.vue
+++ b/src/views/question/knowledge/index.vue
@@ -351,11 +351,37 @@
};
const handleView = (record: TableListItem) => {
+ // 获取查询表单的参数
+ const queryFormRef = dynamicTableInstance?.getQueryFormRef();
+ const queryParams: Record = {
+ id: record.id,
+ };
+
+ if (queryFormRef) {
+ const formValues = queryFormRef.getFieldsValue();
+ // 过滤空值,只传递有值的查询参数
+ Object.keys(formValues).forEach((key) => {
+ const value = formValues[key];
+ // 过滤掉空字符串、null、undefined和空数组
+ if (
+ value !== undefined &&
+ value !== null &&
+ value !== '' &&
+ !(Array.isArray(value) && value.length === 0)
+ ) {
+ // 如果是数组,转换为字符串(用于日期范围等)
+ if (Array.isArray(value)) {
+ queryParams[key] = value.join(',');
+ } else {
+ queryParams[key] = value;
+ }
+ }
+ });
+ }
+
router.push({
path: '/question/knowledgeDetail',
- query: {
- id: record.id,
- },
+ query: queryParams,
});
};
diff --git a/src/views/system/user/index.vue b/src/views/system/user/index.vue
index 334048c..8960702 100644
--- a/src/views/system/user/index.vue
+++ b/src/views/system/user/index.vue
@@ -54,6 +54,7 @@
deleteUserById,
deleteBatchUserById,
updateAuditState,
+ resetUserPassword,
} from '@/api/user';
import { computed, reactive, ref, toRaw } from 'vue';
import { Modal, message, Alert } from 'ant-design-vue';
@@ -99,6 +100,12 @@
vShow: record.auditState === 0,
onClick: () => handleAudit(record),
},
+ {
+ icon: 'resetPwd',
+ color: '#f59e0b',
+ label: '重置密码',
+ onClick: () => handleResetPassword(record),
+ },
{
icon: 'delete',
color: '#ec6f6f',
@@ -152,6 +159,50 @@
dynamicTableInstance?.reload();
};
+ const handleResetPassword = async (record: TableListItem) => {
+ const { id, username } = record;
+ if (!id) return;
+
+ Modal.confirm({
+ title: '重置密码',
+ content: `确定要重置用户 "${username}" 的密码吗?`,
+ icon: ,
+ centered: true,
+ onOk: async () => {
+ try {
+ const res = await resetUserPassword({ id });
+ const newPassword = res;
+
+ // 复制密码到剪切板
+ try {
+ await navigator.clipboard.writeText(newPassword);
+ Modal.success({
+ title: '重置密码成功',
+ content: `新密码为:${newPassword}(已复制到剪切板)`,
+ centered: true,
+ });
+ } catch (clipboardError) {
+ // 如果剪切板API失败,使用传统方法
+ const textArea = document.createElement('textarea');
+ textArea.value = newPassword;
+ document.body.appendChild(textArea);
+ textArea.select();
+ document.execCommand('copy');
+ document.body.removeChild(textArea);
+
+ Modal.success({
+ title: '重置密码成功',
+ content: `新密码为:${newPassword}(已复制到剪切板)`,
+ centered: true,
+ });
+ }
+ } catch (error) {
+ message.error('重置密码失败');
+ }
+ },
+ });
+ };
+
const handleEdit = (record: TableListItem) => {
openUserModal(record);
};
diff --git a/vite.config.ts b/vite.config.ts
index ad82baf..80883d9 100644
--- a/vite.config.ts
+++ b/vite.config.ts
@@ -126,7 +126,7 @@ export default defineConfig({
// },
'/server': {
target: 'http://43.137.2.78:8085',
- // target: 'http://192.168.2.64:8089',
+ // target: 'http://192.168.2.22:8089',
changeOrigin: true,
rewrite: (path) => path.replace(/^\/server/, '/server'),
},