miaofuhao vor 2 Wochen
Ursprung
Commit
8cf2f35ff7

+ 188 - 184
apps/web-ele/src/views/knowledge/edit/edit-drawer.vue

@@ -1,184 +1,188 @@
1
-<script lang="ts" setup>
2
-import { ref } from 'vue';
3
-
4
-import { useVbenDrawer, useVbenForm } from '@vben/common-ui';
5
-
6
-import { Plus } from '@element-plus/icons-vue';
7
-import { ElIcon, ElUpload } from 'element-plus';
8
-
9
-import TinymceEditor from '#/components/tinymce/src/editor.vue';
10
-
11
-import { drawerFormSchema } from './config-data';
12
-
13
-const emit = defineEmits<{
14
-  reload: [];
15
-}>();
16
-
17
-// 附件列表
18
-const attachments = ref<any[]>([]);
19
-const uploadUrlRef = ref<string>('');
20
-
21
-// 表单配置
22
-const [Form, formApi] = useVbenForm({
23
-  showDefaultActions: false,
24
-  schema: drawerFormSchema(),
25
-});
26
-
27
-// 处理附件上传
28
-function handleAttachmentUpload(options: any) {
29
-  // 模拟上传成功处理
30
-  const fileData = {
31
-    uid: options.file.uid,
32
-    name: options.file.name,
33
-    url: URL.createObjectURL(options.file),
34
-    status: 'success',
35
-    raw: options.file,
36
-  };
37
-
38
-  // 多个文件上传时,url以逗号隔开
39
-  uploadUrlRef.value = uploadUrlRef.value
40
-    ? `${uploadUrlRef.value},${fileData.url}`
41
-    : fileData.url;
42
-
43
-  options.onSuccess(fileData);
44
-}
45
-
46
-// 移除附件
47
-function handleAttachmentRemove(file: any, fileList: any[]) {
48
-  attachments.value = fileList;
49
-  // 更新上传url,移除已删除的文件
50
-  uploadUrlRef.value = fileList
51
-    .filter((item: any) => item.status === 'success')
52
-    .map((item: any) => item.url)
53
-    .join(',');
54
-}
55
-
56
-// 预览附件
57
-function handleAttachmentPreview(file: any) {
58
-  console.log('预览附件', file);
59
-  // TODO: 实现附件预览功能
60
-}
61
-
62
-// 确认编辑
63
-async function handleConfirm() {
64
-  try {
65
-    const { valid } = await formApi.validate();
66
-    if (!valid) {
67
-      return;
68
-    }
69
-    const data = await formApi.getValues();
70
-
71
-    // 处理附件url,转换为逗号分隔的字符串
72
-    data.attachments = uploadUrlRef.value;
73
-
74
-    // 模拟提交数据
75
-    console.log('提交数据:', data);
76
-    // TODO: 实现真实的API调用
77
-
78
-    // 提交成功后触发reload事件
79
-    emit('reload');
80
-    drawerApi.close();
81
-  } catch (error) {
82
-    console.error('保存失败:', error);
83
-  }
84
-}
85
-
86
-const isUpdateRef = ref<boolean>(false);
87
-
88
-const [Drawer, drawerApi] = useVbenDrawer({
89
-  async onOpenChange(isOpen) {
90
-    if (!isOpen) {
91
-      return;
92
-    }
93
-    try {
94
-      drawerApi.drawerLoading(true);
95
-      const { chapter, isUpdate } = drawerApi.getData();
96
-      isUpdateRef.value = isUpdate;
97
-      if (isUpdate && chapter) {
98
-        // 处理附件url,转换为文件列表格式
99
-        const attachmentsList = chapter.attachments
100
-          ? chapter.attachments
101
-              .split(',')
102
-              .map((url: string, index: number) => ({
103
-                uid: Date.now() + index,
104
-                name: url.split('/').pop() || `文件${index + 1}`,
105
-                url,
106
-                status: 'success',
107
-              }))
108
-          : [];
109
-
110
-        uploadUrlRef.value = chapter.attachments || '';
111
-        attachments.value = attachmentsList;
112
-
113
-        // 设置表单数据
114
-        await formApi.setValues({
115
-          ...chapter,
116
-          content: chapter.content || '',
117
-          attachments: attachmentsList,
118
-        });
119
-      } else {
120
-        // 新增时重置表单
121
-        await formApi.resetForm();
122
-        attachments.value = [];
123
-        uploadUrlRef.value = '';
124
-      }
125
-    } catch (error) {
126
-      console.error('加载数据失败:', error);
127
-    } finally {
128
-      drawerApi.drawerLoading(false);
129
-    }
130
-  },
131
-  async onConfirm() {
132
-    await handleConfirm();
133
-  },
134
-  onClosed() {
135
-    formApi.resetForm();
136
-    attachments.value = [];
137
-    uploadUrlRef.value = '';
138
-  },
139
-});
140
-</script>
141
-
142
-<template>
143
-  <Drawer :title="isUpdateRef ? '编辑章节' : '新增章节'">
144
-    <Form>
145
-      <!-- 自定义Tinymce编辑器插槽 -->
146
-      <template #content="scope">
147
-        <TinymceEditor v-model="scope.modelValue" :height="400" />
148
-      </template>
149
-
150
-      <!-- 自定义附件上传插槽 -->
151
-      <template #attachments="scope">
152
-        <ElUpload
153
-          v-model:file-list="attachments"
154
-          action="#"
155
-          accept=".jpg,.jpeg,.png,.gif,.pdf,.doc,.docx,.xls,.xlsx,.ppt,.pptx"
156
-          list-type="text"
157
-          show-file-list
158
-          :auto-upload="true"
159
-          :drag="false"
160
-          :limit="5"
161
-          :multiple="true"
162
-          :http-request="handleAttachmentUpload"
163
-          :on-remove="handleAttachmentRemove"
164
-          :on-preview="handleAttachmentPreview"
165
-          class="mb-4"
166
-        >
167
-          <div class="flex items-center justify-center">
168
-            <ElIcon class="el-upload__icon">
169
-              <Plus size="18" />
170
-            </ElIcon>
171
-            <div class="el-upload__text">
172
-              <div>上传附件</div>
173
-              <div class="text-xs text-gray-500">最多上传5个附件</div>
174
-            </div>
175
-          </div>
176
-        </ElUpload>
177
-      </template>
178
-    </Form>
179
-  </Drawer>
180
-</template>
181
-
182
-<style scoped lang="scss">
183
-/* 自定义样式 */
184
-</style>
1
+<script lang="ts" setup>
2
+import { ref } from 'vue';
3
+
4
+import { useVbenDrawer, useVbenForm } from '@vben/common-ui';
5
+
6
+import { Plus } from '@element-plus/icons-vue';
7
+import { ElIcon, ElUpload } from 'element-plus';
8
+
9
+import TinymceEditor from '#/components/tinymce/src/editor.vue';
10
+
11
+import { drawerFormSchema } from './config-data';
12
+
13
+const emit = defineEmits<{
14
+  reload: [];
15
+}>();
16
+
17
+// 附件列表
18
+const attachments = ref<any[]>([]);
19
+const uploadUrlRef = ref<string>('');
20
+
21
+// 表单配置
22
+const [Form, formApi] = useVbenForm({
23
+  showDefaultActions: false,
24
+  schema: drawerFormSchema(),
25
+});
26
+
27
+// 处理附件上传
28
+function handleAttachmentUpload(options: any): Promise<unknown> {
29
+  return new Promise((resolve) => {
30
+    // 模拟上传成功处理
31
+    const fileData = {
32
+      uid: options.file.uid,
33
+      name: options.file.name,
34
+      url: URL.createObjectURL(options.file),
35
+      status: 'success',
36
+      raw: options.file,
37
+    };
38
+
39
+    // 多个文件上传时,url以逗号隔开
40
+    uploadUrlRef.value = uploadUrlRef.value
41
+      ? `${uploadUrlRef.value},${fileData.url}`
42
+      : fileData.url;
43
+
44
+    options.onSuccess(fileData);
45
+    resolve(fileData);
46
+  });
47
+}
48
+
49
+// 移除附件
50
+function handleAttachmentRemove(file: any, fileList: any[]) {
51
+  attachments.value = fileList;
52
+  // 更新上传url,移除已删除的文件
53
+  uploadUrlRef.value = fileList
54
+    .filter((item: any) => item.status === 'success')
55
+    .map((item: any) => item.url)
56
+    .join(',');
57
+}
58
+
59
+// 预览附件
60
+function handleAttachmentPreview(file: any) {
61
+  console.log('预览附件', file);
62
+  // TODO: 实现附件预览功能
63
+}
64
+
65
+// 确认编辑
66
+async function handleConfirm() {
67
+  try {
68
+    const { valid } = await formApi.validate();
69
+    if (!valid) {
70
+      return;
71
+    }
72
+    const data = await formApi.getValues();
73
+
74
+    // 处理附件url,转换为逗号分隔的字符串
75
+    data.attachments = uploadUrlRef.value;
76
+
77
+    // 模拟提交数据
78
+    console.log('提交数据:', data);
79
+    // TODO: 实现真实的API调用
80
+
81
+    // 提交成功后触发reload事件
82
+    emit('reload');
83
+    drawerApi.close();
84
+  } catch (error) {
85
+    console.error('保存失败:', error);
86
+  }
87
+}
88
+
89
+const isUpdateRef = ref<boolean>(false);
90
+
91
+const [Drawer, drawerApi] = useVbenDrawer({
92
+  async onOpenChange(isOpen) {
93
+    if (!isOpen) {
94
+      return;
95
+    }
96
+    try {
97
+      drawerApi.drawerLoading(true);
98
+      const { chapter, isUpdate } = drawerApi.getData();
99
+      isUpdateRef.value = isUpdate;
100
+      if (isUpdate && chapter) {
101
+        // 处理附件url,转换为文件列表格式
102
+        const attachmentsList = chapter.attachments
103
+          ? chapter.attachments
104
+              .split(',')
105
+              .map((url: string, index: number) => ({
106
+                uid: Date.now() + index,
107
+                name: url.split('/').pop() || `文件${index + 1}`,
108
+                url,
109
+                status: 'success',
110
+              }))
111
+          : [];
112
+
113
+        uploadUrlRef.value = chapter.attachments || '';
114
+        attachments.value = attachmentsList;
115
+
116
+        // 设置表单数据
117
+        await formApi.setValues({
118
+          ...chapter,
119
+          content: chapter.content || '',
120
+          attachments: attachmentsList,
121
+        });
122
+      } else {
123
+        // 新增时重置表单
124
+        await formApi.resetForm();
125
+        attachments.value = [];
126
+        uploadUrlRef.value = '';
127
+      }
128
+    } catch (error) {
129
+      console.error('加载数据失败:', error);
130
+    } finally {
131
+      drawerApi.drawerLoading(false);
132
+    }
133
+  },
134
+  async onConfirm() {
135
+    await handleConfirm();
136
+  },
137
+  onClosed() {
138
+    formApi.resetForm();
139
+    attachments.value = [];
140
+    uploadUrlRef.value = '';
141
+  },
142
+});
143
+</script>
144
+
145
+<template>
146
+  <Drawer :title="isUpdateRef ? '编辑章节' : '新增章节'">
147
+    <Form>
148
+      <!-- 自定义Tinymce编辑器插槽 -->
149
+      <template #content="scope">
150
+        <TinymceEditor v-model="scope.modelValue" :height="400" />
151
+      </template>
152
+
153
+      <!-- 自定义附件上传插槽 -->
154
+      <template #attachments="scope">
155
+        <ElUpload
156
+          v-model:file-list="attachments"
157
+          action="#"
158
+          accept=".jpg,.jpeg,.png,.gif,.pdf,.doc,.docx,.xls,.xlsx,.ppt,.pptx"
159
+          list-type="text"
160
+          show-file-list
161
+          :auto-upload="true"
162
+          :drag="false"
163
+          :limit="5"
164
+          :multiple="true"
165
+          :http-request="handleAttachmentUpload"
166
+          :on-remove="handleAttachmentRemove"
167
+          :on-preview="handleAttachmentPreview"
168
+          class="mb-4"
169
+        >
170
+          <div class="flex items-center justify-center">
171
+            <ElIcon class="el-upload__icon">
172
+              <Plus size="18" />
173
+            </ElIcon>
174
+            <div class="el-upload__text">
175
+              <div>上传附件</div>
176
+              <div class="text-xs text-gray-500">最多上传5个附件</div>
177
+            </div>
178
+          </div>
179
+        </ElUpload>
180
+      </template>
181
+    </Form>
182
+  </Drawer>
183
+</template>
184
+
185
+<style scoped lang="scss">
186
+/* 自定义样式 */
187
+</style>
188
+

+ 21 - 370
apps/web-ele/src/views/knowledge/edit/index.vue

@@ -64,14 +64,6 @@ const selectedChapter = ref({
64 64
   content: '这是知识库的主页内容,您可以在这里查看知识库的概述信息。',
65 65
   updatedTime: '2025-12-22 14:30:00',
66 66
 });
67
-
68
-
69
-
70
-// 折叠菜单
71
-const toggleCollapse = () => {
72
-  isCollapse.value = !isCollapse.value;
73
-};
74
-
75 67
 // 保存草稿
76 68
 const saveDraft = () => {
77 69
   ElMessage.success('草稿保存成功');
@@ -87,22 +79,25 @@ const attachments = ref<any[]>([]);
87 79
 const uploadUrlRef = ref<string>('');
88 80
 
89 81
 // 处理附件上传
90
-function handleAttachmentUpload(options: any) {
91
-  // 模拟上传成功处理
92
-  const fileData = {
93
-    uid: options.file.uid,
94
-    name: options.file.name,
95
-    url: URL.createObjectURL(options.file),
96
-    status: 'success',
97
-    raw: options.file,
98
-  };
99
-
100
-  // 多个文件上传时,url以逗号隔开
101
-  uploadUrlRef.value = uploadUrlRef.value
102
-    ? `${uploadUrlRef.value},${fileData.url}`
103
-    : fileData.url;
104
-
105
-  options.onSuccess(fileData);
82
+function handleAttachmentUpload(options: any): Promise<unknown> {
83
+  return new Promise((resolve) => {
84
+    // 模拟上传成功处理
85
+    const fileData = {
86
+      uid: options.file.uid,
87
+      name: options.file.name,
88
+      url: URL.createObjectURL(options.file),
89
+      status: 'success',
90
+      raw: options.file,
91
+    };
92
+
93
+    // 多个文件上传时,url以逗号隔开
94
+    uploadUrlRef.value = uploadUrlRef.value
95
+      ? `${uploadUrlRef.value},${fileData.url}`
96
+      : fileData.url;
97
+
98
+    options.onSuccess(fileData);
99
+    resolve(fileData);
100
+  });
106 101
 }
107 102
 
108 103
 // 移除附件
@@ -124,7 +119,7 @@ function handleAttachmentPreview(file: any) {
124 119
 
125 120
 
126 121
 // 点击章节
127
-const handleChapterClick = (node) => {
122
+const handleChapterClick = (node: any) => {
128 123
   selectedChapter.value = {
129 124
     id: node.id,
130 125
     label: node.label,
@@ -971,349 +966,5 @@ onMounted(() => {
971 966
   background-color: #fff;
972 967
   border-color: #dcdfe6;
973 968
 }
974
-
975
-/* 编辑历史弹框样式 */
976
-.edit-history-dialog {
977
-  display: flex;
978
-  gap: 20px;
979
-  width: 100%;
980
-  height: calc(100vh - 300px);
981
-  padding: 10px;
982
-}
983
-
984
-/* 左侧时间轴 */
985
-.history-timeline {
986
-  width: 250px;
987
-  height: 100%;
988
-  padding: 10px;
989
-  overflow-y: auto;
990
-  background-color: #fff;
991
-  border-radius: 8px;
992
-}
993
-
994
-.history-day {
995
-  margin-bottom: 20px;
996
-}
997
-
998
-.day-title {
999
-  margin-bottom: 10px;
1000
-  font-size: 16px;
1001
-  font-weight: 500;
1002
-  color: #303133;
1003
-}
1004
-
1005
-.history-record {
1006
-  display: flex;
1007
-  gap: 10px;
1008
-  padding: 10px;
1009
-  cursor: pointer;
1010
-  background-color: #fff;
1011
-  border-radius: 6px;
1012
-  transition: all 0.3s ease;
1013
-}
1014
-
1015
-.record-time {
1016
-  flex-shrink: 0;
1017
-  width: 60px;
1018
-  padding-top: 2px;
1019
-  font-size: 14px;
1020
-  font-weight: 500;
1021
-  color: #303133;
1022
-  text-align: left;
1023
-}
1024
-
1025
-.record-info {
1026
-  flex: 1;
1027
-  min-width: 0;
1028
-}
1029
-
1030
-.record-user {
1031
-  margin-bottom: 2px;
1032
-  font-size: 13px;
1033
-  color: #606266;
1034
-}
1035
-
1036
-.record-action {
1037
-  font-size: 13px;
1038
-  color: #909399;
1039
-}
1040
-
1041
-.history-record:hover {
1042
-  background-color: #E6E8EB;
1043
-}
1044
-
1045
-.history-record.active {
1046
-  // border-left: 3px solid #1890ff;
1047
-  color: #1890ff;
1048
-  background-color: #E8F3FF;
1049
-}
1050
-
1051
-.record-time {
1052
-  margin-bottom: 2px;
1053
-  font-size: 14px;
1054
-  font-weight: 500;
1055
-  color: #303133;
1056
-}
1057
-
1058
-.record-user {
1059
-  margin-bottom: 2px;
1060
-  font-size: 13px;
1061
-  color: #606266;
1062
-}
1063
-
1064
-.record-action {
1065
-  font-size: 13px;
1066
-  color: #909399;
1067
-}
1068
-
1069
-/* 右侧内容 */
1070
-.history-content {
1071
-  flex: 1;
1072
-  height: 100%;
1073
-  padding: 20px;
1074
-  overflow-y: auto;
1075
-  background-color: #fff;
1076
-  border-radius: 8px;
1077
-}
1078
-
1079
-.content-title {
1080
-  margin-bottom: 20px;
1081
-  font-size: 24px;
1082
-  font-weight: 500;
1083
-  color: #303133;
1084
-}
1085
-
1086
-.content-section {
1087
-  margin-bottom: 30px;
1088
-}
1089
-
1090
-.section-title {
1091
-  margin-bottom: 10px;
1092
-  font-size: 18px;
1093
-  font-weight: 500;
1094
-  color: #303133;
1095
-}
1096
-
1097
-.section-content {
1098
-  font-size: 14px;
1099
-  line-height: 1.8;
1100
-  color: #606266;
1101
-  white-space: pre-wrap;
1102
-}
1103
-
1104
-.content-attachments {
1105
-  padding-top: 20px;
1106
-  margin-top: 30px;
1107
-  border-top: 1px solid #e8e8e8;
1108
-}
1109
-
1110
-.attachments-title {
1111
-  margin-bottom: 10px;
1112
-  font-size: 16px;
1113
-  font-weight: 500;
1114
-  color: #303133;
1115
-}
1116
-
1117
-/* 滚动条样式 */
1118
-.history-timeline::-webkit-scrollbar,
1119
-.history-content::-webkit-scrollbar {
1120
-  width: 6px;
1121
-  height: 6px;
1122
-}
1123
-
1124
-.history-timeline::-webkit-scrollbar-track,
1125
-.history-content::-webkit-scrollbar-track {
1126
-  background: #f1f1f1;
1127
-  border-radius: 3px;
1128
-}
1129
-
1130
-.history-timeline::-webkit-scrollbar-thumb,
1131
-.history-content::-webkit-scrollbar-thumb {
1132
-  background: #c1c1c1;
1133
-  border-radius: 3px;
1134
-}
1135
-
1136
-.history-timeline::-webkit-scrollbar-thumb:hover,
1137
-.history-content::-webkit-scrollbar-thumb:hover {
1138
-  background: #a8a8a8;
1139
-}
1140
-
1141
-/* 标签页样式 */
1142
-.right-tabs {
1143
-  flex: 1;
1144
-  max-height: 400px;
1145
-  padding-right: 5px;
1146
-  overflow-y: auto;
1147
-}
1148
-
1149
-.right-tabs::-webkit-scrollbar {
1150
-  width: 6px;
1151
-}
1152
-
1153
-.right-tabs::-webkit-scrollbar-track {
1154
-  background: #f1f1f1;
1155
-  border-radius: 3px;
1156
-}
1157
-
1158
-.right-tabs::-webkit-scrollbar-thumb {
1159
-  background: #c1c1c1;
1160
-  border-radius: 3px;
1161
-}
1162
-
1163
-.right-tabs::-webkit-scrollbar-thumb:hover {
1164
-  background: #a8a8a8;
1165
-}
1166
-
1167
-/* 查看记录和操作记录 */
1168
-.view-records,
1169
-.operation-records {
1170
-  padding: 0;
1171
-  background-color: transparent;
1172
-  border-radius: 0;
1173
-  box-shadow: none;
1174
-}
1175
-
1176
-.record-list {
1177
-  display: flex;
1178
-  flex-direction: column;
1179
-  gap: 20px;
1180
-
1181
-  /* max-height: 200px; */
1182
-
1183
-  /* overflow-y: auto; */
1184
-}
1185
-
1186
-.record-item {
1187
-  display: flex;
1188
-  align-items: center;
1189
-  justify-content: space-between;
1190
-  width: 100%;
1191
-  font-size: 14px;
1192
-}
1193
-
1194
-.record-left {
1195
-  display: flex;
1196
-  flex: 1;
1197
-  gap: 10px;
1198
-  align-items: center;
1199
-}
1200
-
1201
-.record-info {
1202
-  display: flex;
1203
-  flex-direction: column;
1204
-  gap: 4px;
1205
-}
1206
-
1207
-.record-avatar {
1208
-  width: 32px;
1209
-  height: 32px;
1210
-  color: #fff;
1211
-  background-color: #1890ff;
1212
-}
1213
-
1214
-.record-user {
1215
-  font-size: 14px;
1216
-  font-weight: 500;
1217
-  color: #000;
1218
-}
1219
-
1220
-.record-time {
1221
-  font-size: 14px;
1222
-  color: #000;
1223
-  text-align: right;
1224
-}
1225
-
1226
-.record-action {
1227
-  margin-top: 2px;
1228
-  font-size: 13px;
1229
-  color: #666;
1230
-}
1231
-
1232
-/* 提醒弹框样式 */
1233
-.notification-content {
1234
-  .form-item {
1235
-    margin-bottom: 20px;
1236
-  }
1237
-  
1238
-  .form-label {
1239
-    margin-bottom: 8px;
1240
-    font-size: 14px;
1241
-    font-weight: 500;
1242
-    color: #000;
1243
-  }
1244
-  
1245
-  .recipient-section {
1246
-    display: flex;
1247
-    gap: 10px;
1248
-    align-items: center;
1249
-  }
1250
-}
1251
-
1252
-/* 提醒弹框样式 */
1253
-.notification-dialog {
1254
-  .dialog-row {
1255
-    display: flex;
1256
-    gap: 12px;
1257
-    align-items: flex-start;
1258
-    margin-bottom: 16px;
1259
-  }
1260
-
1261
-  .row-label {
1262
-    flex-shrink: 0;
1263
-    width: 70px;
1264
-    padding-top: 8px;
1265
-    font-size: 14px;
1266
-    font-weight: 500;
1267
-    color: #303133;
1268
-    text-align: right;
1269
-  }
1270
-
1271
-  .row-content {
1272
-    flex: 1;
1273
-    width: 0;
1274
-  }
1275
-
1276
-  .select-all-btn {
1277
-    margin-top: 8px;
1278
-    text-align: right;
1279
-  }
1280
-
1281
-  .dialog-footer {
1282
-    display: flex;
1283
-    gap: 12px;
1284
-    justify-content: flex-end;
1285
-  }
1286
-}
1287
-
1288
-/* 回复相关样式 */
1289
-.reply-input-wrapper {
1290
-  padding: 15px;
1291
-  margin-top: 12px;
1292
-  background-color: #fafafa;
1293
-  border: 1px solid #e8e8e8;
1294
-  border-radius: 4px;
1295
-}
1296
-
1297
-.reply-input {
1298
-  margin-bottom: 10px;
1299
-  border-radius: 4px;
1300
-}
1301
-
1302
-.reply-actions {
1303
-  display: flex;
1304
-  gap: 10px;
1305
-  justify-content: flex-start;
1306
-}
1307
-
1308
-.submit-btn {
1309
-  color: #fff;
1310
-  background-color: #1890ff;
1311
-  border-color: #1890ff;
1312
-}
1313
-
1314
-.cancel-btn {
1315
-  color: #606266;
1316
-  background-color: #fff;
1317
-  border-color: #dcdfe6;
1318
-}
1319 969
 </style>
970
+

+ 17 - 11
apps/web-ele/src/views/knowledge/type/create.vue

@@ -3,17 +3,22 @@ import { ref, watch } from 'vue';
3 3
 import { ElForm, ElFormItem, ElInput, ElSelect, ElOption, ElUpload, ElMessage, ElButton, ElIcon } from 'element-plus';
4 4
 import { Upload, Plus } from '@element-plus/icons-vue';
5 5
 
6
+// 定义表单数据类型
7
+interface FormData {
8
+  name: string;
9
+  description: string;
10
+  icon: string;
11
+  managers: any[];
12
+  visibleApps: any[];
13
+  visiblePositions: any[];
14
+  association: string;
15
+}
16
+
6 17
 // 定义组件的props
7
-const props = defineProps({
8
-  mode: {
9
-    type: String,
10
-    default: 'create', // create 或 edit
11
-  },
12
-  initialData: {
13
-    type: Object,
14
-    default: () => ({}),
15
-  },
16
-});
18
+const props = defineProps<{
19
+  mode: string;
20
+  initialData?: FormData;
21
+}>();
17 22
 
18 23
 // 定义事件
19 24
 const emit = defineEmits(['close', 'save']);
@@ -22,7 +27,7 @@ const emit = defineEmits(['close', 'save']);
22 27
 const formRef = ref();
23 28
 
24 29
 // 表单数据
25
-const form = ref({
30
+const form = ref<FormData>({
26 31
   name: '',
27 32
   description: '',
28 33
   icon: '',
@@ -366,3 +371,4 @@ const closeForm = () => {
366 371
   margin-top: 32px;
367 372
 }
368 373
 </style>
374
+

+ 42 - 6
apps/web-ele/src/views/knowledge/type/index.vue

@@ -6,6 +6,17 @@ import KnowledgeCreate from './create.vue';
6 6
 import { ref } from 'vue';
7 7
 import { useRouter } from 'vue-router';
8 8
 
9
+// 导入 FormData 类型
10
+interface FormData {
11
+  name: string;
12
+  description: string;
13
+  icon: string;
14
+  managers: any[];
15
+  visibleApps: any[];
16
+  visiblePositions: any[];
17
+  association: string;
18
+}
19
+
9 20
 // 路由实例
10 21
 const router = useRouter();
11 22
 
@@ -31,7 +42,15 @@ const categories = [
31 42
 // 抽屉控制
32 43
 const drawerVisible = ref(false);
33 44
 const drawerMode = ref('create');
34
-const selectedCategory = ref({});
45
+const selectedCategory = ref<FormData>({
46
+  name: '',
47
+  description: '',
48
+  icon: '',
49
+  managers: [],
50
+  visibleApps: [],
51
+  visiblePositions: [],
52
+  association: '',
53
+});
35 54
 
36 55
 // 跳转到详情页
37 56
 const navigateToDetail = (id: number) => {
@@ -41,14 +60,30 @@ const navigateToDetail = (id: number) => {
41 60
 // 打开创建抽屉
42 61
 const openCreateDrawer = () => {
43 62
   drawerMode.value = 'create';
44
-  selectedCategory.value = {};
63
+  selectedCategory.value = {
64
+    name: '',
65
+    description: '',
66
+    icon: '',
67
+    managers: [],
68
+    visibleApps: [],
69
+    visiblePositions: [],
70
+    association: '',
71
+  };
45 72
   drawerVisible.value = true;
46 73
 };
47 74
 
48 75
 // 打开编辑抽屉
49
-const openEditDrawer = (category) => {
76
+const openEditDrawer = (category: any) => {
50 77
   drawerMode.value = 'edit';
51
-  selectedCategory.value = category;
78
+  selectedCategory.value = {
79
+    name: category.name || '',
80
+    description: category.description || '',
81
+    icon: category.icon || '',
82
+    managers: [],
83
+    visibleApps: [],
84
+    visiblePositions: [],
85
+    association: '',
86
+  };
52 87
   drawerVisible.value = true;
53 88
 };
54 89
 
@@ -58,7 +93,7 @@ const closeDrawer = () => {
58 93
 };
59 94
 
60 95
 // 保存知识类别
61
-const saveCategory = (data) => {
96
+const saveCategory = (data: any) => {
62 97
   if (drawerMode.value === 'create') {
63 98
     // 这里可以添加创建逻辑
64 99
     console.log('创建知识库:', data);
@@ -116,7 +151,7 @@ const saveCategory = (data) => {
116 151
     <ElDrawer
117 152
       v-model="drawerVisible"
118 153
       :title="drawerMode === 'create' ? '创建知识库' : '编辑知识库'"
119
-      size="50%"
154
+      size="30%"
120 155
       direction="rtl"
121 156
       @close="closeDrawer"
122 157
     >
@@ -240,3 +275,4 @@ border-radius: 6px;
240 275
   justify-content: center;
241 276
 }
242 277
 </style>
278
+