diff --git a/src/views/client/issue/columns.tsx b/src/views/client/issue/columns.tsx
index 2d69038..d5a09b5 100644
--- a/src/views/client/issue/columns.tsx
+++ b/src/views/client/issue/columns.tsx
@@ -157,7 +157,9 @@ export const baseColumns: TableColumnItem[] = [
},
},
customRender: ({ record }) => {
- const { label, color } = stateTypeList.find((e) => e.value === record.state);
+ const obj = stateTypeList.find((e) => e.value === record.state);
+ const label = obj?.label;
+ const color = obj?.color;
return {label};
},
diff --git a/src/views/client/issue/data.ts b/src/views/client/issue/data.ts
index 2d8cc6f..6228ac9 100644
--- a/src/views/client/issue/data.ts
+++ b/src/views/client/issue/data.ts
@@ -1,32 +1,46 @@
+/*
+ * @Author: AaronWu 2463371514@qq.com
+ * @Date: 2025-04-16 14:22:07
+ * @LastEditors: AaronWu 2463371514@qq.com
+ * @LastEditTime: 2026-01-14 10:57:35
+ * @FilePath: /IssueSupportManage/src/views/client/issue/data.ts
+ * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
+ */
export const stateTypeList: any = [
- // Init(0,"待处理"),
- // Back(1,"退回"),
- // Develop(2,"开发中"),
- // Test(3,"测试中"),
- // End(4,"结束"),
+ {
+ label: '退回',
+ value: -1,
+ color: '#2db7f5',
+ },
{
label: '待处理',
value: 0,
color: '#f50',
},
{
- label: '退回',
+ label: '开发中',
value: 1,
- color: '#2db7f5',
+ color: '#87d068',
},
{
- label: '开发中',
+ label: '测试中',
value: 2,
- color: '#87d068',
+ color: '#108ee9',
},
+ // 待客户确认
{
- label: '测试中',
+ label: '待客户确认',
value: 3,
- color: '#108ee9',
+ color: '#2db7f5',
},
{
label: '已解决',
value: 4,
- color: '#f50',
+ color: '#87d068',
+ },
+ {
+ label: '关闭',
+ value: 5,
+ color: '#d9d9d9',
},
-];
+];
\ No newline at end of file
diff --git a/src/views/client/issue/index.vue b/src/views/client/issue/index.vue
index cdd094f..94840f4 100644
--- a/src/views/client/issue/index.vue
+++ b/src/views/client/issue/index.vue
@@ -275,7 +275,10 @@
...e,
};
});
- values.fileIds = values.files.filter((e) => e.id).map((e) => e.id).join(',');
+ values.fileIds = values.files
+ .filter((e) => e.id)
+ .map((e) => e.id)
+ .join(',');
}
if (values?.fileIds === ',') {
values.fileIds = '';
@@ -529,8 +532,9 @@
if (records && Array.isArray(records) && records.length) {
childItem.children = (records as any).map((e) => {
- const { label, color } = stateTypeList.find((d) => d.value === e.state);
-
+ const obj = stateTypeList.find((i) => i.value === e.state);
+ const label = obj?.label;
+ const color = obj?.color;
return {
title: e.title,
key: e.id,
@@ -567,7 +571,9 @@
if (records && Array.isArray(records) && records.length) {
tree = (records as any).map((e) => {
- const { label, color } = stateTypeList.find((d) => d.value === e.state);
+ const obj = stateTypeList.find((i) => i.value === e.state);
+ const label = obj?.label;
+ const color = obj?.color;
return {
title: e.title,
diff --git a/src/views/question/issue/columns.tsx b/src/views/question/issue/columns.tsx
index 6c269fb..7abe19f 100644
--- a/src/views/question/issue/columns.tsx
+++ b/src/views/question/issue/columns.tsx
@@ -242,7 +242,9 @@ export const baseColumns: TableColumnItem[] = [
},
},
customRender: ({ record }) => {
- const { label, color } = stateTypeList.find((e) => e.value === record.state);
+ const obj = stateTypeList.find((e) => e.value === record.state);
+ const label = obj?.label;
+ const color = obj?.color;
return {label};
},
diff --git a/src/views/question/issue/data.ts b/src/views/question/issue/data.ts
index a27f752..da8e6b1 100644
--- a/src/views/question/issue/data.ts
+++ b/src/views/question/issue/data.ts
@@ -1,43 +1,38 @@
export const stateTypeList: any = [
- // Init(0,"待处理"),
- // Back(1,"退回"),
- // Develop(2,"开发中"),
- // Test(3,"测试中"),
- // End(4,"结束"),
+ {
+ label: '退回',
+ value: -1,
+ color: '#2db7f5',
+ },
{
label: '待处理',
value: 0,
color: '#f50',
},
- {
- label: '退回',
- value: 1,
- color: '#2db7f5',
- },
{
label: '开发中',
- value: 2,
+ value: 1,
color: '#87d068',
},
{
label: '测试中',
- value: 3,
+ value: 2,
color: '#108ee9',
},
// 待客户确认
{
label: '待客户确认',
- value: 4,
+ value: 3,
color: '#2db7f5',
},
{
label: '已解决',
- value: 5,
+ value: 4,
color: '#87d068',
},
{
label: '关闭',
- value: 6,
+ value: 5,
color: '#d9d9d9',
},
];
diff --git a/src/views/question/issue/index.vue b/src/views/question/issue/index.vue
index 973f62c..2ba879c 100644
--- a/src/views/question/issue/index.vue
+++ b/src/views/question/issue/index.vue
@@ -126,6 +126,7 @@
const curRowId = ref('');
const visible = ref(false);
const quillEditor = ref | null>(null);
+ const submitting = ref(false); // 表单提交状态
const editorOptions = ref({
theme: 'snow',
modules: {
@@ -205,7 +206,11 @@
// quillImageUploadCustom(quillEditor.value);
});
- const handleOk = async () => {
+ const handleOk = useDebounceFn(async () => {
+ if (submitting.value) {
+ return;
+ }
+
const values = await formRef?.validate();
if (values) {
console.log('values: ', values);
@@ -214,43 +219,51 @@
message.warning('请等待附件上传完成');
return;
}
- values.id = curRecord.value.id;
-
- if (values.files && Array.isArray(values.files) && values.files.length) {
- values.files = values.files.map((e) => {
- if (e.response) {
+
+ submitting.value = true;
+ try {
+ values.id = curRecord.value.id;
+
+ if (values.files && Array.isArray(values.files) && values.files.length) {
+ values.files = values.files.map((e) => {
+ if (e.response) {
+ return {
+ name: e.name,
+ url: e.response.url,
+ id: e.response.id,
+ };
+ }
return {
- name: e.name,
- url: e.response.url,
- id: e.response.id,
+ ...e,
};
- }
- return {
- ...e,
- };
- });
- values.fileIds = values.files
- .filter((e) => e.id)
- .map((e) => e.id)
- .join(',');
- } else {
- values.fileIds = '';
- }
- if (values?.fileIds === ',') {
- values.fileIds = '';
- }
-
- if (values?.tags && Array.isArray(values.tags) && values.tags.length) {
- values.tags = values.tags.join(',');
+ });
+ values.fileIds = values.files
+ .filter((e) => e.id)
+ .map((e) => e.id)
+ .join(',');
+ } else {
+ values.fileIds = '';
+ }
+ if (values?.fileIds === ',') {
+ values.fileIds = '';
+ }
+
+ if (values?.tags && Array.isArray(values.tags) && values.tags.length) {
+ values.tags = values.tags.join(',');
+ }
+
+ await (values.id ? updateIssue : createIssue)(values);
+ message.success(`${values.id ? '编辑' : '新增'}成功`);
+ visible.value = false;
+ resetFormFields();
+ dynamicTableInstance?.reload();
+ } catch (error) {
+ console.error('提交失败:', error);
+ } finally {
+ submitting.value = false;
}
-
- await (values.id ? updateIssue : createIssue)(values);
- message.success(`${values.id ? '编辑' : '新增'}成功`);
- visible.value = false;
- resetFormFields();
- dynamicTableInstance?.reload();
}
- };
+ }, 300);
const handleCancel = () => {
visible.value = false;
@@ -311,17 +324,17 @@
handleEdit(record);
},
},
- {
- icon: 'init',
- size: '15',
- title: '处理',
- label: '处理',
- ifShow: stateText === '退回',
- onClick: (e) => {
- e.stopPropagation();
- changeState(record, 0);
- },
- },
+ // {
+ // icon: 'init',
+ // size: '15',
+ // title: '处理',
+ // label: '处理',
+ // ifShow: stateText === '退回',
+ // onClick: (e) => {
+ // e.stopPropagation();
+ // changeState(record, 0);
+ // },
+ // },
{
icon: 'dev',
size: '15',
@@ -330,7 +343,7 @@
ifShow: stateText === '待处理',
onClick: (e) => {
e.stopPropagation();
- changeState(record, 2);
+ changeState(record, 1);
},
},
{
@@ -338,10 +351,10 @@
size: '20',
title: '退回',
label: '退回',
- ifShow: stateText === '开发中' || stateText === '测试中',
+ ifShow: stateText !== '待处理' && stateText !== '关闭',
onClick: (e) => {
e.stopPropagation();
- changeState(record, 1);
+ changeState(record, record.state - 1);
},
},
{
@@ -352,7 +365,7 @@
ifShow: stateText === '开发中',
onClick: (e) => {
e.stopPropagation();
- changeState(record, 3);
+ changeState(record, 2);
},
},
// 待客户确认 4
@@ -364,7 +377,7 @@
ifShow: stateText === '测试中',
onClick: (e) => {
e.stopPropagation();
- changeState(record, 4);
+ changeState(record, 3);
},
},
{
@@ -375,7 +388,7 @@
ifShow: stateText === '待客户确认',
onClick: (e) => {
e.stopPropagation();
- changeState(record, 5);
+ changeState(record, 4);
},
},
{
@@ -397,7 +410,7 @@
ifShow: stateText !== '关闭',
onClick: (e) => {
e.stopPropagation();
- changeState(record, 6);
+ changeState(record, 5);
},
},
{
@@ -425,44 +438,62 @@
/**
* @description 打开问题工单弹窗
*/
+ // 创建防抖的提交处理函数
+ const createSubmitHandler = (record: Partial, isModal = false) => {
+ let isSubmitting = false;
+ return useDebounceFn(async (values: any) => {
+ if (isSubmitting) {
+ return;
+ }
+ isSubmitting = true;
+ try {
+ console.log('新增/编辑问题工单', values);
+ values.id = record.id;
+
+ if (values.files && Array.isArray(values.files) && values.files.length) {
+ values.files = values.files.map((e) => {
+ if (e.response) {
+ return {
+ name: e.name,
+ url: e.response.url,
+ id: e.response.id,
+ };
+ }
+ return {
+ ...e,
+ };
+ });
+ values.fileIds = values.files
+ .filter((e) => e.id)
+ .map((e) => e.id)
+ .join(',');
+ } else {
+ values.fileIds = '';
+ }
+
+ if (values?.tags && Array.isArray(values.tags) && values.tags.length) {
+ values.tags = values.tags.join(',');
+ }
+
+ await (record.id ? updateIssue : createIssue)(values);
+ message.success(`${record.id ? '编辑' : '新增'}成功`);
+ dynamicTableInstance?.reload();
+ } catch (error) {
+ console.error('提交失败:', error);
+ } finally {
+ isSubmitting = false;
+ }
+ }, 300);
+ };
+
const openIssueModal = async (record: Partial = {}, isReadOnly = false) => {
+ const handleSubmit = createSubmitHandler(record);
+
const [formRef] = await showModal({
modalProps: {
title: `${isReadOnly ? '查看' : record.id ? '编辑' : '新增'}问题工单`,
width: 700,
- onFinish: async (values) => {
- console.log('新增/编辑问题工单', values);
- values.id = record.id;
-
- if (values.files && Array.isArray(values.files) && values.files.length) {
- values.files = values.files.map((e) => {
- if (e.response) {
- return {
- name: e.name,
- url: e.response.url,
- id: e.response.id,
- };
- }
- return {
- ...e,
- };
- });
- values.fileIds = values.files
- .filter((e) => e.id)
- .map((e) => e.id)
- .join(',');
- } else {
- values.fileIds = '';
- }
-
- if (values?.tags && Array.isArray(values.tags) && values.tags.length) {
- values.tags = values.tags.join(',');
- }
-
- await (record.id ? updateIssue : createIssue)(values);
- message.success(`${record.id ? '编辑' : '新增'}成功`);
- dynamicTableInstance?.reload();
- },
+ onFinish: handleSubmit,
footer: isReadOnly ? null : undefined,
},
formProps: {
@@ -499,26 +530,40 @@
const openFlowModal = async (record: Partial = {}, state) => {
const flowTitle = stateTypeList.find((item) => item.value === state)?.label;
+
+ let isFlowSubmitting = false;
+ const handleFlowSubmit = useDebounceFn(async (values: any) => {
+ if (isFlowSubmitting) {
+ return;
+ }
+ isFlowSubmitting = true;
+ try {
+ await updateIssueState({
+ id: record.id,
+ state: state,
+ ...values,
+ });
+ message.success(`操作成功`);
+ dynamicTableInstance?.reload();
+ // 判断当前行是否有选中
+ if (curRowId.value === record.id) {
+ curRowId.value = '';
+ nextTick(() => {
+ curRowId.value = record.id;
+ });
+ }
+ } catch (error) {
+ console.error('提交失败:', error);
+ } finally {
+ isFlowSubmitting = false;
+ }
+ }, 300);
+
const [formRef] = await showFlowModal({
modalProps: {
title: `${flowTitle}问题工单`,
width: 700,
- onFinish: async (values) => {
- await updateIssueState({
- id: record.id,
- state: state,
- ...values,
- });
- message.success(`操作成功`);
- dynamicTableInstance?.reload();
- // 判断当前行是否有选中
- if (curRowId.value === record.id) {
- curRowId.value = '';
- nextTick(() => {
- curRowId.value = record.id;
- });
- }
- },
+ onFinish: handleFlowSubmit,
},
formProps: {
labelWidth: 100,
diff --git a/src/views/question/knowledge/index.vue b/src/views/question/knowledge/index.vue
index 903681c..eac977a 100644
--- a/src/views/question/knowledge/index.vue
+++ b/src/views/question/knowledge/index.vue
@@ -98,6 +98,7 @@
import { createDictValue } from '@/api/dict';
import { DictEnum } from '@/enums/dictEnum';
import { getDictionaryByTypeName } from '@/utils/dict';
+ import { useDebounceFn } from '@vueuse/core';
defineOptions({
name: 'knowledge',
});
@@ -106,6 +107,7 @@
const curRecord = ref>({});
const visible = ref(false);
+ const submitting = ref(false); // 表单提交状态
const quillEditor = ref | null>(null);
@@ -170,7 +172,11 @@
// quillImageUploadCustom(quillEditor.value);
});
- const handleOk = async () => {
+ const handleOk = useDebounceFn(async () => {
+ if (submitting.value) {
+ return;
+ }
+
const values = await formRef?.validate();
if (values) {
console.log('values: ', values);
@@ -179,57 +185,65 @@
message.warning('请等待附件上传完成');
return;
}
- values.id = curRecord.value.id;
- if (values.files && Array.isArray(values.files) && values.files.length) {
- values.files = values.files.map((e) => {
- if (e.response) {
+ submitting.value = true;
+ try {
+ values.id = curRecord.value.id;
+
+ if (values.files && Array.isArray(values.files) && values.files.length) {
+ values.files = values.files.map((e) => {
+ if (e.response) {
+ return {
+ name: e.name,
+ url: e.response.url,
+ id: e.response.id,
+ };
+ }
return {
- name: e.name,
- url: e.response.url,
- id: e.response.id,
+ ...e,
};
- }
- return {
- ...e,
- };
- });
- values.fileIds = values.files
- .filter((e) => e.id)
- .map((e) => e.id)
- .join(',');
- } else {
- values.fileIds = '';
- }
+ });
+ values.fileIds = values.files
+ .filter((e) => e.id)
+ .map((e) => e.id)
+ .join(',');
+ } else {
+ values.fileIds = '';
+ }
- if (values?.fileIds === ',') {
- values.fileIds = '';
- }
+ if (values?.fileIds === ',') {
+ values.fileIds = '';
+ }
- if (values?.tags && Array.isArray(values.tags) && values.tags.length) {
- const allTags = (await getDictionaryByTypeName(DictEnum.TAG_TYPE)) || [];
- // 找出values.tags中不在allTags中的值
- const notInTags = values.tags.filter((tag) => {
- return !allTags.some((e) => e.value === tag);
- });
- console.log('notInTags: ', notInTags);
- for (const tag of notInTags) {
- await createDictValue({
- dictValue: tag,
- typeId: 33,
- enable: 1,
+ if (values?.tags && Array.isArray(values.tags) && values.tags.length) {
+ const allTags = (await getDictionaryByTypeName(DictEnum.TAG_TYPE)) || [];
+ // 找出values.tags中不在allTags中的值
+ const notInTags = values.tags.filter((tag) => {
+ return !allTags.some((e) => e.value === tag);
});
+ console.log('notInTags: ', notInTags);
+ for (const tag of notInTags) {
+ await createDictValue({
+ dictValue: tag,
+ typeId: 33,
+ enable: 1,
+ });
+ }
+ values.tags = values.tags.join(',');
}
- values.tags = values.tags.join(',');
- }
- await (values.id ? updateKnowledgeBase : createKnowledgeBase)(values);
- message.success(`${values.id ? '编辑' : '新增'}成功`);
- visible.value = false;
- resetFormFields();
- dynamicTableInstance?.reload();
+ await (values.id ? updateKnowledgeBase : createKnowledgeBase)(values);
+ message.success(`${values.id ? '编辑' : '新增'}成功`);
+ visible.value = false;
+ resetFormFields();
+ dynamicTableInstance?.reload();
+ } catch (error) {
+ console.error('提交失败:', error);
+ } finally {
+ submitting.value = false;
+ }
}
- };
+ }, 300);
const handleCancel = () => {
visible.value = false;
@@ -283,39 +297,52 @@
record: Partial = {},
isReadOnly = false,
) => {
+ let isModalSubmitting = false;
+ const handleModalSubmit = useDebounceFn(async (values: any) => {
+ if (isModalSubmitting) {
+ return;
+ }
+ isModalSubmitting = true;
+ try {
+ console.log('新增/编辑知识库', values);
+ values.id = record.id;
+
+ if (values.files && Array.isArray(values.files) && values.files.length) {
+ values.files = values.files.map((e) => {
+ if (e.response) {
+ return {
+ name: e.name,
+ url: e.response.url,
+ id: e.response.id,
+ };
+ }
+ return {
+ ...e,
+ };
+ });
+ values.fileIds = values.files
+ .filter((e) => e.id)
+ .map((e) => e.id)
+ .join(',');
+ } else {
+ values.fileIds = '';
+ }
+
+ await (record.id ? updateKnowledgeBase : createKnowledgeBase)(values);
+ message.success(`${record.id ? '编辑' : '新增'}成功`);
+ dynamicTableInstance?.reload();
+ } catch (error) {
+ console.error('提交失败:', error);
+ } finally {
+ isModalSubmitting = false;
+ }
+ }, 300);
+
const [formRef] = await showModal({
modalProps: {
title: `${isReadOnly ? '查看' : record.id ? '编辑' : '新增'}知识库`,
width: 700,
- onFinish: async (values) => {
- console.log('新增/编辑知识库', values);
- values.id = record.id;
-
- if (values.files && Array.isArray(values.files) && values.files.length) {
- values.files = values.files.map((e) => {
- if (e.response) {
- return {
- name: e.name,
- url: e.response.url,
- id: e.response.id,
- };
- }
- return {
- ...e,
- };
- });
- values.fileIds = values.files
- .filter((e) => e.id)
- .map((e) => e.id)
- .join(',');
- } else {
- values.fileIds = '';
- }
-
- await (record.id ? updateKnowledgeBase : createKnowledgeBase)(values);
- message.success(`${record.id ? '编辑' : '新增'}成功`);
- dynamicTableInstance?.reload();
- },
+ onFinish: handleModalSubmit,
footer: isReadOnly ? null : undefined,
},
formProps: {
diff --git a/vite.config.ts b/vite.config.ts
index 80883d9..e954652 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.22:8089',
+ // target: 'http://192.168.2.27:8089',
changeOrigin: true,
rewrite: (path) => path.replace(/^\/server/, '/server'),
},