Browse Source

方案筹划 样式调整

zhaoen 4 months ago
parent
commit
3ee6155721

+ 6 - 5
src/components/Components/TaskUserCard.vue

@@ -147,13 +147,13 @@
     </div>
 
     <div class="plan-actions">
-      <el-button size="mini" class="dark-button" @click="editPlan">
+      <el-button icon="el-icon-check" class="blue-btn" @click="editPlan">
         信息项确认
       </el-button>
-      <el-button size="mini" class="dark-button" @click="editPlan">
+      <el-button icon="el-icon-edit" class="blue-btn" @click="editPlan">
         编辑
       </el-button>
-      <el-button size="mini" class="dark-button" @click="viewDetail">
+      <el-button icon="el-icon-delete" type="danger" @click="viewDetail">
         删除
       </el-button>
     </div>
@@ -314,7 +314,8 @@
   .plan-name {
     flex: 1;
     margin: 0;
-    font-size: 16px;
+    font-size: 18px;
+    font-weight: bold;
     overflow: hidden;
     text-overflow: ellipsis;
     white-space: nowrap;
@@ -343,7 +344,7 @@
   .info-row {
     display: flex;
     margin-bottom: 8px;
-    font-size: 13px;
+    font-size: 16px;
     align-items: center;
   }
 

+ 4 - 3
src/components/GlobalComponents/OverallCard.vue

@@ -159,7 +159,7 @@
       <!--      <el-button size="mini" class="dark-button" @click="editPlan">-->
       <!--        编辑-->
       <!--      </el-button>-->
-      <el-button size="mini" class="dark-button" @click="viewDetail">
+      <el-button icon="el-icon-edit" class="blue-btn" @click="viewDetail">
         编制综合布设方案
       </el-button>
     </div>
@@ -319,7 +319,8 @@
   .plan-name {
     flex: 1;
     margin: 0;
-    font-size: 16px;
+    font-size: 18px;
+    font-weight: bold;
     overflow: hidden;
     text-overflow: ellipsis;
     white-space: nowrap;
@@ -347,7 +348,7 @@
   .info-row {
     display: flex;
     margin-bottom: 8px;
-    font-size: 13px;
+    font-size: 16px;
     align-items: center;
   }
 

+ 6 - 1
src/router/index.js

@@ -83,7 +83,12 @@ export const constantRoutes = [
     component: () => import("@/views/planningSchem/comprehensive/components/planCreate.vue"),
     hidden: true,
   },
-
+  {
+    path: "/home/collaborativeCreate",
+    name: "collaborativeCreate",
+    component: () => import("@/views/programPlanning/collaborativePlanning/collaborativeCreate.vue"),
+    hidden: true,
+  },
 
   {
     path: "/planningSchem/Interference",

+ 2 - 0
src/styles/element-variables.scss

@@ -788,3 +788,5 @@ $--breakpoints-spec: (                         // 特殊断点配置集合
 .el-table__column-filter-trigger i {
   color: #ffffff;
 }
+
+

+ 29 - 12
src/views/planAndDeduction/taskMage/taskCreate.vue

@@ -36,8 +36,8 @@
                 drag
             >
               <i class="el-icon-upload"></i>
-              <div class="upload-text text-lg font-medium text-gray-700 mb-2">点击选择文件 或拖拽文件到此处</div>
-              <div class="upload-tip text-gray-500 mb-4">支持格式: PDF、Word、TXT、图片等</div>
+              <div class="upload-text text-lg font-medium text-white mb-2">点击选择文件 或拖拽文件到此处</div>
+              <div class="upload-tip text-white mb-4">支持格式: PDF、Word、TXT、图片等</div>
             </el-upload>
           </div>
         </el-card>
@@ -97,7 +97,7 @@
           <el-row :gutter="20" class="mb-8">
             <el-col :span="6" v-for="(item, index) in summaryData" :key="index">
               <el-card
-                  :class="`h-32 shadow-md hover:shadow-lg transition-shadow duration-300 cursor-pointer flex items-center justify-center bg-${getCardBg(index)}`">
+                  :class="`h-32 shadow-md hover:shadow-lg transition-shadow duration-300 cursor-pointer flex items-center justify-center bg-${getCardBg(index)} `">
                 <div class="text-center">
                   <p class="text-gray-600 text-sm mb-1">{{ item.title }}</p>
                   <p class="text-2xl text-black font-bold mb-1">{{ item.value }}</p>
@@ -120,7 +120,7 @@
               <el-row :gutter="20">
                 <el-col :span="6" v-for="(item, index) in basicInfoList" :key="index">
                   <el-card
-                      :class="`p-4 ${getCardClass(item.status)}`"
+                      :class="`p-4 info-card ${getCardClass(item.status)}`"
                       shadow="hover"
                   >
                     <div class="flex justify-between items-start mb-2">
@@ -155,7 +155,7 @@
               <el-row :gutter="20">
                 <el-col :span="8" v-for="(item, index) in interferenceList" :key="index">
                   <el-card
-                      :class="`p-3 ${getCardClass(item.status)}`"
+                      :class="`p-3 info-card ${getCardClass(item.status)}`"
                       shadow="hover"
                   >
                     <div class="flex justify-between items-start mb-2">
@@ -190,7 +190,7 @@
               <el-row :gutter="20">
                 <el-col :span="12" v-for="(item, index) in measurementList" :key="index">
                   <el-card
-                      :class="`p-3 ${getCardClass(item.status)}`"
+                      :class="`p-3 info-card ${getCardClass(item.status)}`"
                       shadow="hover"
                   >
                     <div class="flex justify-between items-start mb-2">
@@ -225,7 +225,7 @@
               <el-row :gutter="20">
                 <el-col :span="12" v-for="(item, index) in layoutList" :key="index">
                   <el-card
-                      :class="`p-3 ${getCardClass(item.status)}`"
+                      :class="`p-3 info-card ${getCardClass(item.status)}`"
                       shadow="hover"
                   >
                     <div class="flex justify-between items-start mb-2">
@@ -260,7 +260,7 @@
               <el-row :gutter="20">
                 <el-col :span="12" v-for="(item, index) in guaranteeList" :key="index">
                   <el-card
-                      :class="`p-3 ${getCardClass(item.status)}`"
+                      :class="`p-3 info-card ${getCardClass(item.status)}`"
                       shadow="hover"
                   >
                     <div class="flex justify-between items-start mb-2">
@@ -304,7 +304,7 @@
           </p>
           <el-row :gutter="20">
             <el-col :span="6" v-for="(item, index) in confidenceList" :key="index">
-              <el-card shadow="hover" class="p-3 bg-gray-50 border-l-4 border-blue-500">
+              <el-card shadow="hover" class="p-3 bg-gray-100 border-l-4 border-blue-500">
                 <div class="flex justify-between items-center mb-2">
                   <span class="text-black font-blod">{{ item.title }}</span>
                   <el-tag
@@ -339,7 +339,7 @@
             <h3 class="text-xl pl-2 font-bold">任务信息确认</h3>
           </div>
           <el-divider></el-divider>
-          <el-tabs v-model="activeTab" class="mb-6 text-base">
+          <el-tabs v-model="activeTab2" class="mb-6 text-base">
             <el-tab-pane label="基本信息" name="basic">
               <el-row :gutter="20">
                 <el-col :span="8" class="mb-4" v-for="(item, index) in basicInfoList" :key="index">
@@ -485,7 +485,6 @@
           type="success"
           @click="nextStep"
           :icon="currentStep < 2 ? 'el-icon-arrow-right' : ''"
-          class="blue-btn"
       >
         {{ currentStep < 2 ? '下一步' : '完成' }}
       </el-button>
@@ -499,6 +498,7 @@ export default {
     return {
       currentStep: 0, // 当前步骤索引,0开始
       activeTab: 'basic', // 默认激活的标签页
+      activeTab2: 'basic', // 默认激活的标签页
       fileList: [], // 上传的文件列表
       isAnalyzing: false, // 是否正在解析
       analysisProgress: 0, // 解析进度
@@ -766,6 +766,7 @@ export default {
       } else {
         // 最后一步点击完成的逻辑
         this.$message.success('所有步骤已完成!');
+        this.$router.push({ path: '/scheme/taskMage' });
       }
     },
 
@@ -790,6 +791,11 @@ export default {
   animation: fadeIn 0.5s ease-out forwards;
 }
 
+.info-card {
+  min-height: 160px;
+
+
+}
 /* 覆盖Element UI样式 */
 ::v-deep .el-upload {
   width: 100%;
@@ -799,6 +805,14 @@ export default {
   height: 215px;
 }
 
+::v-deep .el-card__body{
+  display: flex;
+  flex-direction: column;
+}
+
+::v-deep .el-card__body p{
+  min-height: 48px;
+}
 /* 步骤头部(包含数字的圆形) */
 ::v-deep .el-step__head {
 
@@ -808,5 +822,8 @@ export default {
 ::v-deep .el-step__line {
   margin: 0 20px !important;
 }
-
+::v-deep .el-upload-dragger {
+  background-color: #0e2a53;
+  color: white;
+}
 </style>

+ 60 - 2
src/views/planningSchem/comprehensive/components/planCreate.vue

@@ -97,7 +97,14 @@
                 <el-card class="bg-gray-800 border border-gray-700 rounded-md">
                   <div class="text-center">
                     <h4 class="font-bold mb-2">{{ group.name }}</h4>
-                    <el-button type="success" class="w-full">发起协同</el-button>
+                    <el-button type="success" class="w-full" @click="showUserSelectDialog(group)">发起协同</el-button>
+                    <!-- 回显已选人员 -->
+                    <div v-if="groupCollaborators[group.name] && groupCollaborators[group.name].length">
+                      <p class="text-gray-400 text-sm mb-1">已选协同人员:</p>
+                      <p class="text-blue-400 text-sm">
+                        {{ groupCollaborators[group.name].map(user => user.name).join('、') }}
+                      </p>
+                    </div>
                   </div>
                 </el-card>
               </el-col>
@@ -154,6 +161,28 @@
         {{ currentStep === 2 ? '完成' : '下一步' }}
       </el-button>
     </div>
+
+    <!-- 选人弹窗 -->
+    <el-dialog
+        title="选择协同人员"
+        :visible.sync="showSelectUserDialog"
+        width="500px"
+        @close="cancelSelectUsers"
+    >
+      <el-checkbox-group v-model="selectedUsers">
+        <el-checkbox
+            v-for="user in userList"
+            :key="user.id"
+            :label="user"
+        >
+          {{ user.name }}
+        </el-checkbox>
+      </el-checkbox-group>
+      <div slot="footer" class="dialog-footer">
+        <el-button @click="cancelSelectUsers">取 消</el-button>
+        <el-button type="primary" @click="confirmSelectUsers">确 定</el-button>
+      </div>
+    </el-dialog>
   </div>
 </template>
 
@@ -256,6 +285,17 @@ export default {
         { name: '综合保障组' }
       ],
       selectedPlan: null,
+
+      showSelectUserDialog: false, // 控制选人弹窗显示
+      selectedGroup: null, // 存储当前点击的要发起协同的组
+      selectedUsers: [], // 存储选中的人员
+      userList: [ // 模拟人员列表数据
+        { id: 1, name: '张三' },
+        { id: 2, name: '李四' },
+        { id: 3, name: '王五' },
+        { id: 4, name: '赵六' }
+      ],
+      groupCollaborators: {} // 存储每个组已选的协同人员
     };
   },
   computed: {
@@ -277,6 +317,7 @@ export default {
     }
   },
   methods: {
+
     handleTaskSelect(task) {
       this.selectedTask = task;
       // 自动填充方案名称(可选)
@@ -291,7 +332,7 @@ export default {
       return 'info';
     },
     back() {
-      this.$router.push({ path: '/planningSchem/comprehensive' });
+      this.$router.push({ path: '/scheme/comprehensive' });
     },
     // 上一步
     prevStep() {
@@ -325,6 +366,23 @@ export default {
       setTimeout(() => {
         this.back();
       }, 1500);
+    },
+
+    // 点击发起协同,显示选人弹窗
+    showUserSelectDialog(group) {
+      this.selectedGroup = group;
+      this.showSelectUserDialog = true;
+      // 如果该组之前有选过人员,回显选中状态
+      this.selectedUsers = this.groupCollaborators[group.name] || [];
+    },
+    // 确认选择人员
+    confirmSelectUsers() {
+      this.groupCollaborators[this.selectedGroup.name] = this.selectedUsers;
+      this.showSelectUserDialog = false;
+    },
+    // 取消选择人员
+    cancelSelectUsers() {
+      this.showSelectUserDialog = false;
     }
   }
 };

+ 407 - 0
src/views/programPlanning/collaborativePlanning/CollaborativeCard.vue

@@ -0,0 +1,407 @@
+<template>
+  <el-card
+    class="p-0"
+    shadow="hover"
+  >
+    <template #header>
+      <div class="plan-header">
+        <div class="plan-secret-tag" :style="secretTagStyle">
+          {{ plan.secretLevel }}
+        </div>
+        <el-tooltip
+            :content="plan.planName"
+            placement="top"
+            :disabled="!isPlanNameOverflow"
+        >
+          <h3 ref="planNameRef" class="plan-name" style="color: #e0e6ed">
+            {{ plan.planName }}
+          </h3>
+        </el-tooltip>
+        <el-tag
+            type="info"
+            class="plan-status"
+            effect="dark"
+        >
+          {{ plan.type }}
+        </el-tag>
+      </div>
+    </template>
+
+
+    <div class="plan-content">
+      <div class="plan-main-info">
+        <div class="info-row">
+          <span class="info-label dark-label">任务名称:</span>
+          <el-tooltip
+            :content="plan.taskName"
+            placement="top"
+            :disabled="!isTaskNameOverflow"
+          >
+            <span ref="taskNameRef" class="info-value dark-value text-ellipsis">
+              {{ plan.taskName || "-" }}
+            </span>
+          </el-tooltip>
+        </div>
+        <div class="info-row">
+          <span class="info-label dark-label">任务代号:</span>
+          <el-tooltip
+            :content="plan.taskCode"
+            placement="top"
+            :disabled="!isTaskCodeOverflow"
+          >
+            <span ref="taskCodeRef" class="info-value dark-value text-ellipsis">
+              {{ plan.taskCode || "-" }}
+            </span>
+          </el-tooltip>
+        </div>
+        <div class="info-row">
+          <span class="info-label dark-label">开始时间:</span>
+          <el-tooltip
+            :content="plan.startTime"
+            placement="top"
+            :disabled="!isStartTimeOverflow"
+          >
+            <span
+              ref="startTimeRef"
+              class="info-value dark-value text-ellipsis"
+            >
+              {{ plan.startTime || "-" }}
+            </span>
+          </el-tooltip>
+        </div>
+        <div class="info-row">
+          <span class="info-label dark-label">结束时间:</span>
+          <el-tooltip
+            :content="plan.endTime"
+            placement="top"
+            :disabled="!isEndTimeOverflow"
+          >
+            <span ref="endTimeRef" class="info-value dark-value text-ellipsis">
+              {{ plan.endTime || "-" }}
+            </span>
+          </el-tooltip>
+        </div>
+      </div>
+
+      <div class="plan-additional-info">
+        <div class="info-row">
+           <span class="info-label dark-label mr-2">
+            审核状态:
+          </span>
+          <el-tag
+              :type="statusTagType"
+              size="small"
+              class="plan-status"
+              effect="dark"
+          >
+            {{ plan.status }}
+          </el-tag>
+        </div>
+        <div class="info-row">
+          <span class="info-label dark-label mr-2">
+            干扰方案编制状态:
+          </span>
+          <el-tag
+            :type="compileStatusTagType"
+            size="small"
+            effect="dark"
+            class="info-value"
+          >
+            {{ plan.compileStatus }}
+          </el-tag>
+        </div>
+        <div class="info-row">
+          <span class="info-label dark-label">秘级年限:</span>
+          <el-tooltip
+            :content="plan.secretYears"
+            placement="top"
+            :disabled="!isSecretYearsOverflow"
+          >
+            <span
+              ref="secretYearsRef"
+              class="info-value dark-value text-ellipsis"
+            >
+              {{ plan.secretYears || "-" }}
+            </span>
+          </el-tooltip>
+        </div>
+      </div>
+    </div>
+
+    <div class="plan-actions">
+      <el-button class="blue-btn" @click="editPlan">
+        编辑
+      </el-button>
+      <el-button class="blue-btn" @click="viewDetail">
+        详情
+      </el-button>
+      <el-button
+        type="danger"
+        @click="selectPlan"
+      >
+        删除
+      </el-button>
+    </div>
+  </el-card>
+</template>
+
+<script>
+  export default {
+    name: "InterferenceCard",
+    props: {
+      plan: {
+        type: Object,
+        required: true,
+        default: () => ({
+          id: "",
+          planName: "",
+          taskName: "",
+          taskCode: "",
+          startTime: "",
+          endTime: "",
+          compileStatus: "",
+          secretLevel: "秘密",
+          secretYears: "10年",
+          status: "有效",
+        }),
+      },
+    },
+    data() {
+      return {
+        isPlanNameOverflow: false,
+        isTaskNameOverflow: false,
+        isTaskCodeOverflow: false,
+        isTimeRangeOverflow: false,
+        isSecretYearsOverflow: false,
+        isStartTimeOverflow: false,
+        isEndTimeOverflow: false,
+      };
+    },
+    computed: {
+      timeRange() {
+        return `${this.plan.startTime} 至 ${this.plan.endTime}`;
+      },
+      cardClass() {
+        return {
+          "top-secret": this.plan.secretLevel === "绝密",
+          secret: this.plan.secretLevel === "秘密",
+          confidential: this.plan.secretLevel === "机密",
+          invalid: this.plan.status === "已失效",
+        };
+      },
+      secretTagStyle() {
+        const colors = {
+          绝密: "#c45656",
+          机密: "#b88230",
+          秘密: "#3475b5",
+        };
+        return {
+          backgroundColor: colors[this.plan.secretLevel] || "#6b7280",
+        };
+      },
+      statusTagType() {
+        const statusMap = {
+          有效: "success",
+          待审核: "warning",
+          已失效: "danger",
+          草稿: "info",
+        };
+        return statusMap[this.plan.status] || "info";
+      },
+      compileStatusTagType() {
+        const statusMap = {
+          已编制: "success",
+          编制中: "warning",
+          未编制: "danger",
+          已审核: "",
+        };
+        return statusMap[this.plan.compileStatus] || "info";
+      },
+    },
+    mounted() {
+      this.checkOverflows();
+    },
+    updated() {
+      this.checkOverflows();
+    },
+    methods: {
+      checkOverflows() {
+        this.isStartTimeOverflow = this.checkElementOverflow(
+          this.$refs.startTimeRef
+        );
+        this.isEndTimeOverflow = this.checkElementOverflow(
+          this.$refs.endTimeRef
+        );
+        this.isPlanNameOverflow = this.checkElementOverflow(
+          this.$refs.planNameRef
+        );
+        this.isTaskNameOverflow = this.checkElementOverflow(
+          this.$refs.taskNameRef
+        );
+        this.isTaskCodeOverflow = this.checkElementOverflow(
+          this.$refs.taskCodeRef
+        );
+        this.isTimeRangeOverflow = this.checkElementOverflow(
+          this.$refs.timeRangeRef
+        );
+        this.isSecretYearsOverflow = this.checkElementOverflow(
+          this.$refs.secretYearsRef
+        );
+      },
+      checkElementOverflow(element) {
+        return element ? element.scrollWidth > element.clientWidth : false;
+      },
+      selectPlan() {
+        this.$emit("select", this.plan);
+      },
+      editPlan() {
+        this.$emit("edit", this.plan);
+      },
+      viewDetail() {
+        this.$emit("view-detail", this.plan);
+      },
+    },
+  };
+</script>
+
+<style scoped>
+::v-deep .el-card__header {
+  background-color: #123e7f;
+}
+
+  .target-plan-card {
+    margin-bottom: 15px;
+    transition: all 0.3s ease;
+    border-radius: 4px;
+    border: 1px solid #425163;
+    display: flex;
+    flex-direction: column;
+  }
+
+  .target-plan-card:hover {
+    box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.2);
+  }
+
+  .plan-header {
+    display: flex;
+    align-items: center;
+    //margin-bottom: 12px;
+  }
+
+  .plan-secret-tag {
+    padding: 2px 8px;
+    border-radius: 4px;
+    color: white;
+    font-size: 12px;
+    margin-right: 8px;
+  }
+
+  .plan-name {
+    flex: 1;
+    margin: 0;
+    font-size: 18px;
+    font-weight: bold;
+    overflow: hidden;
+    text-overflow: ellipsis;
+    white-space: nowrap;
+    //max-width: 180px;
+  }
+
+  .plan-status {
+    margin-left: 8px;
+  }
+
+  .plan-content {
+    padding: 14px 16px;
+    flex: 1;
+  }
+
+  .plan-main-info {
+    margin-bottom: 10px;
+  }
+
+  .plan-additional-info {
+    padding-top: 10px;
+    border-top: 1px dashed #425163;
+  }
+
+  .info-row {
+    display: flex;
+    margin-bottom: 8px;
+    font-size: 16px;
+    align-items: center;
+  }
+
+  .dark-label {
+    color: #8796ad;
+    //width: 70px;
+    display: inline-block;
+    flex-shrink: 0;
+  }
+
+  .dark-value {
+    color: #e0e6ed;
+    flex: 1;
+  }
+
+  .text-ellipsis {
+    overflow: hidden;
+    text-overflow: ellipsis;
+    white-space: nowrap;
+    display: inline-block;
+    max-width: 100%;
+  }
+
+  .plan-actions {
+    display: flex;
+    justify-content: space-between;
+    padding: 14px 16px;
+    border-top: 1px solid #425163;
+  }
+
+  .dark-button {
+    background-color: #425163;
+    border-color: #5a6b7d;
+    color: #e0e6ed;
+  }
+
+  .dark-button:hover {
+    background-color: #5a6b7d;
+    border-color: #677a8c;
+    color: #ffffff;
+  }
+
+  /* 不同秘级的边框颜色 */
+  .top-secret {
+    border-top: 3px solid #c45656;
+  }
+
+  .secret {
+    border-top: 3px solid #3475b5;
+  }
+
+  .confidential {
+    border-top: 3px solid #b88230;
+  }
+
+  /* 失效状态的样式 */
+  .invalid {
+    opacity: 0.7;
+    position: relative;
+  }
+
+  .invalid::after {
+    content: "已失效";
+    position: absolute;
+    top: 50%;
+    left: 50%;
+    transform: translate(-50%, -50%) rotate(-15deg);
+    font-size: 24px;
+    font-weight: bold;
+    color: #f56c6c;
+    background-color: rgba(0, 0, 0, 0.7);
+    padding: 5px 15px;
+    border-radius: 4px;
+    z-index: 1;
+  }
+</style>

+ 159 - 0
src/views/programPlanning/collaborativePlanning/WangEditor.vue

@@ -0,0 +1,159 @@
+<template>
+  <div class="wangeditor-container">
+    <!-- 编辑器容器 -->
+    <div ref="editor" class="editor-wrapper"></div>
+  </div>
+</template>
+
+<script>
+import E from 'wangeditor'
+
+export default {
+  name: 'WangEditor',
+  props: {
+    // 接收父组件传入的初始内容
+    value: {
+      type: String,
+      default: ''
+    },
+    // 编辑器高度
+    height: {
+      type: Number,
+      default: 300
+    },
+    // 是否禁用编辑器
+    disabled: {
+      type: Boolean,
+      default: false
+    }
+  },
+  data() {
+    return {
+      editor: null // 编辑器实例
+    }
+  },
+  watch: {
+    // 监听父组件传入的内容变化,同步到编辑器
+    value(newVal) {
+      if (this.editor && newVal !== this.editor.txt.html()) {
+        this.editor.txt.html(newVal)
+      }
+    },
+    // 监听禁用状态变化
+    disabled(newVal) {
+      if (this.editor) {
+        newVal ? this.editor.disable() : this.editor.enable()
+      }
+    }
+  },
+  mounted() {
+    // 初始化编辑器
+    this.initEditor()
+  },
+  beforeDestroy() {
+    // 销毁编辑器,释放资源
+    if (this.editor) {
+      this.editor.destroy()
+      this.editor = null
+    }
+  },
+  methods: {
+    initEditor() {
+      // 创建编辑器实例
+      this.editor = new E(this.$refs.editor)
+
+      // 配置编辑器
+      this.editor.config.height = this.height
+
+      // 配置菜单栏(按需调整)
+      this.editor.config.menus = [
+        'head',  // 标题
+        'bold',  // 粗体
+        'fontSize',  // 字号
+        'fontName',  // 字体
+        'italic',  // 斜体
+        'underline',  // 下划线
+        'strikeThrough',  // 删除线
+        'foreColor',  // 文字颜色
+        'backColor',  // 背景颜色
+        'link',  // 插入链接
+        'list',  // 列表
+        'justify',  // 对齐方式
+        'quote',  // 引用
+        'emoticon',  // 表情
+        'image',  // 插入图片
+        'table',  // 表格
+        'code',  // 代码
+        'undo',  // 撤销
+        'redo'  // 重做
+      ]
+
+      // 配置图片上传(根据后端接口调整)
+      this.editor.config.uploadImgServer = '/api/upload-image'  // 后端上传接口
+      this.editor.config.uploadImgHeaders = {
+        'Authorization': 'Bearer ' + localStorage.getItem('token')  // 上传携带token
+      }
+      this.editor.config.uploadImgName = 'file'  // 上传文件的name字段
+      this.editor.config.uploadImgMaxSize = 2 * 1024 * 1024  // 最大2MB
+      this.editor.config.uploadImgMaxLength = 5  // 一次最多上传5张
+
+      // 图片上传成功后的处理
+      this.editor.config.uploadImgHooks = {
+        success: (xhr) => {
+          // 上传成功,xhr为返回的响应对象
+          console.log('图片上传成功', xhr)
+        },
+        fail: (xhr) => {
+          console.error('图片上传失败', xhr)
+        }
+      }
+
+      // 编辑器内容变化时,同步到父组件
+      this.editor.config.onchange = (html) => {
+        this.$emit('input', html)  // 触发v-model绑定
+        this.$emit('change', html)  // 触发change事件
+      }
+
+      // 如果需要禁用状态
+      if (this.disabled) {
+        this.editor.config.readOnly = true
+      }
+
+      // 初始化编辑器
+      this.editor.create()
+
+      // 设置初始内容
+      if (this.value) {
+        this.editor.txt.html(this.value)
+      }
+    }
+  }
+}
+</script>
+
+<style scoped>
+::v-deep .editor-wrapper {
+  border: none;
+  border-radius: 10px;
+}
+
+::v-deep .w-e-toolbar{
+  background-color: rgb(22 45 85) !important;
+}
+
+::v-deep .w-e-text-container{
+  background-color: rgba(255, 255, 255, 0.2);
+}
+
+/* 解决编辑器内部样式穿透问题 */
+::v-deep .w-e-toolbar {
+  flex-wrap: wrap;
+  padding: 5px 10px;
+  border-bottom: 1px solid #e5e7eb;
+}
+
+::v-deep .w-e-text-container {
+  z-index: 1 !important;  /* 解决可能的层级问题 */
+}
+</style>
+

+ 287 - 0
src/views/programPlanning/collaborativePlanning/collaborativeCreate.vue

@@ -0,0 +1,287 @@
+<template>
+  <div>
+    <div class="w-full p-4" style="background-color: #162d55">
+      <!-- 顶部信息栏 -->
+      <div class="flex justify-end align-center text-sm text-blue-200">
+      <span class="flex flex-1 text-2xl font-bold">
+        BB布设方案编制
+      </span>
+        <span class="mr-4">任务编号: TASK-2024-001</span>
+        <span class="mr-4">任务名称: 综合试验任务</span>
+        <span>当前状态: 方案编制中</span>
+      </div>
+    </div>
+    <div class="bb-layout-page text-white min-h-screen p-4">
+
+
+      <div class="flex gap-4">
+        <!-- 左侧侧边栏 -->
+        <div class="relative max-w-md mx-auto p-6 bg-gray-400 bg-opacity-20 backdrop-blur-lg border-gray-50 rounded-xl">
+          <div class="flex items-center border-blue-400 border-b mb-4">
+            <h3 class="text-lg font-bold" style="color: #4fc2f7">任务信息</h3>
+          </div>
+
+          <div class="p-4 mb-4 bg-black bg-opacity-20 rounded-md">
+            <el-card shadow="hover" class="p-3 mb-2 text-white bg-gray-100 bg-opacity-20 border-l-8 border-blue-400">
+              <div class="flex justify-between items-center mb-2">
+                <span class="text-blue-300 font-blod">实验区域</span>
+              </div>
+              <div class="flex text-sm mt-2">
+                <span>500m x 800m</span>
+              </div>
+            </el-card>
+            <el-card shadow="hover" class="p-3 mb-2 text-white bg-gray-100 bg-opacity-20 border-l-8 border-blue-400">
+              <div class="flex justify-between items-center mb-2">
+                <span class="text-blue-300 font-blod">BB装备数量</span>
+              </div>
+              <div class="flex text-sm mt-2">
+                <span>>8套</span>
+              </div>
+            </el-card>
+            <el-card shadow="hover" class="p-3 mb-2 text-white bg-gray-100 bg-opacity-20 border-l-8 border-blue-400">
+              <div class="flex justify-between items-center mb-2">
+                <span class="text-blue-300 font-blod">布设密度</span>
+              </div>
+              <div class="flex text-sm mt-2">
+                <span>中等</span>
+              </div>
+            </el-card>
+            <el-card shadow="hover" class="p-3 text-white bg-gray-100 bg-opacity-20 border-l-8 border-blue-400">
+              <div class="flex justify-between items-center mb-2">
+                <span class="text-blue-300 font-blod">任务类型</span>
+              </div>
+              <div class="flex text-sm mt-2">
+                <span>综合实验</span>
+              </div>
+            </el-card>
+          </div>
+
+          <!-- 方案模板 -->
+          <div class="flex items-center border-blue-400 border-b mb-4">
+            <h3 class="text-lg font-bold" style="color: #4fc2f7">方案模板</h3>
+          </div>
+          <div
+              class="flex flex-col p-4 mb-4 align-center justify-center rounded-md bg-gray-400 bg-opacity-30 border-none">
+            <span class="flex justify-center mb-2 text-lg font-bold">标准模板</span>
+            <span class="flex justify-center text-sm">常用于常规试验</span>
+          </div>
+          <div
+              class="flex flex-col p-4 mb-4 align-center justify-center rounded-md bg-gray-400 bg-opacity-30 border-none">
+            <span class="flex justify-center mb-2 text-lg font-bold">高密度模板</span>
+            <span class="flex justify-center text-sm">常用于密集目标</span>
+          </div>
+          <div
+              class="flex flex-col p-4 mb-4 align-center justify-center rounded-md bg-gray-400 bg-opacity-30 border-none">
+            <span class="flex justify-center mb-2 text-lg font-bold">分散式模板</span>
+            <span class="flex justify-center text-sm">常用于分散目标</span>
+          </div>
+          <div class="flex flex-col p-4 mb-4 align-center justify-center rounded-md bg-gray-400 bg-opacity-30 border-none">
+            <span class="flex justify-center mb-2 text-lg font-bold">自定义模板</span>
+            <span class="flex justify-center text-sm">手动配置参数</span>
+          </div>
+
+          <!-- 布设算法 -->
+          <div class="flex items-center border-blue-400 border-b mb-4">
+            <h3 class="text-lg font-bold" style="color: #4fc2f7">布设算法</h3>
+          </div>
+          <el-tabs type="card" stretch v-model="activeTab" class="mb-6">
+            <el-tab-pane label="随机布设" name="random">
+              <div class="bg-gray-400 bg-opacity-30 p-4 rounded">
+                <h2 class="text-xl font-semibold mb-4">随机布设参数</h2>
+                <el-form :model="randomParams" label-width="120px">
+                  <el-form-item label="随机种子">
+                    <el-input v-model="randomParams.randomSeed" placeholder="请输入随机种子"></el-input>
+                  </el-form-item>
+                  <el-form-item label="布设密度">
+                    <el-select v-model="randomParams.layoutDensity" placeholder="请选择布设密度">
+                      <el-option label="低等密度" value="low"></el-option>
+                      <el-option label="中等密度" value="medium"></el-option>
+                      <el-option label="高等密度" value="high"></el-option>
+                    </el-select>
+                  </el-form-item>
+                  <el-form-item label="最小间距(m)">
+                    <el-input v-model.number="randomParams.minSpacing" placeholder="请输入最小间距"></el-input>
+                  </el-form-item>
+                </el-form>
+              </div>
+            </el-tab-pane>
+            <el-tab-pane label="网格布设" name="grid">
+              <div class="bg-gray-400 bg-opacity-30 p-4 rounded">
+                <h2 class="text-xl font-semibold mb-4">网格布设参数</h2>
+                <!-- 可根据需求添加网格布设相关表单元素 -->
+              </div>
+            </el-tab-pane>
+            <el-tab-pane label="聚类布设" name="cluster">
+              <div class="bg-gray-400 bg-opacity-30 p-4 rounded">
+                <h2 class="text-xl font-semibold mb-4">聚类布设参数</h2>
+                <!-- 可根据需求添加聚类布设相关表单元素 -->
+              </div>
+            </el-tab-pane>
+          </el-tabs>
+
+          <!-- BB装备配置 -->
+          <el-card class="bg-gray-400 bg-opacity-30 border-none">
+            <div class="text-lg font-bold mb-2">BB装备配置</div>
+            <el-form label-position="top" size="small" label-width="60px">
+              <el-form-item label="装备数量">
+                <el-input value="12"></el-input>
+              </el-form-item>
+              <el-form-item label="装备类型">
+                <el-select placeholder="请选择" style="width: 100%">
+                  <el-option
+                      v-for="type in equipmentTypes"
+                      :key="type"
+                      :label="type"
+                      :value="type"
+                  ></el-option>
+                </el-select>
+              </el-form-item>
+            </el-form>
+          </el-card>
+
+          <!-- 操作控制 -->
+          <div class="space-y-2">
+            <el-button type="primary" size="small">生成方案</el-button>
+            <el-button type="success" size="small">应用方案</el-button>
+            <el-button type="warning" size="small">清空布设</el-button>
+            <el-button type="danger" size="small">导出方案</el-button>
+          </div>
+        </div>
+
+        <!-- 右侧主内容区 -->
+        <div class="flex-1 space-y-4 p-6 bg-gray-400 bg-opacity-20 backdrop-blur-lg border-gray-50 rounded-xl">
+          <!-- 布设状态 -->
+          <div class="flex items-center mb-4">
+            <h3 class="text-lg font-bold" style="color: #4fc2f7">布设状态</h3>
+          </div>
+            <div class="flex flex-col p-4 bg-black bg-opacity-20 mb-2">
+              <div class="">
+                <p>已布设BB数量: <span class="text-blue-300">0</span></p>
+                <p>当前算法: <span class="text-blue-300">随机布设</span></p>
+                <p>布设密度: <span class="text-blue-300">中等</span></p>
+                <p>覆盖面积: <span class="text-blue-300">0%</span></p>
+              </div>
+            </div>
+
+          <div class="flex items-center mb-4">
+            <h3 class="text-lg font-bold" style="color: #4fc2f7">方案信息</h3>
+          </div>
+          <div class="grid gap-4 grid-cols-4 p-4 mb-4 bg-black bg-opacity-20 rounded-md">
+            <el-card shadow="hover" class="p-3 text-white bg-gray-100 bg-opacity-20 border-l-8 border-blue-400">
+              <div class="flex justify-between items-center mb-2">
+                <span class="text-blue-300 font-blod">方案名称</span>
+              </div>
+              <div class="flex text-sm mt-2">
+                <span>BB布设方案-001</span>
+              </div>
+            </el-card>
+            <el-card shadow="hover" class="p-3 text-white bg-gray-100 bg-opacity-20 border-l-8 border-blue-400">
+              <div class="flex justify-between items-center mb-2">
+                <span class="text-blue-300 font-blod">创建时间</span>
+              </div>
+              <div class="flex text-sm mt-2">
+                <span>2025-08-20 11:05:30</span>
+              </div>
+            </el-card>
+            <el-card shadow="hover" class="p-3 text-white bg-gray-100 bg-opacity-20 border-l-8 border-blue-400">
+              <div class="flex justify-between items-center mb-2">
+                <span class="text-blue-300 font-blod">方案状态</span>
+              </div>
+              <div class="flex text-sm mt-2">
+                <span>编制中</span>
+              </div>
+            </el-card>
+            <el-card shadow="hover" class="p-3 text-white bg-gray-100 bg-opacity-20 border-l-8 border-blue-400">
+              <div class="flex justify-between items-center mb-2">
+                <span class="text-blue-300 font-blod">编制人员</span>
+              </div>
+              <div class="flex text-sm mt-2">
+                <span>张三</span>
+              </div>
+            </el-card>
+          </div>
+            <!-- 图例 -->
+            <div class="flex items-center text-base mb-2">
+              <span class="inline-block w-3 h-3 bg-orange-500 rounded-full mr-1"></span>
+              <span class="mr-4">BB装备</span>
+              <span class="inline-block w-3 h-3 bg-blue-500 rounded-full mr-1"></span>
+              <span class="mr-4">选中状态</span>
+              <span class="inline-block w-3 h-3 bg-purple-500 rounded-full mr-1"></span>
+              <span class="mr-4">聚类中心</span>
+              <span class="inline-block w-3 h-3 bg-green-500 rounded-full mr-1"></span>
+              <span>判别线</span>
+            </div>
+            <!-- 网格画布(模拟) -->
+            <div class="w-full bg-black bg-opacity-20 bg-blue-850 border border-blue-700 flex items-center justify-center" style="min-height: 400px">
+              <span class="text-blue-400">网格画布区域(可结合Canvas等实现交互)</span>
+            </div>
+            <div class="text-sm bg-blue-400 bg-opacity-20 rounded-md p-4 mt-2">
+              操作提示: 点击BB区位可选中,拖拽可调整位置,双击可查看详情,使用右侧配置区设置参数后点击"生成方案"按钮。
+            </div>
+
+          <!-- 方案信息 -->
+          <WangEditor
+              v-model="content"
+              :height="400"
+              :disabled="false"
+              @change="handleContentChange"
+          />
+        </div>
+      </div>
+    </div>
+  </div>
+
+</template>
+
+<script>
+import WangEditor from "@/views/programPlanning/collaborativePlanning/WangEditor.vue";
+export default {
+  components:{
+    WangEditor
+  },
+  data() {
+    return {
+      content:'',
+      selectedTemplate: 'standard',
+      selectedAlgorithm: 'random',
+      equipmentTypes: [
+        '陆地模拟蓝军B系统',
+        '发烟罐模拟蓝军模拟系统',
+        '无人机蓝军系统',
+        '大气状态分析仪'
+      ],
+      planInfo: [
+        {
+          name: 'BB布设方案-001',
+          createTime: '2024-01-15 14:30',
+          status: '编制中',
+          editor: '张三'
+        }
+      ],
+      activeTab: 'random',
+      randomParams: {
+        randomSeed: '12345',
+        layoutDensity: 'medium',
+        minSpacing: 50,
+      },
+    };
+  },
+  methods: {
+    handleContentChange(html) {
+      console.log('编辑器内容变化:', html)
+      // 可以在这里处理内容,如实时保存等
+    }
+  },
+};
+</script>
+
+<style scoped>
+.bb-layout-page {
+  font-size: 16px;
+  background-color: #244786;
+}
+
+.el-card {
+  border-radius: 4px;
+}
+</style>

+ 260 - 0
src/views/programPlanning/collaborativePlanning/index.vue

@@ -0,0 +1,260 @@
+<template>
+  <div>
+    <DarkLayout :query-form="queryForm">
+      <!-- 查询表单插槽 -->
+      <template #query-form>
+        <el-form-item label="方案名称">
+          <el-input
+              v-model="queryForm.name"
+              placeholder="请输入方案名称"
+              clearable
+          />
+        </el-form-item>
+        <el-form-item label="任务代号">
+          <el-input
+              v-model="queryForm.taskCode"
+              placeholder="请输入任务代号"
+              clearable
+          />
+        </el-form-item>
+      </template>
+
+      <!-- Header右侧操作按钮 -->
+      <template #header-actions>
+        <el-button type="primary" @click="handleQuery">查询</el-button>
+        <el-button class="blue-btn" @click="resetQuery">重置</el-button>
+        <el-button class="blue-btn" @click="handleAdd">新增</el-button>
+      </template>
+
+      <!-- 主要内容 -->
+      <template #main>
+        <CollaborativeCard
+            v-for="plan in planList"
+            :key="plan.id"
+            :plan="plan"
+            v-if="planList.length > 0"
+            @select="handleSelect"
+            @edit="handleEdit"
+            @view-detail="viewDetails"
+        />
+        <el-empty v-else description="暂无方案数据" />
+      </template>
+
+      <!-- 底部右侧分页 -->
+      <template #footer-actions>
+        <el-pagination
+            @size-change="handleSizeChange"
+            @current-change="handleCurrentChange"
+            :current-page="pagination.currentPage"
+            :page-sizes="[10, 20, 50, 100]"
+            :page-size="pagination.pageSize"
+            layout="total, sizes, prev, pager, next, jumper"
+            :total="pagination.total"
+        />
+      </template>
+
+    </DarkLayout>
+    <!-- 任务详情弹窗 -->
+    <DarkDialog title="任务详情"
+                :visible.sync="dialogVisible"
+                width="50%"
+                :before-close="handleClose">
+      <el-descriptions :column="2" border>
+        <el-descriptions-item label="方案名称">{{ currentPlan.planName }}</el-descriptions-item>
+        <el-descriptions-item label="任务名称">{{ currentPlan.taskName }}</el-descriptions-item>
+        <el-descriptions-item label="任务代号">{{ currentPlan.taskCode }}</el-descriptions-item>
+        <el-descriptions-item label="开始时间">{{ currentPlan.startTime }}</el-descriptions-item>
+        <el-descriptions-item label="结束时间">{{ currentPlan.endTime }}</el-descriptions-item>
+        <el-descriptions-item label="编制状态">{{ currentPlan.compileStatus }}</el-descriptions-item>
+        <el-descriptions-item label="密级">{{ currentPlan.secretLevel }}</el-descriptions-item>
+        <el-descriptions-item label="保密期限">{{ currentPlan.secretYears }}</el-descriptions-item>
+        <el-descriptions-item label="状态">{{ currentPlan.status }}</el-descriptions-item>
+      </el-descriptions>
+      <span slot="footer" class="dialog-footer">
+        <el-button @click="dialogVisible = false">关闭</el-button>
+      </span>
+    </DarkDialog>
+
+  </div>
+</template>
+
+<script>
+import DarkLayout from '@/components/GlobalComponents/DarkLayout.vue'
+import CollaborativeCard from './CollaborativeCard.vue'
+import DarkDialog from "@/components/Components/DarkDialog.vue";
+
+export default {
+  components: {
+    DarkDialog,
+    DarkLayout,
+    CollaborativeCard
+  },
+  data() {
+    return {
+      tableData: [
+        {
+          date: '2023-06-01',
+          name: '张三',
+          address: '北京市海淀区'
+        },
+        {
+          date: '2023-06-02',
+          name: '李四',
+          address: '上海市浦东新区'
+        }
+      ],
+      dialogVisible: false,
+      currentPlan: {}, // 当前选中的任务数据
+      queryForm: {
+        name: '',
+        taskCode: ''
+      },
+      planList: [
+        {
+          id: 'plan-001',
+          planName: '东海靶场2023年度-干扰保障方案',
+          taskName: '新型导弹打击试验',
+          taskCode: 'DH-2023-001',
+          startTime: '2023-06-15',
+          endTime: '2023-06-20',
+          compileStatus: '已编制',
+          secretLevel: '秘密',
+          secretYears: '10年',
+          status: '有效',
+          type:'干扰方案'
+        },
+        {
+          id: 'plan-002',
+          planName: '南海靶场电子-干扰保障方案',
+          taskName: '电子对抗演练',
+          taskCode: 'NH-2023-002',
+          startTime: '2023-07-10',
+          endTime: '2023-07-15',
+          compileStatus: '编制中',
+          secretLevel: '机密',
+          secretYears: '5年',
+          status: '待审核',
+          type:'干扰方案',
+        },
+        {
+          id: 'plan-003',
+          planName: '东海靶场2023年度靶标保障方案',
+          taskName: '新型导弹打击试验',
+          taskCode: 'DH-2023-001',
+          startTime: '2023-06-15',
+          endTime: '2023-06-20',
+          compileStatus: '已编制',
+          secretLevel: '秘密',
+          secretYears: '10年',
+          status: '有效',
+          type:'测量方案',
+        },
+        {
+          id: 'plan-004',
+          planName: '南海靶场电子对抗方案',
+          taskName: '电子对抗演练',
+          taskCode: 'NH-2023-002',
+          startTime: '2023-07-10',
+          endTime: '2023-07-15',
+          compileStatus: '编制中',
+          secretLevel: '机密',
+          secretYears: '5年',
+          status: '待审核',
+          type:'测量方案',
+        },
+        {
+          id: 'plan-005',
+          planName: '东海靶场2023年度靶标保障方案',
+          taskName: '新型导弹打击试验',
+          taskCode: 'DH-2023-001',
+          startTime: '2023-06-15',
+          endTime: '2023-06-20',
+          compileStatus: '已编制',
+          secretLevel: '秘密',
+          secretYears: '10年',
+          status: '有效',
+          type:'靶标方案',
+        },
+        {
+          id: 'plan-006',
+          planName: '南海靶场电子对抗方案',
+          taskName: '电子对抗演练',
+          taskCode: 'NH-2023-002',
+          startTime: '2023-07-10',
+          endTime: '2023-07-15',
+          compileStatus: '编制中',
+          secretLevel: '机密',
+          secretYears: '5年',
+          status: '待审核',
+          type:'靶标方案',
+        },
+        {
+          id: 'plan-007',
+          planName: '南海靶场电子-干扰保障方案',
+          taskName: '电子对抗演练',
+          taskCode: 'NH-2023-002',
+          startTime: '2023-07-10',
+          endTime: '2023-07-15',
+          compileStatus: '编制中',
+          secretLevel: '机密',
+          secretYears: '5年',
+          status: '待审核',
+          type:'干扰方案',
+        },
+      ],
+      pagination: {
+        currentPage: 1,
+        pageSize: 10,
+        total: 0
+      },
+      showAdvancedSearch: false
+    }
+  },
+  methods: {
+    handleClose(done) {
+      // 可以在这里添加关闭前的确认逻辑
+      done()
+    },
+    handleSelect(plan) {
+    },
+    handleEdit(plan) {
+      //跳转页面
+      this.$router.push({ path: '/planningSchem/Interference' })
+    },
+    viewDetails(plan) {
+      console.log("000")
+      this.currentPlan = plan
+      this.dialogVisible = true
+      console.log(111)
+    },
+    handleQuery() {
+      // 查询逻辑
+    },
+    resetQuery() {
+      this.queryForm = {
+        name: '',
+        taskCode: ''
+      }
+      this.handleQuery()
+    },
+    handleAdd(){
+      this.$router.push({ path: '/home/collaborativeCreate' });
+    },
+    handleSizeChange(val) {
+      this.pagination.pageSize = val
+      this.fetchData()
+    },
+    handleCurrentChange(val) {
+      this.pagination.currentPage = val
+      this.fetchData()
+    },
+    fetchData() {
+      // 获取数据逻辑
+    }
+  }
+}
+</script>
+
+<style scoped>
+
+</style>

+ 0 - 0
src/views/programPlanning/experimentTaskCreation/index.vue


+ 1 - 0
tailwind.config.js

@@ -1,4 +1,5 @@
 module.exports = {
+  mode: "jit",
   purge: [
     "./src/**/*.html",
     "./src/**/*.vue",