| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936 |
- <template>
- <div>
- <DarkLayout :query-form="queryForm">
- <!-- 查询表单插槽 -->
- <template #query-form>
- <el-form-item label="推演任务名称">
- <el-input
- v-model="queryForm.simulationName"
- placeholder="请输入推演任务名称"
- clearable
- />
- </el-form-item>
- </template>
- <!-- Header右侧操作按钮 -->
- <template #header-actions>
- <el-button icon="el-icon-search" type="primary" @click="handleQuery">
- 查询
- </el-button>
- <el-button
- @click="openAddDialog"
- icon="el-icon-plus"
- class="blue-btn"
- >
- 添加
- </el-button>
- </template>
- <!-- 主要内容 -->
- <template #main>
- <ScenarioeditingCard
- v-if="planList.length > 0"
- v-for="plan in planList"
- :key="plan.id + '-' + plan.createTime"
- :plan="plan"
- @edit="openExpectedEditDialog(plan)"
- @view-detail="viewDetails(plan)"
- />
- <el-empty v-else description="暂无方案数据" />
- </template>
- <!-- 底部右侧分页 -->
- <template #footer-actions>
- <el-pagination
- @size-change="handleSizeChange"
- @current-change="handleCurrentChange"
- :current-page="queryForm.pageNo"
- :page-sizes="[10, 20, 50, 100]"
- :page-size="queryForm.pageSize"
- layout="total, sizes, prev, pager, next, jumper"
- :total="total"
- />
- </template>
- </DarkLayout>
- <!-- 任务详情弹窗 -->
- <DarkDrawer
- title="任务详情"
- :visible.sync="dialogVisible"
- width="40%"
- :before-close="handleClose"
- >
- <el-row :gutter="20">
- <el-col :span="24" v-for="(task, index) in taskList" :key="index">
- <h3 class="section-title">
- <i class="el-icon-document mr-2"></i> 总体任务
- </h3>
- <div
- class="task-card"
- >
- <div class="flex justify-between items-center mb-3">
- <h4 class="task-title">{{ task.taskName }}</h4>
- </div>
- <div class="task-info">
- <li>任务代号: {{ task.taskCode || "-" }}</li>
- <li>任务类型: {{ $getDictNameByValue('task_type',task.taskType+'') || "-" }}</li>
- <li>任务时间: {{ task.testTime || "-" }}</li>
- <li>创建时间: {{ task.createTime || "-" }}</li>
- </div>
- </div>
- </el-col>
- <el-col :span="24" v-for="(task, index) in subTaskList" :key="index">
- <h3 class="section-title mt-4">
- <i class="el-icon-document mr-2"></i> 子任务
- </h3>
- <div
- class="task-card"
- >
- <div class="flex justify-between items-center mb-3">
- <h4 class="task-title">{{ task.subTaskName || "-" }}</h4>
- </div>
- <div class="task-info">
- <li>任务代号: {{ task.subTaskCode || "-" }}</li>
- <li>任务类型: {{ $getDictNameByValue('task_type',task.subTaskType+'') || "-" }}</li>
- <li>任务时间: {{ task.subTestTime || "-" }}</li>
- <li>打击维度: {{ task.fightAway || "对陆" }}</li>
- <li>创建时间: {{ task.createTime || "-" }}</li>
- </div>
- </div>
- </el-col>
- </el-row>
- </DarkDrawer>
- <!-- 新建/编辑 推演任务设定(单选总体方案) -->
- <DarkDrawer :title="editDialogTitle" :visible.sync="editVisible" size="55%">
- <el-form
- ref="editFormRef"
- :model="editForm"
- :rules="baseRules"
- label-width="120px"
- class="edit-form-dark"
- >
- <div class="form-grid">
- <!-- 基础信息 -->
- <el-form-item label="推演任务名称" prop="simulationName">
- <el-input v-model="editForm.simulationName" clearable />
- </el-form-item>
- <!-- 选择总体任务 -->
- <div class="task-select-section span-2">
- <h3 class="section-title">
- <i class="el-icon-document mr-2"></i> 选择总体任务
- </h3>
- <p class="section-desc">请选择要关联的总体任务,系统将根据总体任务推荐对应的子任务</p>
- <el-row :gutter="20">
- <el-col :span="8" class="mb-4" v-for="(task, index) in taskList" :key="index">
- <div
- class="task-card"
- :class="{ 'task-card--active': selectedTask && selectedTask.id === task.id }"
- @click="handleTaskSelect(task)"
- >
- <div class="flex justify-between items-center mb-3">
- <h4 class="task-title">{{ task.taskName }}</h4>
- </div>
- <div class="task-info">
- <li>任务代号: {{ task.taskCode || "-" }}</li>
- <li>任务类型: {{ $getDictNameByValue('task_type',task.taskType+'') || "-" }}</li>
- <li>任务时间: {{ task.testTime || "-" }}</li>
- <li>创建时间: {{ task.createTime || "-" }}</li>
- </div>
- <el-button class="task-btn" type="primary">选择此任务</el-button>
- </div>
- </el-col>
- </el-row>
- </div>
- <!-- 选择子任务 -->
- <div v-if="selectedTask" class="task-select-section span-2">
- <h3 class="section-title">
- <i class="el-icon-document mr-2"></i> 选择子任务
- </h3>
- <el-row :gutter="20">
- <el-col :span="8" class="mb-4" v-for="(task, index) in subTaskList" :key="index">
- <div
- class="task-card"
- :class="{ 'task-card--active': selectedSubTask && selectedSubTask.id === task.id }"
- @click="handleSubTaskSelect(task)"
- >
- <div class="flex justify-between items-center mb-3">
- <h4 class="task-title">{{ task.subTaskName || "-" }}</h4>
- </div>
- <div class="task-info">
- <li>任务代号: {{ task.subTaskCode || "-" }}</li>
- <li>任务类型: {{ $getDictNameByValue('task_type',task.subTaskType+'') || "-" }}</li>
- <li>任务时间: {{ task.subTestTime || "-" }}</li>
- <li>打击维度: {{ task.fightAway || "对陆" }}</li>
- <li>创建时间: {{ task.createTime || "-" }}</li>
- </div>
- <el-button class="task-btn" type="primary">选择此任务</el-button>
- </div>
- </el-col>
- </el-row>
- </div>
- <div v-if="selectedSubTask" class="task-select-section span-2">
- <h3 class="section-title">
- <i class="el-icon-document mr-2"></i> 选择方案
- </h3>
- <el-row :gutter="20">
- <!-- 树形表格实现 -->
- <el-table
- ref="treeTable"
- :data="schemeTable"
- style="width: 100%"
- row-key="id"
- border
- :tree-props="{ children: 'verList'}"
- @select="handleTreeSelect"
- @select-all="handleTreeSelectAll"
- >
- <!-- 单选列:不显示表头的选择框 -->
- <el-table-column
- type="selection"
- width="50"
- align="center"
- :selectable="canSelect"
- :show-header="false"
- />
- <!-- 树形表格字段 -->
- <el-table-column
- prop="schemeVersion"
- label="版本号"
- width="120"
- align="center"
- ></el-table-column>
- <el-table-column
- prop="batchId"
- label="批次ID"
- width=""
- align="center"
- ></el-table-column>
- <el-table-column
- prop="measurementSchemeStatus"
- label="测量方案"
- width="120"
- align="center"
- >
- <template slot-scope="scope">
- <el-tag size="mini" :type="getStatusTagType(scope.row.measurementSchemeStatus)">
- {{ scope.row.measurementSchemeStatus }}
- </el-tag>
- </template>
- </el-table-column>
- <!-- 干扰方案 -->
- <el-table-column
- label="干扰方案"
- width="120"
- align="center"
- >
- <template slot-scope="scope">
- <el-tag
- size="mini"
- :type="getStatusTagType(scope.row.interferenceSchemeStatus)"
- style="cursor: pointer;"
- @click="handleDocxClick(scope.row, '干扰')"
- >
- {{ scope.row.interferenceSchemeStatus }}
- </el-tag>
- </template>
- </el-table-column>
- <!-- 靶标方案 -->
- <el-table-column
- label="靶标方案"
- width="120"
- align="center"
- >
- <template slot-scope="scope">
- <el-tag
- size="mini"
- :type="getStatusTagType(scope.row.targetSchemeStatus)"
- style="cursor: pointer;"
- @click="handleDocxClick(scope.row, '靶标')"
- >
- {{ scope.row.targetSchemeStatus }}
- </el-tag>
- </template>
- </el-table-column>
- </el-table>
- </el-row>
- </div>
- </div>
- </el-form>
- <span class="pt-4 w-full flex justify-center">
- <el-button @click="editVisible = false">取 消</el-button>
- <el-button type="primary" @click="onEditSave">保 存</el-button>
- </span>
- </DarkDrawer>
- <!-- 文档预览弹窗 -->
- <el-dialog
- :visible.sync="docxDialogVisible"
- :title="dialogTitle"
- width="80%"
- top="5vh"
- @close="docxDialogVisible = false"
- v-if="docxDialogVisible"
- >
- <VueOfficeDocx
- v-if="docxSrc"
- :src="docxSrc"
- @error="onError"
- @rendered="onRendered"
- style="height: 70vh; overflow-y: auto;"
- />
- </el-dialog>
- </div>
- </template>
- <script>
- import DarkLayout from '@/components/GlobalComponents/DarkLayout.vue'
- import TaskUserCard from '@/components/Components/TaskUserCard.vue'
- import DarkDialog from "@/components/Components/DarkDialog.vue";
- import ScenarioeditingCard from "@/components/GlobalComponents/ScenarioeditingCard.vue";
- import {getList, insertDeductionTask, updateDeductionTask} from "@/api/deductionTask";
- import {findPageTask, findSubTaskPage} from "@/api/taskMage/taskMage";
- import {getListVer} from "@/api/planningScheme";
- export default {
- components: {
- ScenarioeditingCard,
- DarkDialog,
- DarkLayout,
- TaskUserCard
- },
- data() {
- return {
- /* 可选试验任务 */
- taskList: [],
- subTaskList:[],
- // 文档预览
- docxDialogVisible: false,
- dialogTitle: '',
- docxSrc: null,
- /* 当前选择状态(单选) */
- editVisible: false,
- editMode: 'edit', // 'add' | 'edit'
- selectedTask: null,
- selectedSubTask: null,
- schemeTable: [],
- selectedTreeNode: null, // 记录当前选中的树形节点
- /* 表单数据 */
- editForm: {
- id: '',
- simulationName: '',
- intendedEditing:0,
- simType:0,
- taskId:'',
- subTaskId:'',
- schemeId:'',
- versionId: '' // 记录选中的版本ID
- },
- baseRules: {
- simulationName: [{ required: true, message: '请输入任务名称', trigger: 'blur' }],
- },
- /* 其他弹窗与数据 */
- selectedPlan: {},
- tableData: [
- { date: '2023-06-01', name: '张三', address: '北京市海淀区' },
- { date: '2023-06-02', name: '李四', address: '上海市浦东新区' }
- ],
- dialogVisible: false,
- currentPlan: {},
- /* 列表和分页 */
- queryForm: { simulationName: '',intendedEditing:0,simType:0,pageNo: 1,pageSize: 10 },
- planList: [],
- total: 0,
- }
- },
- computed: {
- isAddMode() {
- return this.editMode === 'add'
- },
- editDialogTitle() {
- return this.editMode === 'add' ? '新建推演任务设定' : '编辑推演任务设定'
- },
- secretChipClass() {
- const map = { '绝密': 'danger', '机密': 'warning', '秘密': 'primary' }
- return map[this.selectedPlan?.secretLevel] || 'neutral'
- },
- selectedOverallPlanNames() {
- const p = this.currentOverallPlans.find(p => p.id === this.selectedOverallPlanId)
- return p ? [p.planName] : []
- }
- },
- mounted() {
- this.fetchData()
- },
- methods: {
- // 解析 schemeSubPlan 获取 docx 文件链接
- getDocxUrl(row, type) {
- if (!row.schemeSubPlan) return null;
- try {
- const planList = row.schemeSubPlan.startsWith('[')
- ? JSON.parse(row.schemeSubPlan)
- : [JSON.parse(row.schemeSubPlan)];
- // 查找对应类型的 docx 文件
- const targetType = type === '干扰' ? 1 : 2; // 假设 1=干扰,2=靶标(根据后端定义调整)
- const file = planList.find(item =>
- item.type === targetType && item.fileType === 'docx'
- );
- return file ? file.fileHttp : null;
- } catch (e) {
- console.error('解析 schemeSubPlan 失败:', e);
- return null;
- }
- },
- // 点击 tag 触发
- handleDocxClick(row, type) {
- const status = type === '干扰'
- ? row.interferenceSchemeStatus
- : row.targetSchemeStatus;
- if (status !== '已导入') return;
- const url = this.getDocxUrl(row, type);
- if (!url) {
- this.$message.warning(`${type}方案未找到可预览的文档`);
- return;
- }
- this.docxSrc = url;
- this.dialogTitle = `${type}方案文档预览 - ${row.schemeVersion}`;
- this.docxDialogVisible = true;
- },
- onError(e) {
- this.$message.error('文档加载失败,请稍后重试');
- console.error(e);
- },
- onRendered() {
- console.log('文档渲染完成');
- },
- getStatusTagType(status) {
- if (!status) return 'info';
- switch (status) {
- case '已编制':
- case '已导入':
- return 'success';
- case '未导入':
- case '未编制':
- return 'info';
- case '进行中':
- return 'warning';
- default:
- return 'info';
- }
- },
- // 控制哪些行可被选择(全部可选)
- canSelect(row) {
- return true; // 可根据条件禁用某些行的选择
- },
- // 处理树形表格选择事件
- handleTreeSelect(selection, row) {
- // 如果已选中,则取消
- if (this.selectedTreeNode === row) {
- this.$refs.treeTable.clearSelection();
- this.selectedTreeNode = null;
- } else {
- // 清除之前的选择,只选中当前行
- this.$refs.treeTable.clearSelection();
- this.$nextTick(() => {
- this.$refs.treeTable.toggleRowSelection(row, true);
- });
- this.selectedTreeNode = row;
- }
- },
- // 禁用树形表格全选功能
- handleTreeSelectAll(selection) {
- if (selection.length > 1) {
- // 强制只保留最后一项
- const lastSelected = selection[selection.length - 1];
- this.$refs.treeTable.clearSelection();
- this.$refs.treeTable.toggleRowSelection(lastSelected, true);
- this.selectedTreeNode = lastSelected;
- }
- },
- /* 任务选择:加载其总体方案并清空已选 */
- async handleTaskSelect(task) {
- this.selectedTask = task;
- this.selectedSubTask = null;
- const params = {
- taskId_EQ: task.id,
- pageNo: 1,
- pageSize: 9999
- };
- const res = await findSubTaskPage(params);
- this.subTaskList = res.data.rows;
- },
- /* 单选工具 */
- isPlanSelected(plan) {
- return this.selectedOverallPlanId === plan.id;
- },
- togglePlan(plan) {
- this.selectedOverallPlanId = (this.selectedOverallPlanId === plan.id) ? '' : plan.id;
- },
- async getTaskList() {
- const params = {
- taskName_LIKE: '',
- taskType_EQ: '',
- pageNo: 1,
- pageSize: 9999
- };
- const res = await findPageTask(params);
- this.taskList = res.data.rows;
- },
- async getSubTaskList(taskId) {
- const params = {
- taskId_EQ: taskId,
- pageNo: 1,
- pageSize: 9999
- };
- const res = await findSubTaskPage(params);
- this.subTaskList = res.data.rows;
- },
- /* 添加:打开空白同一套表单 */
- async openAddDialog() {
- await this.getTaskList();
- this.editMode = 'add';
- this.selectedTask = null;
- this.selectedSubTask = null;
- this.editForm = {
- id: '',
- simulationName: '',
- intendedEditing: 0,
- simType: 0,
- taskId: '',
- subTaskId: '',
- schemeId: '',
- versionId: ''
- };
- this.editVisible = true;
- this.$nextTick(() => this.$refs.editFormRef && this.$refs.editFormRef.clearValidate());
- },
- /* 编辑:回填同一套表单 + 自动选中任务与总体方案(单选) */
- async openEditDialog(plan) {
- this.editMode = 'edit';
- this.editForm = JSON.parse(JSON.stringify(plan));
- // 重置选择状态
- this.selectedTreeNode = null;
- if (this.$refs.treeTable) {
- this.$refs.treeTable.clearSelection();
- }
- await this.getTaskList();
- const task = this.taskList.find(item => item.id === plan.taskId);
- if (task) {
- await this.handleTaskSelect(task);
- const subTask = this.subTaskList.find(item => item.id === plan.subTaskId);
- if (subTask) {
- // 等待子任务选择完成和数据加载
- await new Promise(resolve => {
- this.handleSubTaskSelect(subTask);
- // 给数据加载一点时间
- setTimeout(resolve, 500);
- });
- // 使用双重nextTick确保表格已渲染
- this.$nextTick(() => {
- this.$nextTick(() => {
- if (!this.$refs.treeTable) return;
- // 递归查找节点
- const findNode = (nodes, targetId) => {
- for (const node of nodes) {
- if (node.id === targetId) {
- return node;
- }
- if (node.verList && node.verList.length) {
- const found = findNode(node.verList, targetId);
- if (found) return found;
- }
- }
- return null;
- };
- const targetNode = findNode(this.schemeTable, plan.schemeId);
- if (targetNode) {
- // 先清除所有选择
- this.$refs.treeTable.clearSelection();
- // 选中目标节点
- this.$refs.treeTable.toggleRowSelection(targetNode, true);
- this.selectedTreeNode = targetNode;
- // 展开父节点
- this.expandParentNodes(this.schemeTable, targetNode.id);
- }
- });
- });
- }
- }
- this.editVisible = true;
- this.$nextTick(() => this.$refs.editFormRef && this.$refs.editFormRef.clearValidate());
- },
- // 优化展开父节点方法
- expandParentNodes(nodes, targetId) {
- const expandNodes = [];
- // 先收集需要展开的节点
- const findAndCollectParents = (nodes, targetId) => {
- for (const node of nodes) {
- if (node.id === targetId) {
- return true;
- }
- if (node.verList && node.verList.length) {
- const found = findAndCollectParents(node.verList, targetId);
- if (found) {
- expandNodes.push(node);
- return true;
- }
- }
- }
- return false;
- };
- findAndCollectParents(nodes, targetId);
- // 延迟展开,确保表格已准备好
- setTimeout(() => {
- expandNodes.forEach(node => {
- this.$refs.treeTable.toggleRowExpansion(node, true);
- });
- }, 300);
- },
- // 同时修改handleSubTaskSelect方法,确保数据加载完成
- handleSubTaskSelect(task) {
- return new Promise((resolve) => {
- this.selectedSubTask = task;
- this.selectedTreeNode = null;
- getListVer({subTaskId:task.id}).then((res) => {
- this.schemeTable = res.data;
- // 确保表格数据更新后重新渲染
- this.$nextTick(() => {
- if (this.$refs.treeTable) {
- this.$refs.treeTable.doLayout();
- }
- resolve();
- });
- console.log(this.schemeTable)
- });
- });
- },
- openExpectedEditDialog(plan) {
- this.$router.push({
- path: '/Deduction/taskSettingssss',
- query: {
- plan: JSON.stringify(plan)
- }
- });
- },
- /* 保存:处理树形表格选择 */
- onEditSave() {
- this.$refs.editFormRef.validate((valid) => {
- if (!valid) return;
- if (!this.selectedTask) {
- this.$message.error('请先选择一个总体任务');
- return;
- }
- if (!this.selectedSubTask) {
- this.$message.error('请选择一个子任务');
- return;
- }
- // 检查是否选择了节点
- if (!this.selectedTreeNode) {
- this.$message.error('请选择一个方案或版本');
- return;
- }
- // 写入所选方案和版本
- this.editForm.taskId = this.selectedTask.id;
- this.editForm.subTaskId = this.selectedSubTask.id;
- this.editForm.schemeId = this.selectedTreeNode.id;
- this.editForm.simulationType = 0;
- if(this.editMode==='add'){
- insertDeductionTask(this.editForm).then((res) => {
- if (res.code === 0) {
- this.$message.success('新建成功');
- this.taskList = [];
- this.selectedTask = null;
- this.subTaskList = [];
- this.selectedSubTask = null;
- this.selectedTreeNode = null;
- this.editVisible = false;
- this.handleQuery()
- } else {
- this.$message.error('新建失败');
- }
- });
- }else{
- updateDeductionTask(this.editForm).then((res)=>{
- if (res.code === 0) {
- this.$message.success('修改成功');
- this.taskList = [];
- this.selectedTask = null;
- this.subTaskList = [];
- this.selectedSubTask = null;
- this.selectedTreeNode = null;
- this.editVisible = false;
- this.handleQuery()
- } else {
- this.$message.error('修改失败');
- }
- })
- }
- });
- },
- /* 其它原有方法 */
- statusClass(s) {
- const map = { '已确认': 'success', '未确认': 'warning', '已失效': 'danger', '草稿': 'info' };
- return map[s] || 'info';
- },
- statusTagType(status) {
- const map = { '有效': 'warning', '待审核': 'warning', '草稿': 'info', '已失效': 'danger' };
- return map[status] || 'info';
- },
- handleClose(done) { done(); },
- async viewDetails(plan) {
- await this.getTaskList()
- this.taskList = this.taskList.filter(item=>item.id===plan.taskId)
- await this.getSubTaskList(plan.taskId)
- this.subTaskList = this.subTaskList.filter(item=>item.id===plan.subTaskId)
- this.dialogVisible = true;
- },
- /* 列表&分页占位 */
- handleQuery() {
- getList(this.queryForm).then((res) => {
- this.planList = res.data.records;
- this.total = res.data.total;
- });
- },
- resetQuery() {
- this.queryForm = { simulationName: '',intendedEditing:0,pageNo: 1,pageSize: 10 };
- this.handleQuery();
- },
- handleSizeChange(val) {
- this.queryForm.pageSize = val;
- this.handleQuery();
- },
- handleCurrentChange(val) {
- this.queryForm.pageNo = val;
- this.handleQuery();
- },
- fetchData() {
- this.queryForm.pageNo = 1;
- this.handleQuery();
- }
- }
- }
- </script>
- <style scoped>
- /* 弹窗体在 DarkDialog 里已经是深色,这里只美化表单 */
- .edit-form-dark {
- background: rgba(12, 33, 66, 0.6);
- border: 1px solid #2c3f59;
- border-radius: 8px;
- padding: 14px 16px;
- }
- .form-grid {
- display: grid;
- grid-template-columns: 1fr 1fr;
- column-gap: 18px;
- row-gap: 10px;
- }
- .form-grid .span-2 { grid-column: 1 / span 2; }
- ::v-deep .el-form-item__label { color: #9db2c9; }
- ::v-deep .el-input__inner,
- ::v-deep .el-textarea__inner,
- ::v-deep .el-select .el-input__inner,
- ::v-deep .el-date-editor .el-input__inner {
- background: rgba(0,0,0,0.18);
- border-color: rgba(255,255,255,0.12);
- color: #e6efff;
- }
- ::v-deep .el-input__inner::placeholder { color: #94a3b8; }
- ::v-deep .el-select-dropdown,
- ::v-deep .el-picker-panel {
- background: #1b2d4c;
- border-color: #2c3f59;
- color: #e6efff;
- }
- @media (max-width: 860px) {
- .form-grid { grid-template-columns: 1fr; }
- .form-grid .span-2 { grid-column: auto; }
- }
- .blue-btn:hover{
- background: #004466;
- border: 2px solid #1e3a5f;
- border-color: #4085ac;
- color: #fff;
- }
- /* Dialog 外观更暗、更清晰的分层 */
- ::v-deep .el-dialog__header {
- background: linear-gradient(180deg, #153b73, #0e2a53);
- border-bottom: 1px solid #364a64;
- }
- ::v-deep .el-dialog__title { color: #e6eefc; font-weight: 600; }
- ::v-deep .el-dialog__body { background: #0b254a; padding: 18px 22px; }
- ::v-deep .el-dialog__footer{
- background: #0b254a; border-top: 1px solid #364a64;
- }
- /* 内容容器 */
- .basic-info {
- border: 1px solid #2c3f59;
- border-radius: 8px;
- background: rgba(12, 33, 66, 0.6);
- box-shadow: inset 0 0 0 1px rgba(255,255,255,0.02);
- }
- /* 顶部条:密级与状态 */
- .top-line{
- display:flex; gap:10px; align-items:center;
- padding:12px 14px; border-bottom:1px dashed #2c3f59;
- }
- .chip{
- display:inline-block; padding:4px 10px; border-radius:999px;
- color:#fff; font-size:12px; letter-spacing:0.5px;
- }
- .chip.primary{ background:#3475b5; } /* 秘密 */
- .chip.warning{ background:#b88230; } /* 机密 */
- .chip.danger{ background:#c45656; } /* 绝密 */
- .chip.neutral{ background:#6b7280; }
- .chip.soft{ opacity:.9; }
- .chip.success{ background:#1f9d55; }
- .chip.info{ background:#4b5563; }
- /* 分组标题与栅格 */
- .section { padding: 10px 14px 14px; }
- .section + .section { border-top: 1px dashed #2c3f59; }
- .section-title{
- font-size:13px; color:#9db2c9; margin-bottom:8px;
- position:relative; padding-left:10px;
- }
- .section-title::before{
- content:''; position:absolute; left:0; top:4px; bottom:4px; width:3px;
- background: linear-gradient(180deg, #66a3ff, #3a7bd5);
- border-radius:2px;
- }
- /* 双栏对齐的键值栅格 */
- .info-grid{
- display:grid;
- grid-template-columns: 1fr 1fr;
- gap: 10px 18px;
- }
- .kv{ display:grid; grid-template-columns: 120px 1fr; align-items:center; }
- .kv.span-2{ grid-column: 1 / span 2; }
- .kv-label{ color:#8aa0bb; font-size:13px; justify-self:start; }
- .kv-value{
- color:#e7eef8; font-size:13px; line-height:1.6;
- background: rgba(0,0,0,0.12);
- border: 1px solid rgba(255,255,255,0.06);
- padding: 6px 10px; border-radius: 6px;
- }
- /* 任务卡片 */
- .task-select-section { margin-top: 20px; }
- .section-desc { font-size: 13px; color: #94a3b8; margin-bottom: 14px; }
- .task-card {
- background: #09264c;
- border: 1px solid #334155;
- border-radius: 8px;
- padding: 16px;
- color: #e2e8f0;
- transition: all 0.25s ease;
- display: flex; flex-direction: column; justify-content: space-between;
- height: 100%;
- }
- .task-card:hover {
- border-color: #3b82f6;
- box-shadow: 0 4px 12px rgba(0,0,0,0.5);
- transform: translateY(-2px);
- cursor: pointer;
- }
- .task-card--active {
- border: 2px solid #3b82f6;
- box-shadow: 0 0 10px rgba(59,130,246,0.7);
- }
- .task-title { height:45px;font-size: 15px; font-weight: 600; color: #fff; }
- .task-info { font-size: 13px; line-height: 1.6; margin-bottom: 12px; }
- .task-btn { width: 100%; font-weight: 600; border-radius: 6px; }
- /* 总体方案卡片(单选) */
- .plan-select-section { margin-top: 10px; }
- .plan-select-header {
- display:flex; align-items:center; justify-content: space-between; margin-bottom: 6px;
- }
- .plan-tools { display:flex; align-items:center; gap:10px; }
- .tool-label { color:#9db2c9; font-size:12px; margin-right:4px; }
- .plan-card {
- background: #0f1f38;
- border: 1px solid #2b3b55;
- border-radius: 8px;
- padding: 14px;
- color: #e2e8f0;
- transition: all .2s ease;
- height: 100%;
- }
- .plan-card:hover { border-color:#3b82f6; transform: translateY(-2px); cursor: pointer; }
- .plan-card--selected { border: 2px solid #3b82f6; box-shadow: 0 0 10px rgba(59,130,246,.5); }
- .plan-card__header { display:flex; align-items:center; justify-content: space-between; margin-bottom: 8px; }
- .plan-card__title { font-weight: 600; }
- .plan-card__check { font-size: 16px; }
- .plan-card__meta { display:flex; gap:12px; font-size:12px; color:#9db2c9; margin-bottom:8px; }
- .plan-card__desc { font-size: 12px; color:#cbd5e1; margin-bottom:10px; line-height: 1.7; }
- .plan-card__footer { display:flex; gap:8px; align-items:center; flex-wrap: wrap; }
- .selected-summary { margin-top: 10px; }
- </style>
|