editor.vue 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790
  1. <template>
  2. <div class="editor">
  3. <draggable
  4. v-model="comList"
  5. @add="onAdd"
  6. @update="onDragEnd"
  7. @end="onDragComplete"
  8. group="itxst"
  9. animation="300"
  10. :style="draggableStyle"
  11. handle=".drag-handle"
  12. :scroll="true"
  13. :scrollSensitivity="100"
  14. :scrollSpeed="20"
  15. >
  16. <transition-group style="display: block; min-height: 100vh">
  17. <template v-for="(it, index) in comList">
  18. <div
  19. :key="index"
  20. class="layers"
  21. :class="comIndex == index ? 'active-layer' : ''"
  22. >
  23. <!-- <div class="drag-handle" draggable>
  24. <img src="@/icons/svg/drag.svg" style="width: 20px;" icon-class="drag" />
  25. </div> -->
  26. <!-- :options="categoryList":props="props" -->
  27. <!-- <div style="padding: 10px 0">
  28. <el-form label-position="left" class="inline-form">
  29. <el-row :gutter="24" style="margin-left: 0; margin-right: 0">
  30. <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
  31. <el-form-item
  32. >
  33. <div class="btn-save">
  34. <el-tooltip
  35. v-if="type !== 'document'"
  36. class="item"
  37. effect="dark"
  38. content="保存模块"
  39. placement="top"
  40. >
  41. <el-button
  42. @click="onSaveTemplate(it)"
  43. icon="el-icon-document-add"
  44. circle
  45. >
  46. </el-button>
  47. </el-tooltip>
  48. <el-button
  49. circle
  50. v-if="it.isEdit !== 1"
  51. @click="onEdit(index, 1)"
  52. icon="el-icon-edit"
  53. >
  54. </el-button>
  55. <el-button
  56. circle
  57. @click="onEdit(index, 2)"
  58. icon="el-icon-view"
  59. v-else
  60. >
  61. </el-button>
  62. <el-tooltip
  63. class="item"
  64. effect="dark"
  65. content="删除"
  66. placement="top"
  67. >
  68. <el-button
  69. circle
  70. @click="onRemove(index)"
  71. icon="el-icon-delete"
  72. ></el-button
  73. >
  74. </el-tooltip>
  75. </div>
  76. </el-form-item>
  77. </el-col>
  78. </el-row>
  79. </el-form>
  80. </div> -->
  81. <div class="main" @click="onSetActive(index)">
  82. <component
  83. :is="it.type"
  84. :ref="`component_${index}`"
  85. :com="it"
  86. :coms="comList"
  87. :currentIndex="index"
  88. :isAdmin="isAdmin"
  89. :insertCmd="insertCmd"
  90. @onUpdate="onUpdate"
  91. @onUpdateAttr="onUpdateAttr"
  92. @onUpdata="onUpdata"
  93. @onUpdateProdAttr="onUpdateProdAttr"
  94. @updateComContent="handleComContentUpdate"
  95. :isEdit="it.isEdit"
  96. />
  97. </div>
  98. <!-- <div class="label">
  99. {{ it.name }}
  100. <div class="del">
  101. <svg-icon
  102. @click="onEdit(index, 1)"
  103. v-if="it.isEdit !== 1"
  104. icon-class="edit"
  105. style="color: #fff; margin-right: 10px"
  106. />
  107. <svg-icon
  108. @click="onEdit(index, 2)"
  109. v-else
  110. icon-class="view"
  111. style="color: #fff; margin-right: 10px"
  112. />
  113. <svg-icon
  114. @click="onRemove(index)"
  115. icon-class="delete"
  116. style="color: #fff; margin-left: 10px"
  117. />
  118. </div>
  119. </div> -->
  120. </div>
  121. </template>
  122. <template v-if="comList.length <= 0">
  123. <div class="editor-empty" :key="-1">
  124. <el-empty description="请拖放组件至当前页面" />
  125. </div>
  126. </template>
  127. </transition-group>
  128. </draggable>
  129. </div>
  130. </template>
  131. <script>
  132. import draggable from "vuedraggable";
  133. import Table from "./components/Table";
  134. import TextArea from "./components/TextArea";
  135. import Empty from "./components/Empty";
  136. import {
  137. getAllList,
  138. createTemplate,
  139. updateTemplate,
  140. treeCategory,
  141. } from "@/api/template";
  142. export default {
  143. name: "editor",
  144. emits: [
  145. "onSetActiveIndex",
  146. "onDelete",
  147. "onInsert",
  148. "onLoadArticle",
  149. "onRebuild",
  150. "onSetComs",
  151. ],
  152. components: {
  153. Table,
  154. TextArea,
  155. draggable,
  156. Empty,
  157. },
  158. props: {
  159. coms: {
  160. type: Array,
  161. default: null,
  162. },
  163. comIndex: {
  164. type: Number,
  165. default: 0,
  166. },
  167. templateCate: {
  168. type: Array,
  169. default: () => {
  170. return [];
  171. },
  172. },
  173. insertCmd: {
  174. type: Object,
  175. default: null,
  176. },
  177. isAdmin: {
  178. type: Number,
  179. default: 2,
  180. },
  181. },
  182. watch: {
  183. coms: {
  184. async handler(val) {
  185. // 如果正在保存,则跳过处理
  186. if (this.isSaving || !val) return;
  187. try {
  188. // 处理拖拽数据,确保属性正确转换
  189. const processedComs = val.map((item) => {
  190. // 首先创建基础对象
  191. const processedItem = {
  192. ...item,
  193. // 确保 attrs 是数组
  194. dcb_attrs: Array.isArray(item.attrs)
  195. ? item.attrs
  196. : JSON.parse(item.attrs || "[]"),
  197. // 同步最新内容,优先使用当前显示的内容
  198. content: item.content || item.dcb_nr || "",
  199. dcb_nr: item.content || item.dcb_nr || "",
  200. // 确保 type 使用 dcb_type
  201. type: item.dcb_type || item.type,
  202. // 确保 name 使用 dcb_name
  203. name: item.dcb_name || item.name,
  204. };
  205. // 确保 content 和 dcb_nr 同步
  206. if (processedItem.content !== processedItem.dcb_nr) {
  207. processedItem.dcb_nr = processedItem.content;
  208. }
  209. return processedItem;
  210. });
  211. console.log("editor_coms:",processedComs);
  212. this.comList = processedComs;
  213. this.$emit("onSetComs:", this.comList);
  214. } catch (error) {
  215. console.error('处理组件数据时出错:', error);
  216. }
  217. },
  218. immediate: true,
  219. deep: true,
  220. },
  221. comIndex: {
  222. handler(val) {
  223. if (val <= 0) return;
  224. this.comList = this.comList.map((it) => {
  225. it.isEdit = 2;
  226. it.selDisabled = true;
  227. it.valDisabled = true;
  228. if (
  229. typeof it.category_id === "string" &&
  230. it.category_id.includes(" ")
  231. ) {
  232. it.category_id = it.category_id.split(" ");
  233. } else if (!Array.isArray(it.category_id)) {
  234. // 如果不是数组,将其转换为包含单个元素的数组
  235. it.category_id = [it.category_id].filter(Boolean);
  236. }
  237. return it;
  238. });
  239. },
  240. immediate: true, //立即执行
  241. deep: true,
  242. },
  243. },
  244. data() {
  245. return {
  246. showEditor: false,
  247. operation: "",
  248. id: 0,
  249. comList: [],
  250. categoryList: [],
  251. props: {
  252. value: "id",
  253. label: "name",
  254. children: "children",
  255. checkStrictly: true,
  256. },
  257. saveAs: false,
  258. draggableStyle: {
  259. width: "100%",
  260. overflowY: "auto",
  261. },
  262. type: "",
  263. isSaving: false, // 添加保存状态标志
  264. };
  265. },
  266. mounted() {
  267. console.log(this.$store.state);
  268. this.initCategoryList();
  269. this.type = this.$route.query.type;
  270. this.templateId = this.$route.query.templateId;
  271. this.$nextTick(() => {
  272. this.updateDirectoryNumbers(); // 初始化目录序号
  273. });
  274. },
  275. methods: {
  276. /* 拖拽 修改目录序号*/
  277. onDragComplete() {
  278. console.log("拖动结束");
  279. this.$nextTick(() => {
  280. this.updateDirectoryNumbers();
  281. this.$emit("onRebuild", this.comList);
  282. });
  283. },
  284. updateDirectoryNumbers() {
  285. let levelCounters = {};
  286. this.comList.forEach((module, moduleIndex) => {
  287. if (module.attrs) {
  288. module.attrs.forEach((attr) => {
  289. if (attr.type === "Directory") {
  290. const newNumber = this.generateNumberedContent(
  291. moduleIndex,
  292. attr.level,
  293. levelCounters
  294. );
  295. // 只更新 number 属性,完全不触及 content
  296. if (!attr.hasOwnProperty("number")) {
  297. this.$set(attr, "number", newNumber);
  298. } else {
  299. attr.number = newNumber;
  300. }
  301. }
  302. });
  303. }
  304. });
  305. },
  306. generateNumberedContent(moduleIndex, level, levelCounters) {
  307. return this.generateLevelPrefix(moduleIndex, level, levelCounters);
  308. },
  309. generateLevelPrefix(moduleIndex, level, levelCounters) {
  310. let prefix = [];
  311. for (let i = 1; i <= level; i++) {
  312. if (i === 1) {
  313. prefix.push(moduleIndex + 1);
  314. } else {
  315. if (!levelCounters[i]) {
  316. levelCounters[i] = 1;
  317. } else {
  318. levelCounters[i]++;
  319. }
  320. prefix.push(levelCounters[i]);
  321. }
  322. }
  323. return prefix.join(".");
  324. },
  325. carefulCopy(items) {
  326. return items.map((item) => {
  327. const newItem = { ...item };
  328. // 深拷贝 attrs 数组
  329. if (Array.isArray(newItem.attrs)) {
  330. newItem.attrs = newItem.attrs.map((attr) => ({ ...attr }));
  331. }
  332. // 深拷贝 content,如果它是一个对象或数组
  333. if (typeof newItem.content === "object" && newItem.content !== null) {
  334. newItem.content = JSON.parse(JSON.stringify(newItem.content));
  335. }
  336. // 处理特殊的 type,如 Table
  337. if (newItem.type === "Table") {
  338. newItem.tableHeader = [...newItem.tableHeader];
  339. newItem.tableData = newItem.tableData.map((row) => ({ ...row }));
  340. }
  341. // 保留其他属性的引用
  342. return newItem;
  343. });
  344. },
  345. handleComContentUpdate(index, updatedCom) {
  346. // 更新本地的 coms 数组
  347. this.$set(this.coms, index, updatedCom);
  348. // 触发父组件的更新
  349. this.$emit("onRebuild", this.coms);
  350. },
  351. showCategoryName(item) {
  352. return (
  353. this.type == "module" &&
  354. /* this.$store.state.user.roleInfo.id == 1 && */
  355. !item.valDisabled
  356. );
  357. },
  358. enableName(item) {
  359. item.valDisabled = false;
  360. this.$forceUpdate();
  361. },
  362. showCategorySelect(item) {
  363. return (
  364. this.type === "module" &&
  365. /* this.$store.state.user.roleInfo.id === 1 && */
  366. !item.selDisabled
  367. );
  368. },
  369. /* 选择分类 */
  370. enableSelect(item) {
  371. item.selDisabled = true;
  372. console.log(item);
  373. this.$forceUpdate();
  374. },
  375. /* 获取分类名称 */
  376. getCategory(item) {
  377. const findCategory = (list, id) => {
  378. for (const el of list) {
  379. if (el.id === id) {
  380. return el.name;
  381. }
  382. if (el.children) {
  383. const name = findCategory(el.children, id);
  384. if (name) {
  385. return name;
  386. }
  387. }
  388. }
  389. return null;
  390. };
  391. return findCategory(this.categoryList, item) || "请选择分类";
  392. /* return (
  393. this.categoryList.find((el) => el.id === item)?.name || "请选择分类"
  394. ); */
  395. },
  396. onSaveAs(e) {
  397. this.saveAs = true;
  398. this.onSaveTemplate(e);
  399. },
  400. /* 保存模块 */
  401. onSaveTemplate(e) {
  402. let _this = this;
  403. // 创建一个新对象来存储过滤后的数据
  404. let data = {};
  405. // 遍历原始对象,只保留 dcb_ 开头的属性
  406. Object.keys(e).forEach((key) => {
  407. if (key.startsWith("dcb_")) {
  408. data[key] = e[key];
  409. }
  410. });
  411. // 特殊字段映射
  412. data.dcb_nr = e.content;
  413. data.dcb_attrs = JSON.stringify(e.attrs);
  414. data.dcb_type = e.type;
  415. data.dcb_name = e.name; // 如果需要保存名称
  416. // 处理分类ID
  417. if (Array.isArray(e.category_id)) {
  418. data.category_id = e.category_id[e.category_id.length - 1];
  419. } else {
  420. data.category_id = e.category_id;
  421. }
  422. data.status = 5;
  423. // 根据是否存在 dcb_id 决定创建还是更新
  424. if (e.dcb_id == undefined || this.saveAs) {
  425. createTemplate(data).then((res) => {
  426. if (res.code != 200) return;
  427. e.id = res.data;
  428. _this.$alert("模块信息保存成功");
  429. _this.$emit("onRefresh");
  430. this.saveAs = false;
  431. e.selDisabled = false;
  432. e.valDisabled = false;
  433. this.$forceUpdate();
  434. });
  435. } else {
  436. updateTemplate(data).then((res) => {
  437. if (res.code != 200) return;
  438. _this.$alert("模块信息更新成功");
  439. _this.$emit("onRefresh");
  440. e.selDisabled = false;
  441. e.valDisabled = false;
  442. this.$forceUpdate();
  443. });
  444. }
  445. },
  446. /* 获取模块分类 */
  447. //获取模板分类信息
  448. async initCategoryList() {
  449. let _this = this;
  450. let res = await treeCategory(); //await getAllList();
  451. console.log(res);
  452. this.categoryList =
  453. res.data; /* //this.processDataForCascader(res.data); */
  454. },
  455. processDataForCascader(data) {
  456. console.log("Raw data:", data); // 调试原始数据
  457. const idMap = new Map();
  458. const rootItems = [];
  459. // First pass: create a map of all items
  460. data.forEach((item) => {
  461. const processedItem = { ...item, children: [] };
  462. idMap.set(item.id, processedItem);
  463. });
  464. // Second pass: build the tree structure
  465. data.forEach((item) => {
  466. if (item.parent_id === "0" || item.parent_id === 0) {
  467. rootItems.push(idMap.get(item.id));
  468. } else {
  469. const parent = idMap.get(parseInt(item.parent_id));
  470. if (parent) {
  471. parent.children.push(idMap.get(item.id));
  472. } else {
  473. console.warn(
  474. `Parent with id ${item.parent_id} not found for item:`,
  475. item
  476. );
  477. rootItems.push(idMap.get(item.id)); // 如果找不到父项,作为根项添加
  478. }
  479. }
  480. });
  481. console.log("Processed data:", rootItems); // 调试处理后的数据
  482. return rootItems;
  483. },
  484. onChangeCategory(item, value) {
  485. const selectedId = value[value.length - 1];
  486. item.category_id = selectedId;
  487. // You can now use the selected ID as needed
  488. },
  489. //更新产品属性
  490. onUpdateProdAttr(comIndex, attrIndex, data) {
  491. this.comList[comIndex].attrs[attrIndex].content = data;
  492. let attrName = this.comList[comIndex].attrs[attrIndex].attrs.name;
  493. let attrType = this.comList[comIndex].attrs[attrIndex].attrs.type;
  494. for (var i = 0; i < this.comList.length; i++) {
  495. for (var j = 0; j < this.comList[i].attrs.length; j++) {
  496. if (this.comList[i].attrs[j].type == "ProductAttr") {
  497. if (
  498. this.comList[i].attrs[j].attrs.name == attrName &&
  499. this.comList[i].attrs[j].attrs.type == attrType
  500. ) {
  501. this.comList[i].attrs[j].content = data;
  502. }
  503. }
  504. }
  505. }
  506. this.$emit("onRebuild", this.comList);
  507. },
  508. onUpdateAttr(comIndex, attrIndex, data) {
  509. console.log(comIndex, attrIndex, data);
  510. this.comList[comIndex].attrs[attrIndex].content = data;
  511. let dataType = this.comList[comIndex].attrs[attrIndex].type;
  512. let dataId = this.comList[comIndex].attrs[attrIndex].data;
  513. for (var i = 0; i < this.comList.length; i++) {
  514. for (var j = 0; j < this.comList[i].attrs.length; j++) {
  515. if (
  516. this.comList[i].attrs[j].type == dataType &&
  517. this.comList[i].attrs[j].id == dataId
  518. ) {
  519. this.comList[i].attrs[j].content = data;
  520. }
  521. }
  522. }
  523. this.$emit("onRebuild", this.comList);
  524. },
  525. /* 修改单个值 */
  526. onUpdata(comIndex, attrIndex, attrId, data, type) {
  527. let _this = this;
  528. let com = _this.coms[comIndex];
  529. if (type === "variableNull") {
  530. // 只更新特定的 variableNull 属性
  531. if (
  532. com &&
  533. com.attrs &&
  534. com.attrs[attrIndex] &&
  535. com.attrs[attrIndex].id === attrId
  536. ) {
  537. this.$set(com.attrs[attrIndex], "content", data);
  538. }
  539. } else {
  540. // 原有的逻辑,更新所有相同类型的属性
  541. let dataType = com.attrs[attrIndex].type;
  542. for (var i = 0; i < _this.coms.length; i++) {
  543. for (var j = 0; j < _this.coms[i].attrs.length; j++) {
  544. if (
  545. _this.coms[i].attrs[j].type == dataType &&
  546. _this.coms[i].attrs[j].id == attrId
  547. ) {
  548. _this.coms[i].attrs[j].content = data;
  549. }
  550. }
  551. }
  552. }
  553. _this.$emit("onRebuild", _this.coms);
  554. },
  555. onRemove(index) {
  556. this.$confirm("此操作将删除该模块, 是否继续?", "提示", {
  557. confirmButtonText: "确定",
  558. cancelButtonText: "取消",
  559. type: "warning",
  560. })
  561. .then(() => {
  562. this.$emit("onDelete", index);
  563. })
  564. .catch(() => {
  565. this.$message({
  566. type: "info",
  567. message: "已取消删除",
  568. });
  569. });
  570. },
  571. async onEdit(e, state) {
  572. try {
  573. // 如果是切换到预览模式
  574. if (state === 2) {
  575. this.isSaving = true;
  576. // 获取组件引用并添加详细日志
  577. const componentRef = this.$refs[`component_${e}`];
  578. console.log("componentRef:", componentRef);
  579. // 检查组件引用是否正确
  580. if (!componentRef || !componentRef[0]) {
  581. console.error(`组件引用获取失败: component_${e}`);
  582. throw new Error('组件引用不存在');
  583. }
  584. // 检查 save 方法是否存在
  585. if (typeof componentRef[0].save !== 'function') {
  586. console.error('组件没有 save 方法:', componentRef[0]);
  587. throw new Error('组件 save 方法不存在');
  588. }
  589. try {
  590. // 1. 等待组件内容保存
  591. console.log('开始保存组件内容...');
  592. await componentRef[0].save();
  593. console.log('组件内容保存完成');
  594. // 2. 等待父组件的更新完成
  595. console.log('开始更新父组件...');
  596. await new Promise(resolve => {
  597. this.$nextTick(async () => {
  598. await this.$emit("onRebuild", this.comList);
  599. resolve();
  600. });
  601. });
  602. console.log('父组件更新完成');
  603. // 3. 更新编辑状态
  604. console.log('更新编辑状态...');
  605. this.$set(this.comList[e], 'isEdit', 2);
  606. // 4. 确保视图更新完成
  607. await this.$nextTick();
  608. console.log('视图更新完成');
  609. } catch (error) {
  610. console.error('保存过程中出错:', error);
  611. this.$message.error('保存失败:' + error.message);
  612. throw error;
  613. }
  614. } else {
  615. // 编辑模式的处理...
  616. console.log('切换到编辑模式...');
  617. this.comList = this.comList.map((it, index) => {
  618. it.isEdit = 2;
  619. if (index === e && state === 1) {
  620. this.filterAttrs(it);
  621. }
  622. return it;
  623. });
  624. if (state === 1) {
  625. this.comList[e].isEdit = 1;
  626. this.onSetActive(e);
  627. }
  628. }
  629. // 触发重建
  630. await this.$emit("onRebuild", this.comList);
  631. console.log('重建完成');
  632. } catch (error) {
  633. console.error('切换模式失败:', error);
  634. this.$message.error('切换模式失败:' + error.message);
  635. } finally {
  636. this.isSaving = false;
  637. console.log('操作完成,isSaving 重置为 false');
  638. }
  639. },
  640. // 新增 filterAttrs 方法
  641. filterAttrs(item) {
  642. // 从 content 中提取所有 {{}} 包裹的 ID
  643. const contentIds = (item.dcb_nr.match(/{{([^}]+)}}/g) || []).map(
  644. (match) => match.slice(2, -2).trim()
  645. );
  646. // 过滤 attrs,只保留在 content 中出现的 ID
  647. item.attrs = item.attrs.filter((attr) => contentIds.includes(attr.id));
  648. },
  649. onAdd(e) {
  650. e.preventDefault();
  651. e.stopPropagation();
  652. this.$emit("onRebuild", this.comList);
  653. },
  654. onDragEnd(e) {
  655. e.preventDefault();
  656. e.stopPropagation();
  657. this.$emit("onRebuild", this.comList);
  658. },
  659. onUpdate(index, content) {
  660. let _this = this;
  661. this.coms[index].content = content;
  662. // 触发父组件的更新
  663. this.$emit("onRebuild", this.coms);
  664. },
  665. //激活当前层
  666. onSetActive(e) {
  667. this.$emit("onSetActiveIndex", e);
  668. },
  669. // 添加一个辅助方法来验证组件引用
  670. validateComponentRef(ref, index) {
  671. if (!ref) {
  672. throw new Error(`组件引用为空 (index: ${index})`);
  673. }
  674. if (!Array.isArray(ref)) {
  675. throw new Error(`组件引用不是数组 (index: ${index})`);
  676. }
  677. if (!ref[0]) {
  678. throw new Error(`组件引用数组为空 (index: ${index})`);
  679. }
  680. if (!ref[0].save) {
  681. throw new Error(`组件没有 save 方法 (index: ${index})`);
  682. }
  683. }
  684. },
  685. };
  686. </script>
  687. <style lang="scss">
  688. @import "./editor.scss";
  689. .layers {
  690. // margin-left: 26px;
  691. .drag-handle {
  692. position: absolute;
  693. top: 0;
  694. left: -27px;
  695. cursor: move;
  696. padding: 0 5px;
  697. display: flex;
  698. align-items: center;
  699. /* background-color: #f0f0f0; */
  700. &:hover {
  701. /* background-color: #e0e0e0; */
  702. }
  703. }
  704. .content-wrapper {
  705. flex-grow: 1;
  706. display: flex;
  707. flex-direction: column;
  708. }
  709. .main {
  710. flex-grow: 1;
  711. }
  712. }
  713. .inline-form {
  714. display: block;
  715. width: 100%;
  716. /* flex-wrap: wrap;
  717. gap: 10px; */
  718. }
  719. .inline-form .el-form-item {
  720. display: flex;
  721. align-items: center;
  722. margin-bottom: 0;
  723. flex: 1;
  724. min-width: 300px;
  725. }
  726. .inline-form .el-form-item__label {
  727. flex-shrink: 0;
  728. width: auto;
  729. padding-right: 12px;
  730. }
  731. .inline-form .el-form-item__content {
  732. flex-grow: 1;
  733. margin-left: 0 !important;
  734. }
  735. .input-item {
  736. width: 200px;
  737. }
  738. </style>