Просмотр исходного кода

考试相关,优化日程页面

chenxiaochao 1 месяц назад
Родитель
Сommit
d828f67dd4

+ 17 - 0
apps/web-ele/src/api/knowledge/category.ts

@@ -0,0 +1,17 @@
1
+import { requestClient } from '#/api/request';
2
+enum Api {
3
+  baseknowledgeCategory = '/knowledgeCategory/category',
4
+  queryknowledgeCategory = '/knowledgeCategory/category/list',
5
+}
6
+//新增知识库分类
7
+export function addKnowledgeCategory(data: any) {
8
+  return requestClient.post(Api.baseknowledgeCategory, data, {
9
+    successMessageMode: 'message',
10
+  });
11
+}
12
+//查询知识库分类列表
13
+export function queryKnowledgeCategory() {
14
+  return requestClient.get(Api.queryknowledgeCategory, {
15
+    isTransformResponse: false,
16
+  });
17
+}

+ 38 - 0
apps/web-ele/src/router/routes/core.ts

@@ -37,6 +37,44 @@ const coreRoutes: RouteRecordRaw[] = [
37 37
     redirect: DEFAULT_HOME_PATH,
38 38
     children: [],
39 39
   },
40
+  //考试相关通过链接进入
41
+  {
42
+    name: 'Examin',
43
+    path: '/examin',
44
+    component: () =>
45
+      import('#/views/examManage/myExamPaper/cpn/examInfo/index.vue'),
46
+    meta: {
47
+      title: '考试信息',
48
+    },
49
+  },
50
+  {
51
+    name: 'Startexamin',
52
+    path: '/startexamin',
53
+    component: () =>
54
+      import('#/views/examManage/myExamPaper/cpn/startexamin/index.vue'),
55
+    meta: {
56
+      title: '开始考试',
57
+    },
58
+  },
59
+  {
60
+    name: 'Examcompleted',
61
+    path: '/examcompleted',
62
+    component: () =>
63
+      import('#/views/examManage/myExamPaper/cpn/endexamin/examcompleted.vue'),
64
+    meta: {
65
+      title: '考试完成',
66
+    },
67
+  },
68
+  {
69
+    name: 'Viewexamin',
70
+    path: '/viewexamin',
71
+    component: () =>
72
+      import('#/views/examManage/myExamPaper/cpn/endexamin/viewexamin.vue'),
73
+    meta: {
74
+      title: '查看考试结果',
75
+    },
76
+  },
77
+  //结束
40 78
   {
41 79
     component: AuthPageLayout,
42 80
     meta: {

+ 33 - 0
apps/web-ele/src/router/routes/local.ts

@@ -201,6 +201,39 @@ const localRoutes: RouteRecordStringComponent[] = [
201 201
     path: '/examManage/myExamPaper/examInfo/:id',
202 202
   },
203 203
   // 新增路由结束
204
+  {
205
+    component: '/examManage/myExamPaper/cpn/startexamin/index',
206
+    meta: {
207
+      activePath: '/examManage/myExamPaper',
208
+      icon: 'carbon:information',
209
+      title: '开始考试',
210
+      hideInMenu: true,
211
+    },
212
+    name: 'Startexamin',
213
+    path: '/examManage/myExamPaper/cpn/startexamin/index',
214
+  },
215
+  {
216
+    component: '/examManage/myExamPaper/cpn/endexamin/examcompleted',
217
+    meta: {
218
+      activePath: '/examManage/myExamPaper',
219
+      icon: 'carbon:information',
220
+      title: '考试完成',
221
+      hideInMenu: true,
222
+    },
223
+    name: 'ExamCompleted',
224
+    path: '/examManage/myExamPaper/cpn/endexamin/examcompleted',
225
+  },
226
+  {
227
+    component: '/examManage/myExamPaper/cpn/endexamin/viewexamin',
228
+    meta: {
229
+      activePath: '/examManage/myExamPaper',
230
+      icon: 'carbon:information',
231
+      title: '查看考试结果',
232
+      hideInMenu: true,
233
+    },
234
+    name: 'Viewexamin',
235
+    path: '/examManage/myExamPaper/cpn/endexamin/viewexamin',
236
+  },
204 237
 ];
205 238
 
206 239
 /**

+ 59 - 0
apps/web-ele/src/views/examManage/myExamPaper/cpn/endexamin/examcompleted.vue

@@ -0,0 +1,59 @@
1
+<script lang="ts" setup>
2
+import { Page } from '@vben/common-ui';
3
+import { ref } from 'vue';
4
+import { useRouter, useRoute } from 'vue-router';
5
+import { CircleCheckFilled } from '@element-plus/icons-vue';
6
+const router = useRouter();
7
+const route = useRoute();
8
+const handleClick = () => {
9
+  if(route.path==='/examcompleted'){
10
+  router.replace({ path: '/viewexamin' });
11
+
12
+  }else{
13
+  router.replace({ path: '/examManage/myExamPaper/cpn/endexamin/viewexamin' });
14
+
15
+  }
16
+};
17
+</script>
18
+<template>
19
+  <Page title="考试完成">
20
+    <div class="exam-completed-container">
21
+      <el-icon class="exam-completed-icon"><CircleCheckFilled /></el-icon>
22
+      <div class="exam-completed-title">考试完成</div>
23
+      <div class="exam-completed-desc">
24
+        请稍后在【我的考试-已考试】中查看成绩。
25
+      </div>
26
+      <el-button class="exam-completed-btn" @click="handleClick"
27
+        >查看结果</el-button
28
+      >
29
+    </div>
30
+  </Page>
31
+</template>
32
+<style lang="scss" scoped>
33
+.exam-completed-container {
34
+  margin-top: 120px;
35
+  display: flex;
36
+  flex-direction: column;
37
+  align-items: center;
38
+  justify-content: center;
39
+  gap: 24px;
40
+  .exam-completed-icon {
41
+    font-size: 88px;
42
+    color: #52c41a;
43
+  }
44
+  .exam-completed-title {
45
+    font-size: 18px;
46
+    font-weight: 500;
47
+    color: #31373d;
48
+  }
49
+  .exam-completed-desc {
50
+    font-size: 14px;
51
+    font-weight: 400;
52
+    color: #31373d;
53
+  }
54
+  .exam-completed-btn {
55
+    width: 160px;
56
+    height: 40px;
57
+  }
58
+}
59
+</style>

Разница между файлами не показана из-за своего большого размера
+ 245 - 0
apps/web-ele/src/views/examManage/myExamPaper/cpn/endexamin/viewexamin.vue


+ 15 - 12
apps/web-ele/src/views/examManage/myExamPaper/cpn/examInfo/index.vue

@@ -1,17 +1,20 @@
1 1
 <script lang="ts" setup>
2 2
 import { Page } from '@vben/common-ui';
3
+import { ref } from 'vue';
4
+import havetoken from './istokenexamin/havetoken.vue';
5
+import notoken from './istokenexamin/notoken.vue';
6
+const userinfo = localStorage.getItem(
7
+  'Smart-Steward-Admin-5.5.4-dev-core-access',
8
+) as any;
9
+const token = ref('');
10
+if (userinfo) {
11
+  token.value = JSON.parse(userinfo).accessToken || '';
12
+}
3 13
 </script>
4 14
 <template>
5
-<Page>
6
-<div class="wrap">
7
-        开发中
8
-</div>
9
-</Page>
15
+  <view>
16
+    <havetoken v-if="token" />
17
+    <notoken v-else />
18
+  </view>
10 19
 </template>
11
-<style lang="scss" scoped>
12
-.wrap {
13
-padding: 16px;
14
-background-color: #fff;
15
-border-radius: 6px;
16
-}
17
-</style>
20
+<style lang="scss" scoped></style>

+ 110 - 0
apps/web-ele/src/views/examManage/myExamPaper/cpn/examInfo/istokenexamin/havetoken.vue

@@ -0,0 +1,110 @@
1
+<script lang="ts" setup>
2
+import { Page } from '@vben/common-ui';
3
+import { useRouter } from 'vue-router';
4
+import { useTabs } from '@vben/hooks';
5
+const { closeCurrentTab } = useTabs();
6
+const router = useRouter();
7
+const examinformation = {
8
+  ExamName: '考试名称 1',
9
+  TotalExamScore: '100',
10
+  Passingscore: '60',
11
+  Examduration: '30分钟',
12
+  ExamInstructions: '这是考试说明',
13
+};
14
+const handlclick = async () => {
15
+  await closeCurrentTab();
16
+  router.push({
17
+    path: '/examManage/myExamPaper/cpn/startexamin/index',
18
+  });
19
+};
20
+</script>
21
+<template>
22
+  <Page title="考试信息">
23
+    <div class="examinformation">
24
+      <div class="examinformation_item">
25
+        <div class="examinformation_item_left">考试名称</div>
26
+        <div class="examinformation_item_right">
27
+          {{ examinformation.ExamName }}
28
+        </div>
29
+      </div>
30
+      <div class="examinformation_item">
31
+        <div class="examinformation_item_left">考试总分</div>
32
+        <div class="examinformation_item_right">
33
+          {{ examinformation.TotalExamScore }}
34
+        </div>
35
+      </div>
36
+      <div class="examinformation_item">
37
+        <div class="examinformation_item_left">及格分数</div>
38
+        <div class="examinformation_item_right">
39
+          {{ examinformation.Passingscore }}
40
+        </div>
41
+      </div>
42
+      <div class="examinformation_item">
43
+        <div class="examinformation_item_left">考试时长</div>
44
+        <div class="examinformation_item_right">
45
+          {{ examinformation.Examduration }}
46
+        </div>
47
+      </div>
48
+      <div class="examinformation_item">
49
+        <div class="examinformation_item_left">考试说明</div>
50
+        <div class="examinformation_item_right">
51
+          {{ examinformation.ExamInstructions }}
52
+        </div>
53
+      </div>
54
+    </div>
55
+    <div class="btn">
56
+      <el-button style="flex: 1">返 回</el-button>
57
+      <el-button style="flex: 1" type="primary" @click="handlclick"
58
+        >开 始 考 试</el-button
59
+      >
60
+    </div>
61
+  </Page>
62
+</template>
63
+<style lang="scss" scoped>
64
+.examinformation {
65
+  width: 100%;
66
+  height: 180px;
67
+  border: 1px solid #d4d6d9;
68
+  display: flex;
69
+  flex-direction: column;
70
+  justify-content: space-between;
71
+  .examinformation_item {
72
+    flex: 1;
73
+    border-bottom: 1px solid #d4d6d9;
74
+    display: flex;
75
+    justify-content: space-between;
76
+    color: #31373d;
77
+    font-size: 14px;
78
+    .examinformation_item_left {
79
+      background-color: #f2f3f5;
80
+      width: 240px;
81
+      font-weight: 500;
82
+      display: flex;
83
+      align-items: center;
84
+      justify-content: end;
85
+      box-sizing: border-box;
86
+      padding-right: 16px;
87
+    }
88
+    .examinformation_item_right {
89
+      border-left: 1px solid #d4d6d9;
90
+      flex: 1;
91
+      font-weight: 400;
92
+      display: flex;
93
+      align-items: center;
94
+      box-sizing: border-box;
95
+      padding-left: 16px;
96
+    }
97
+    &:last-child {
98
+      border-bottom: none;
99
+    }
100
+  }
101
+}
102
+.btn {
103
+  width: 352px;
104
+  height: 40px;
105
+  display: flex;
106
+  justify-content: space-between;
107
+  gap: 32px;
108
+  margin: 24px auto;
109
+}
110
+</style>

+ 172 - 0
apps/web-ele/src/views/examManage/myExamPaper/cpn/examInfo/istokenexamin/notoken.vue

@@ -0,0 +1,172 @@
1
+<script lang="ts" setup>
2
+import { Page } from '@vben/common-ui';
3
+import { reactive, ref } from 'vue';
4
+import { useRouter, useRoute } from 'vue-router';
5
+import type { FormInstance, FormRules } from 'element-plus';
6
+const router = useRouter();
7
+const route = useRoute();
8
+const ruleFormRef = ref<FormInstance>();
9
+const examinformation = {
10
+  ExamName: '考试名称 1',
11
+  TotalExamScore: '100',
12
+  Passingscore: '60',
13
+  Examduration: '30分钟',
14
+  ExamInstructions: '这是考试说明',
15
+};
16
+const ruleForm = reactive({
17
+  username: '',
18
+  mobilenumber: '',
19
+});
20
+
21
+const rules = reactive<FormRules<typeof ruleForm>>({
22
+  username: [
23
+    {
24
+      required: true,
25
+      message: '姓名不能为空!',
26
+      trigger: 'change',
27
+    },
28
+  ],
29
+  mobilenumber: [
30
+    {
31
+      required: true,
32
+      message: '手机号不能为空!',
33
+      trigger: 'change',
34
+    },
35
+  ],
36
+});
37
+
38
+const submitForm = (formEl: FormInstance | undefined) => {
39
+  if (!formEl) return;
40
+  formEl.validate((valid) => {
41
+    if (valid) {
42
+      router.replace({
43
+        path: '/startexamin',
44
+      });
45
+    } else {
46
+      console.log('error submit!');
47
+    }
48
+  });
49
+};
50
+</script>
51
+<template>
52
+  <Page>
53
+    <div style="display: flex; flex-direction: column; align-items: center">
54
+      <div class="title">欢迎进入联合汇能考试中心</div>
55
+      <div class="examinformation">
56
+        <div class="examinformation_item">
57
+          <div class="examinformation_item_left">考试名称</div>
58
+          <div class="examinformation_item_right">
59
+            {{ examinformation.ExamName }}
60
+          </div>
61
+        </div>
62
+        <div class="examinformation_item">
63
+          <div class="examinformation_item_left">考试总分</div>
64
+          <div class="examinformation_item_right">
65
+            {{ examinformation.TotalExamScore }}
66
+          </div>
67
+        </div>
68
+        <div class="examinformation_item">
69
+          <div class="examinformation_item_left">及格分数</div>
70
+          <div class="examinformation_item_right">
71
+            {{ examinformation.Passingscore }}
72
+          </div>
73
+        </div>
74
+        <div class="examinformation_item">
75
+          <div class="examinformation_item_left">考试时长</div>
76
+          <div class="examinformation_item_right">
77
+            {{ examinformation.Examduration }}
78
+          </div>
79
+        </div>
80
+        <div class="examinformation_item">
81
+          <div class="examinformation_item_left">考试说明</div>
82
+          <div class="examinformation_item_right">
83
+            {{ examinformation.ExamInstructions }}
84
+          </div>
85
+        </div>
86
+      </div>
87
+      <div class="examinformation_content">
88
+        <el-form
89
+          ref="ruleFormRef"
90
+          style="width: 400px"
91
+          :model="ruleForm"
92
+          status-icon
93
+          :rules="rules"
94
+          label-width="auto"
95
+          class="demo-ruleForm"
96
+        >
97
+          <el-form-item label="姓名" prop="username">
98
+            <el-input v-model="ruleForm.username" autocomplete="off" />
99
+          </el-form-item>
100
+          <el-form-item label="手机号" prop="mobilenumber">
101
+            <el-input v-model="ruleForm.mobilenumber" autocomplete="off" />
102
+          </el-form-item>
103
+          <el-form-item>
104
+            <el-button
105
+              style="margin: 0 auto; width: 160px; height: 40px"
106
+              type="primary"
107
+              @click="submitForm(ruleFormRef)"
108
+            >
109
+              开 始 考 试
110
+            </el-button>
111
+          </el-form-item>
112
+        </el-form>
113
+      </div>
114
+    </div>
115
+  </Page>
116
+</template>
117
+<style lang="scss" scoped>
118
+.title {
119
+  font-size: 22px;
120
+  font-weight: 600;
121
+  margin-bottom: 48px;
122
+}
123
+.examinformation {
124
+  width: 100%;
125
+  height: 180px;
126
+  border: 1px solid #d4d6d9;
127
+  display: flex;
128
+  flex-direction: column;
129
+  justify-content: space-between;
130
+  .examinformation_item {
131
+    flex: 1;
132
+    border-bottom: 1px solid #d4d6d9;
133
+    display: flex;
134
+    justify-content: space-between;
135
+    color: #31373d;
136
+    font-size: 14px;
137
+    .examinformation_item_left {
138
+      background-color: #f2f3f5;
139
+      width: 240px;
140
+      font-weight: 500;
141
+      display: flex;
142
+      align-items: center;
143
+      justify-content: end;
144
+      box-sizing: border-box;
145
+      padding-right: 16px;
146
+    }
147
+    .examinformation_item_right {
148
+      border-left: 1px solid #d4d6d9;
149
+      flex: 1;
150
+      font-weight: 400;
151
+      display: flex;
152
+      align-items: center;
153
+      box-sizing: border-box;
154
+      padding-left: 16px;
155
+    }
156
+    &:last-child {
157
+      border-bottom: none;
158
+    }
159
+  }
160
+}
161
+.examinformation_content {
162
+  margin-top: 129px;
163
+  //   border: 1px solid red;
164
+  // display: flex;
165
+  //   width: 352px;
166
+  //   height: 40px;
167
+  //   display: flex;
168
+  //   justify-content: space-between;
169
+  //   gap: 32px;
170
+  //   margin: 24px auto;
171
+}
172
+</style>

Разница между файлами не показана из-за своего большого размера
+ 1023 - 0
apps/web-ele/src/views/examManage/myExamPaper/cpn/startexamin/index.vue


Разница между файлами не показана из-за своего большого размера
+ 259 - 11
apps/web-ele/src/views/examManage/questScoring/cpn/examCorrect/index.vue


+ 9 - 3
apps/web-ele/src/views/knowledge/type/create.vue

@@ -93,8 +93,14 @@ const selectDefaultIcon = (iconValue: string) => {
93 93
 // 表单提交
94 94
 const submitForm = () => {
95 95
   // 这里可以添加表单提交逻辑
96
-  emit('save', form.value);
97
-  ElMessage.success(props.mode === 'create' ? '创建成功' : '编辑成功');
96
+  formRef.value.validate((valid) => {
97
+    if (valid) {
98
+      emit('save', form.value);
99
+      ElMessage.success(props.mode === 'create' ? '创建成功' : '编辑成功');
100
+    } else {
101
+      ElMessage.error('请填写正确的信息');
102
+    }
103
+  });
98 104
 };
99 105
 
100 106
 // 关闭表单
@@ -159,7 +165,7 @@ const closeForm = () => {
159 165
             @click="selectDefaultIcon(icon.value)"
160 166
           >
161 167
             <!-- 这里可以根据icon.value显示不同的图标 -->
162
-            <div class="icon-placeholder" :class="icon.value"></div>
168
+            <ElIcon class="icon-placeholder" :class="icon.value"></ElIcon>
163 169
           </div>
164 170
         </div>
165 171
       </div>

+ 107 - 84
apps/web-ele/src/views/knowledge/type/index.vue

@@ -3,9 +3,12 @@ import { Page } from '@vben/common-ui';
3 3
 import { ElButton, ElCard, ElIcon, ElPagination } from 'element-plus';
4 4
 import { Edit, Delete } from '@element-plus/icons-vue';
5 5
 import KnowledgeCreate from './create.vue';
6
-import { ref } from 'vue';
6
+import { ref, onMounted, reactive } from 'vue';
7 7
 import { useRouter } from 'vue-router';
8
-
8
+import {
9
+  addKnowledgeCategory,
10
+  queryKnowledgeCategory,
11
+} from '#/api/knowledge/category';
9 12
 // 导入 FormData 类型
10 13
 interface FormData {
11 14
   name: string;
@@ -21,24 +24,24 @@ interface FormData {
21 24
 const router = useRouter();
22 25
 
23 26
 // 示例数据
24
-const categories = [
25
-  { id: 1, name: '悬浮态', description: '位使用人员提供了知识管理场景示例', creator: '张三', createTime: '2025-01-01', icon: 'Menu', color: '#3370FF' },
26
-  { id: 2, name: '常规态', description: '位使用人员提供了知识管理场景示例', creator: '张三', createTime: '2025-01-01', icon: 'Menu', color: '#3370FF' },
27
-  { id: 3, name: '我的文件', description: '位使用人员提供了知识管理场景示例', creator: '张三', createTime: '2025-01-01', icon: 'Menu', color: '#3370FF' },
28
-  { id: 4, name: '我的文件', description: '位使用人员提供了知识管理场景示例', creator: '张三', createTime: '2025-01-01', icon: 'Document', color: '#9254DE' },
29
-  { id: 5, name: '我的文件', description: '位使用人员提供了知识管理场景示例', creator: '张三', createTime: '2025-01-01', icon: 'Menu', color: '#FF7D00' },
30
-  { id: 6, name: '我的文件', description: '位使用人员提供了知识管理场景示例', creator: '张三', createTime: '2025-01-01', icon: 'Menu', color: '#00B42A' },
31
-  { id: 7, name: '我的文件', description: '位使用人员提供了知识管理场景示例', creator: '张三', createTime: '2025-01-01', icon: 'Menu', color: '#FF7D00' },
32
-  { id: 8, name: '我的文件', description: '位使用人员提供了知识管理场景示例', creator: '张三', createTime: '2025-01-01', icon: 'Menu', color: '#9254DE' },
33
-  { id: 9, name: '我的文件', description: '位使用人员提供了知识管理场景示例', creator: '张三', createTime: '2025-01-01', icon: 'Menu', color: '#3370FF' },
34
-  { id: 10, name: '我的文件', description: '位使用人员提供了知识管理场景示例', creator: '张三', createTime: '2025-01-01', icon: 'Menu', color: '#3370FF' },
35
-  { id: 11, name: '我的文件', description: '位使用人员提供了知识管理场景示例', creator: '张三', createTime: '2025-01-01', icon: 'Menu', color: '#3370FF' },
36
-  { id: 12, name: '我的文件', description: '位使用人员提供了知识管理场景示例', creator: '张三', createTime: '2025-01-01', icon: 'Menu', color: '#3370FF' },
37
-  { id: 13, name: '我的文件', description: '位使用人员提供了知识管理场景示例', creator: '张三', createTime: '2025-01-01', icon: 'Menu', color: '#3370FF' },
38
-  { id: 14, name: '我的文件', description: '位使用人员提供了知识管理场景示例', creator: '张三', createTime: '2025-01-01', icon: 'Menu', color: '#3370FF' },
39
-  { id: 15, name: '我的文件', description: '位使用人员提供了知识管理场景示例', creator: '张三', createTime: '2025-01-01', icon: 'Menu', color: '#3370FF' },
40
-];
41
-
27
+const categories = ref([]) as any;
28
+const total = ref<number>(0);
29
+// const currentPage = ref(1);
30
+const pageSize = ref<number>(15);
31
+const createCategory = async () => {
32
+  try {
33
+    const res = await queryKnowledgeCategory();
34
+    if (res.code === 200) {
35
+      categories.value = res.rows || [];
36
+      total.value = res.total || 0;
37
+    }
38
+  } catch (error) {
39
+    console.log(error);
40
+  }
41
+};
42
+onMounted(() => {
43
+  createCategory();
44
+});
42 45
 // 抽屉控制
43 46
 const drawerVisible = ref(false);
44 47
 const drawerMode = ref('create');
@@ -93,10 +96,12 @@ const closeDrawer = () => {
93 96
 };
94 97
 
95 98
 // 保存知识类别
96
-const saveCategory = (data: any) => {
99
+const saveCategory = async (data: any) => {
97 100
   if (drawerMode.value === 'create') {
98 101
     // 这里可以添加创建逻辑
99
-    console.log('创建知识库:', data);
102
+    // console.log('创建知识库:', data);
103
+    const res = await addKnowledgeCategory(data);
104
+    console.log(res);
100 105
   } else {
101 106
     // 这里可以添加编辑逻辑
102 107
     console.log('编辑知识库:', data);
@@ -104,72 +109,91 @@ const saveCategory = (data: any) => {
104 109
 };
105 110
 </script>
106 111
 <template>
107
-<Page>
108
-<div class="wrap">
109
-    <!-- 页面头部 -->
110
-    <div class="header">
111
-      <ElButton type="primary" @click="openCreateDrawer">+ 添加类别</ElButton>
112
-      <!-- <ElButton type="default">管理</ElButton> -->
113
-    </div>
114
-    <!-- 卡片列表 -->
115
-    <div class="card-list">
116
-      <div v-for="category in categories" :key="category.id" class="card-item">
117
-        <ElCard :bordered="false" class="category-card" @click="navigateToDetail(category.id)">
118
-          <div class="card-content">
119
-            <!-- 左侧图标 -->
120
-            <div class="card-icon" :style="{ backgroundColor: category.color + '20', color: category.color }">
121
-              <ElIcon :icon="category.icon" size="24" />
122
-            </div>
123
-            <!-- 中间内容 -->
124
-            <div class="card-main">
125
-              <h3 class="card-title">{{ category.name }}</h3>
126
-              <p class="card-description">{{ category.description }}</p>
127
-            </div>
128
-            <!-- 右侧信息 -->
129
-            <div class="card-info">
130
-              <div class="creator">{{ category.creator }}</div>
131
-              <div class="create-time">{{ category.createTime }}</div>
132
-              <!-- 操作按钮 -->
133
-              <div class="card-actions">
134
-                <ElButton type="text" :icon="Edit" circle @click.stop="openEditDrawer(category)" />
135
-              <ElButton type="text" :icon="Delete" circle />
112
+  <Page>
113
+    <div class="wrap">
114
+      <!-- 页面头部 -->
115
+      <div class="header">
116
+        <ElButton type="primary" @click="openCreateDrawer">+ 添加类别</ElButton>
117
+        <!-- <ElButton type="default">管理</ElButton> -->
118
+      </div>
119
+      <!-- 卡片列表 -->
120
+      <div class="card-list">
121
+        <div
122
+          v-for="category in categories"
123
+          :key="category.id"
124
+          class="card-item"
125
+        >
126
+          <ElCard
127
+            :bordered="false"
128
+            class="category-card"
129
+            @click="navigateToDetail(category.id)"
130
+          >
131
+            <div class="card-content">
132
+              <!-- 左侧图标 -->
133
+              <div
134
+                class="card-icon"
135
+                :style="{
136
+                  backgroundColor: category.color + '20',
137
+                  color: category.color,
138
+                }"
139
+              >
140
+                <ElIcon :icon="category.icon" size="24" />
141
+              </div>
142
+              <!-- 中间内容 -->
143
+              <div class="card-main">
144
+                <h3 class="card-title">{{ category.name }}</h3>
145
+                <p class="card-description">{{ category.description }}</p>
146
+              </div>
147
+              <!-- 右侧信息 -->
148
+              <div class="card-info">
149
+                <div class="creator">{{ category.createBy }}</div>
150
+                <div class="create-time">{{ category.createTime }}</div>
151
+                <!-- 操作按钮 -->
152
+                <div class="card-actions">
153
+                  <ElButton
154
+                    type="text"
155
+                    :icon="Edit"
156
+                    circle
157
+                    @click.stop="openEditDrawer(category)"
158
+                  />
159
+                  <ElButton type="text" :icon="Delete" circle />
160
+                </div>
136 161
               </div>
137 162
             </div>
138
-          </div>
139
-        </ElCard>
163
+          </ElCard>
164
+        </div>
140 165
       </div>
141
-    </div>
142
-    <!-- 分页 -->
143
-    <div class="pagination">
144
-      <ElPagination 
145
-        layout="prev, pager, next" 
146
-        :total="categories.length" 
147
-        :page-size="15"
148
-      />
149
-    </div>
150
-    <!-- 创建/编辑抽屉 -->
151
-    <ElDrawer
152
-      v-model="drawerVisible"
153
-      :title="drawerMode === 'create' ? '创建知识库' : '编辑知识库'"
154
-      size="30%"
155
-      direction="rtl"
156
-      @close="closeDrawer"
157
-    >
158
-      <KnowledgeCreate
159
-        :mode="drawerMode"
160
-        :initial-data="selectedCategory"
166
+      <!-- 分页 -->
167
+      <div class="pagination">
168
+        <ElPagination
169
+          layout="prev, pager, next"
170
+          :total="total"
171
+          :page-size="pageSize"
172
+        />
173
+      </div>
174
+      <!-- 创建/编辑抽屉 -->
175
+      <ElDrawer
176
+        v-model="drawerVisible"
177
+        :title="drawerMode === 'create' ? '创建知识库' : '编辑知识库'"
178
+        size="30%"
179
+        direction="rtl"
161 180
         @close="closeDrawer"
162
-        @save="saveCategory"
163
-      />
164
-    </ElDrawer>
165
-</div>
166
-</Page>
181
+      >
182
+        <KnowledgeCreate
183
+          :mode="drawerMode"
184
+          :initial-data="selectedCategory"
185
+          @close="closeDrawer"
186
+          @save="saveCategory"
187
+        />
188
+      </ElDrawer>
189
+    </div>
190
+  </Page>
167 191
 </template>
168 192
 <style lang="scss" scoped>
169 193
 .wrap {
170
-padding: 16px;
171
-background-color: #fff;
172
-border-radius: 6px;
194
+  padding: 16px;
195
+  background-color: #fff;
196
+  border-radius: 6px;
173 197
 }
174 198
 
175 199
 .header {
@@ -192,11 +216,11 @@ border-radius: 6px;
192 216
 }
193 217
 
194 218
 .category-card:hover {
195
-  background-color: #E8F3FF;
219
+  background-color: #e8f3ff;
196 220
 }
197 221
 
198 222
 .category-card:hover .card-title {
199
-  color: #2D64D0;
223
+  color: #2d64d0;
200 224
 }
201 225
 
202 226
 .category-card:hover .creator,
@@ -275,4 +299,3 @@ border-radius: 6px;
275 299
   justify-content: center;
276 300
 }
277 301
 </style>
278
-

+ 96 - 58
apps/web-ele/src/views/schedule/view/components/day/index.vue

@@ -15,16 +15,18 @@ const emergencyTasks = [
15 15
     title: '应急演练',
16 16
     icon: 'warning',
17 17
     color: '#D34B27',
18
+    mainColor: '#FFE6E0',
18 19
     deadline: '12-31 23:59',
19 20
     days: 61,
20 21
     status: '可授权',
21
-    statusColor: 'blue',
22
+    statusColor: '#215ACD',
22 23
   },
23 24
   {
24 25
     id: 2,
25 26
     title: '纳税人普查',
26 27
     icon: 'document',
27 28
     color: '#D34B27',
29
+    mainColor: '#FFE6E0',
28 30
     deadline: '12-31 23:59',
29 31
     days: 61,
30 32
     status: '被授权',
@@ -38,24 +40,27 @@ const todayTasks = [
38 40
     title: '监控录像抽检',
39 41
     icon: 'monitor',
40 42
     color: '#FF9428',
43
+    mainColor: '#FFEAD6',
41 44
     deadline: '12-07 23:59',
42 45
     status: '可授权',
43
-    statusColor: 'blue',
46
+    statusColor: '#215ACD',
44 47
   },
45 48
   {
46 49
     id: 2,
47 50
     title: '爆缸试水1',
48 51
     icon: 'water',
49 52
     color: '#FF9428',
53
+    mainColor: '#FFEAD6',
50 54
     deadline: '12-14 23:00',
51 55
     status: '已授权',
52
-    statusColor: 'green',
56
+    statusColor: '#339169',
53 57
   },
54 58
   {
55 59
     id: 3,
56 60
     title: '应急消防用品月检',
57 61
     icon: 'fire',
58
-    color: '#67C23A',
62
+    color: '#FF9428',
63
+    mainColor: '#FFEAD6',
59 64
     deadline: '12-31 13:59',
60 65
     status: '被授权',
61 66
     statusColor: 'orange',
@@ -64,16 +69,18 @@ const todayTasks = [
64 69
     id: 4,
65 70
     title: '核对销售(油品)调查1',
66 71
     icon: 'check',
67
-    color: '#E6A23C',
72
+    color: '#FF9428',
73
+    mainColor: '#FFEAD6',
68 74
     deadline: '12-15 23:59',
69 75
     status: '可授权',
70
-    statusColor: 'blue',
76
+    statusColor: '#215ACD',
71 77
   },
72 78
   {
73 79
     id: 5,
74 80
     title: '便利店盘点',
75 81
     icon: 'shopping',
76
-    color: '#E6A23C',
82
+    color: '#FF9428',
83
+    mainColor: '#FFEAD6',
77 84
     deadline: '12-31 23:59',
78 85
     status: '被授权',
79 86
     statusColor: 'orange',
@@ -82,25 +89,28 @@ const todayTasks = [
82 89
     id: 6,
83 90
     title: '新员工三级教育',
84 91
     icon: 'user',
85
-    color: '#409EFF',
92
+    color: '#339169',
93
+    mainColor: '#D6EFE6',
86 94
     deadline: '12-06 23:00',
87 95
     status: '已授权',
88
-    statusColor: 'green',
96
+    statusColor: '#339169',
89 97
   },
90 98
   {
91 99
     id: 7,
92 100
     title: '厨房宿舍月检',
93 101
     icon: 'home',
94
-    color: '#909399',
102
+    color: '#339169',
103
+    mainColor: '#D6EFE6',
95 104
     deadline: '12-31 23:59',
96 105
     status: '可授权',
97
-    statusColor: 'blue',
106
+    statusColor: '#215ACD',
98 107
   },
99 108
   {
100 109
     id: 8,
101 110
     title: '收油流程巡检',
102 111
     icon: 'oil',
103
-    color: '#409EFF',
112
+    color: '#339169',
113
+    mainColor: '#D6EFE6',
104 114
     deadline: '12-07 23:59',
105 115
     status: '被授权',
106 116
     statusColor: 'orange',
@@ -109,28 +119,31 @@ const todayTasks = [
109 119
     id: 9,
110 120
     title: '第一次例会',
111 121
     icon: 'meeting',
112
-    color: '#409EFF',
122
+    color: '#339169',
123
+    mainColor: '#D6EFE6',
113 124
     deadline: '12-15 23:00',
114 125
     status: '可授权',
115
-    statusColor: 'blue',
126
+    statusColor: '#215ACD',
116 127
   },
117 128
   {
118 129
     id: 10,
119 130
     title: '建军计划',
120 131
     icon: 'plan',
121
-    color: '#67C23A',
132
+    color: '#339169',
133
+    mainColor: '#D6EFE6',
122 134
     deadline: '12-03 23:00',
123 135
     status: '已授权',
124
-    statusColor: 'green',
136
+    statusColor: '#339169',
125 137
   },
126 138
   {
127 139
     id: 11,
128 140
     title: '员工培训',
129 141
     icon: 'training',
130
-    color: '#409EFF',
142
+    color: '#339169',
143
+    mainColor: '#D6EFE6',
131 144
     deadline: '12-31 23:59',
132 145
     status: '可授权',
133
-    statusColor: 'blue',
146
+    statusColor: '#215ACD',
134 147
   },
135 148
 ];
136 149
 
@@ -139,25 +152,28 @@ const tomorrowTasks = [
139 152
     id: 1,
140 153
     title: '巡检日检',
141 154
     icon: 'check',
142
-    color: '#67C23A',
155
+    color: '#215ACD',
156
+    mainColor: '#E4EDFF',
143 157
     deadline: '12-31 13:59',
144 158
     status: '可授权',
145
-    statusColor: 'blue',
159
+    statusColor: '#215ACD',
146 160
   },
147 161
   {
148 162
     id: 2,
149 163
     title: '爆缸试水1',
150 164
     icon: 'water',
151
-    color: '#409EFF',
165
+    color: '#215ACD',
166
+    mainColor: '#E4EDFF',
152 167
     deadline: '12-14 23:00',
153 168
     status: '已授权',
154
-    statusColor: 'green',
169
+    statusColor: '#339169',
155 170
   },
156 171
   {
157 172
     id: 3,
158 173
     title: '应急消防用品月检',
159 174
     icon: 'fire',
160
-    color: '#67C23A',
175
+    color: '#215ACD',
176
+    mainColor: '#E4EDFF',
161 177
     deadline: '12-31 13:59',
162 178
     status: '被授权',
163 179
     statusColor: 'orange',
@@ -166,25 +182,28 @@ const tomorrowTasks = [
166 182
     id: 4,
167 183
     title: '核对销售(油品)调查1',
168 184
     icon: 'check',
169
-    color: '#E6A23C',
185
+    color: '#215ACD',
186
+    mainColor: '#E4EDFF',
170 187
     deadline: '12-15 23:59',
171 188
     status: '可授权',
172
-    statusColor: 'blue',
189
+    statusColor: '#215ACD',
173 190
   },
174 191
   {
175 192
     id: 5,
176 193
     title: '便利店盘点',
177 194
     icon: 'shopping',
178
-    color: '#E6A23C',
195
+    color: '#86909C',
196
+    mainColor: '#F1F1F1',
179 197
     deadline: '12-31 23:59',
180 198
     status: '已授权',
181
-    statusColor: 'green',
199
+    statusColor: '#339169',
182 200
   },
183 201
   {
184 202
     id: 6,
185 203
     title: '新员工三级教育',
186 204
     icon: 'user',
187
-    color: '#409EFF',
205
+    color: '#86909C',
206
+    mainColor: '#F1F1F1',
188 207
     deadline: '12-06 23:00',
189 208
     status: '被授权',
190 209
     statusColor: 'orange',
@@ -193,10 +212,11 @@ const tomorrowTasks = [
193 212
     id: 7,
194 213
     title: '巡检日检',
195 214
     icon: 'check',
196
-    color: '#67C23A',
215
+    color: '#86909C',
216
+    mainColor: '#F1F1F1',
197 217
     deadline: '12-31 13:59',
198 218
     status: '可授权',
199
-    statusColor: 'blue',
219
+    statusColor: '#215ACD',
200 220
   },
201 221
 ];
202 222
 // 模拟图标映射
@@ -231,31 +251,37 @@ function hexToRgb(hex) {
231 251
   <div class="mb-6">
232 252
     <h3 class="mb-3 text-lg font-semibold">逾期待处理</h3>
233 253
     <div
234
-      class="grid grid-cols-4 gap-4 sm:grid-cols-4 md:grid-cols-4 lg:grid-cols-5 xl:grid-cols-6"
254
+      class="grid grid-cols-4 gap-3 sm:grid-cols-4 md:grid-cols-4 lg:grid-cols-5 xl:grid-cols-5"
235 255
     >
236 256
       <div
237 257
         v-for="task in emergencyTasks"
238 258
         :key="task.id"
239
-        class="cursor-pointer rounded-lg shadow-sm transition-all hover:shadow-md"
259
+        class="h-[96px] w-[240px] cursor-pointer rounded shadow-sm transition-all hover:shadow-md"
240 260
         @click="handleTaskClick(task.id)"
241 261
       >
242 262
         <div
243
-          class="flex h-8 items-center justify-center rounded-t-lg text-sm font-medium text-white"
263
+          class="flex h-8 items-center justify-center rounded-t text-sm font-medium text-white"
244 264
           :style="{ backgroundColor: task.color }"
245 265
         >
246 266
           已逾期 {{ task.days }} 天
247 267
         </div>
248
-        <div
249
-          class="flex items-center justify-between rounded-b-lg border border-t-0 border-gray-200 p-4"
250
-          :style="{ backgroundColor: `rgba(${hexToRgb(task.color)}, 0.35)` }"
268
+        <div 
269
+          class="flex items-center justify-between rounded-b border border-t-0 border-gray-200 p-4 h-[64px]" 
270
+          :style="{ backgroundColor: task.mainColor }" 
251 271
         >
252 272
           <div class="flex items-center" style="margin-right: 8px">
253 273
             <span
254 274
               class="flex-none rounded px-2 py-0.5 text-xs font-medium"
255
-              :class="{
256
-                'bg-blue-100 text-blue-600': task.statusColor === 'blue',
257
-                'bg-orange-100 text-orange-600': task.statusColor === 'orange',
258
-                'bg-green-100 text-green-600': task.statusColor === 'green',
275
+              style="color: #ffffff"
276
+              :style="{
277
+                backgroundColor:
278
+                  task.statusColor === '#215ACD'
279
+                    ? '#215ACD'
280
+                    : task.statusColor === '#339169'
281
+                      ? '#339169'
282
+                      : task.statusColor === 'orange'
283
+                        ? '#ea580c'
284
+                        : '',
259 285
               }"
260 286
             >
261 287
               {{ task.status }}
@@ -277,32 +303,38 @@ function hexToRgb(hex) {
277 303
   <div class="mb-6">
278 304
     <h3 class="mb-3 text-lg font-semibold">当日</h3>
279 305
     <div
280
-      class="grid grid-cols-4 gap-4 sm:grid-cols-4 md:grid-cols-4 lg:grid-cols-5 xl:grid-cols-6"
306
+      class="grid grid-cols-4 gap-3 sm:grid-cols-4 md:grid-cols-4 lg:grid-cols-5 xl:grid-cols-5"
281 307
     >
282 308
       <div
283 309
         v-for="task in todayTasks"
284 310
         :key="task.id"
285
-        class="cursor-pointer rounded-lg shadow-sm transition-all hover:shadow-md"
311
+        class="h-[96px] w-[240px] cursor-pointer rounded shadow-sm transition-all hover:shadow-md"
286 312
         @click="handleTaskClick(task.id)"
287 313
       >
288 314
         <div
289
-          class="flex h-8 items-center justify-center rounded-t-lg text-sm font-medium text-white"
315
+          class="flex h-8 items-center justify-center rounded-t text-sm font-medium text-white"
290 316
           :style="{ backgroundColor: task.color }"
291 317
         >
292 318
           {{ task.deadline }}
293 319
         </div>
294 320
         <div
295
-          class="flex items-center justify-between rounded-b-lg border border-t-0 border-gray-200 p-4"
296
-          :style="{ backgroundColor: `rgba(${hexToRgb(task.color)}, 0.35)` }"
321
+          class="flex items-center justify-between rounded-b border border-t-0 border-gray-200 p-4 h-[64px]"
322
+          :style="{ backgroundColor: task.mainColor }"
297 323
         >
298 324
           <div class="flex items-center" style="margin-right: 8px">
299 325
             <span
300 326
               v-if="task.status"
301 327
               class="flex-none rounded px-2 py-0.5 text-xs font-medium"
302
-              :class="{
303
-                'bg-blue-100 text-blue-600': task.statusColor === 'blue',
304
-                'bg-orange-100 text-orange-600': task.statusColor === 'orange',
305
-                'bg-green-100 text-green-600': task.statusColor === 'green',
328
+              style="color: #ffffff"
329
+              :style="{
330
+                backgroundColor:
331
+                  task.statusColor === '#215ACD'
332
+                    ? '#215ACD'
333
+                    : task.statusColor === '#339169'
334
+                      ? '#339169'
335
+                      : task.statusColor === 'orange'
336
+                        ? '#ea580c'
337
+                        : '',
306 338
               }"
307 339
             >
308 340
               {{ task.status }}
@@ -322,32 +354,38 @@ function hexToRgb(hex) {
322 354
   <div>
323 355
     <h3 class="mb-3 text-lg font-semibold">明日</h3>
324 356
     <div
325
-      class="grid grid-cols-4 gap-4 sm:grid-cols-4 md:grid-cols-4 lg:grid-cols-5 xl:grid-cols-6"
357
+      class="grid grid-cols-4 gap-3 sm:grid-cols-4 md:grid-cols-4 lg:grid-cols-5 xl:grid-cols-5"
326 358
     >
327 359
       <div
328 360
         v-for="task in tomorrowTasks"
329 361
         :key="task.id"
330
-        class="cursor-pointer rounded-lg shadow-sm transition-all hover:shadow-md"
362
+        class="h-[96px] w-[240px] cursor-pointer rounded shadow-sm transition-all hover:shadow-md"
331 363
         @click="handleTaskClick(task.id)"
332 364
       >
333 365
         <div
334
-          class="flex h-8 items-center justify-center rounded-t-lg text-sm font-medium text-white"
366
+          class="flex h-8 items-center justify-center rounded-t text-sm font-medium text-white"
335 367
           :style="{ backgroundColor: task.color }"
336 368
         >
337 369
           {{ task.deadline }}
338 370
         </div>
339 371
         <div
340
-          class="flex items-center justify-between rounded-b-lg border border-t-0 border-gray-200 p-4"
341
-          :style="{ backgroundColor: `rgba(${hexToRgb(task.color)}, 0.35)` }"
372
+          class="flex items-center justify-between rounded-b border border-t-0 border-gray-200 p-4 h-[64px]"
373
+          :style="{ backgroundColor: task.mainColor }"
342 374
         >
343 375
           <div class="flex items-center" style="margin-right: 8px">
344 376
             <span
345 377
               v-if="task.status"
346 378
               class="flex-none rounded px-2 py-0.5 text-xs font-medium"
347
-              :class="{
348
-                'bg-blue-100 text-blue-600': task.statusColor === 'blue',
349
-                'bg-orange-100 text-orange-600': task.statusColor === 'orange',
350
-                'bg-green-100 text-green-600': task.statusColor === 'green',
379
+              style="color: #ffffff"
380
+              :style="{
381
+                backgroundColor:
382
+                  task.statusColor === '#215ACD'
383
+                    ? '#215ACD'
384
+                    : task.statusColor === '#339169'
385
+                      ? '#339169'
386
+                      : task.statusColor === 'orange'
387
+                        ? '#ea580c'
388
+                        : '',
351 389
               }"
352 390
             >
353 391
               {{ task.status }}