compile copy.vue 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521
  1. <template>
  2. <div class="global-variable">
  3. <div class="parcel">
  4. <div class="controlling">
  5. <div class="hade">
  6. <p>
  7. 执行器组名称:<el-input v-model="zxqName" size="small"></el-input>
  8. </p>
  9. <el-button size="small" type="text" @click="addGroup"
  10. >添加执行器</el-button
  11. >
  12. </div>
  13. <div
  14. class="group"
  15. v-for="(group, groupIndex) in groups"
  16. :key="groupIndex"
  17. @click="changeCurrentGroup(groupIndex)"
  18. >
  19. <p class="SP1">
  20. <span>
  21. 执行器{{ groupIndex + 1 }}
  22. <el-input
  23. style="margin: 0 10px"
  24. size="small"
  25. v-model="group.inputValue"
  26. ></el-input>
  27. <el-button size="small" type="text" @click="dialogVisible = true">
  28. 上传附件
  29. </el-button>
  30. </span>
  31. </p>
  32. <div
  33. v-for="(table, tableIndex) in group.tables"
  34. :key="tableIndex"
  35. class="table-container"
  36. >
  37. <div>
  38. <el-button
  39. size="small"
  40. type="text"
  41. @click="ondel(groupIndex, tableIndex)"
  42. >
  43. 删除
  44. </el-button>
  45. </div>
  46. <el-table
  47. :data="table.data"
  48. border
  49. style="width: 100%"
  50. tooltip-effect="dark"
  51. ref="multipleTable"
  52. @selection-change="
  53. handleSelectionChange($event, groupIndex, tableIndex)
  54. "
  55. >
  56. <el-table-column type="selection" width="55"> </el-table-column>
  57. <el-table-column
  58. v-for="(key, colIndex) in table.columnKeys"
  59. :key="colIndex"
  60. :label="'Item ' + (parseInt(key) + 1)"
  61. :prop="key.toString()"
  62. ></el-table-column>
  63. </el-table>
  64. </div>
  65. </div>
  66. </div>
  67. <div class="database">
  68. <el-tabs type="border-card">
  69. <!-- 动态生成标签页 -->
  70. <el-tab-pane
  71. v-for="(group, groupIndex) in groups"
  72. :key="groupIndex"
  73. :label="'执行器组 ' + (groupIndex + 1)"
  74. >
  75. <div class="pair">
  76. <p v-for="(item, index) in modelList" :key="index">
  77. <span>{{ item.name }}</span>
  78. <el-select
  79. size="small"
  80. v-model="item.val"
  81. multiple
  82. collapse-tags
  83. placeholder="请选择"
  84. >
  85. <el-option
  86. v-for="item in selectoptions"
  87. :key="item"
  88. :label="item"
  89. :value="item"
  90. >
  91. </el-option>
  92. </el-select>
  93. </p>
  94. </div>
  95. <div class="combination">
  96. <p>添加数据字段</p>
  97. <div class="search">
  98. <el-input size="small" v-model="field"></el-input>
  99. <el-button size="small" type="text" @click="newVisible = true"
  100. >自定义</el-button
  101. >
  102. </div>
  103. <el-checkbox-group v-model="checkList" @change="duoxuan" class="repetition">
  104. <el-checkbox
  105. v-for="(item, index) in checkOptions"
  106. :key="index"
  107. :label="item"
  108. >
  109. {{ item }}
  110. </el-checkbox>
  111. </el-checkbox-group>
  112. </div>
  113. </el-tab-pane>
  114. </el-tabs>
  115. <el-button class="fixed-button" type="primary" > 保存 </el-button>
  116. </div>
  117. <!-- 弹窗 -->
  118. <el-dialog
  119. title="上传"
  120. :visible.sync="dialogVisible"
  121. width="20%"
  122. :before-close="handleClose"
  123. >
  124. <el-form ref="form" :model="form" label-width="100px">
  125. <el-form-item label="上传附件:">
  126. <el-upload
  127. class="upload-demo"
  128. action="https://jsonplaceholder.typicode.com/posts/"
  129. :on-preview="handlePreview"
  130. :on-remove="handleRemove"
  131. :before-remove="beforeRemove"
  132. multiple
  133. :limit="3"
  134. :on-exceed="handleExceed"
  135. :file-list="fileList"
  136. >
  137. <el-button @click="onUpload" size="small">上传</el-button>
  138. </el-upload>
  139. </el-form-item>
  140. <el-form-item label="是否有列名:">
  141. <el-radio-group v-model="form.resource">
  142. <el-radio label="是"></el-radio>
  143. <el-radio label="否"></el-radio>
  144. </el-radio-group>
  145. </el-form-item>
  146. <el-form-item label="列名所在行:">
  147. <el-input v-model="form.name"></el-input>
  148. </el-form-item>
  149. <el-form-item label="范围最小值:">
  150. <el-input v-model="form.name"></el-input>
  151. </el-form-item>
  152. <el-form-item label="范围最大值:">
  153. <el-input v-model="form.name"></el-input>
  154. </el-form-item>
  155. <el-form-item>
  156. <el-button type="primary" @click="onSubmit()">立即创建</el-button>
  157. </el-form-item>
  158. </el-form>
  159. </el-dialog>
  160. <el-dialog
  161. title="新增"
  162. :visible.sync="newVisible"
  163. width="15%"
  164. :before-close="handleClose"
  165. >
  166. <div>
  167. <i class="el-icon-plus" @click="addInput"></i>
  168. <i
  169. class="el-icon-minus"
  170. @click="removeInput(index)"
  171. v-if="inputList.length > 1"
  172. ></i>
  173. </div>
  174. <div
  175. v-for="(item, index) in inputList"
  176. :key="index"
  177. class="input-group"
  178. >
  179. <el-input
  180. size="small"
  181. v-model="item.value"
  182. placeholder="请输入"
  183. style="margin-bottom: 10px"
  184. ></el-input>
  185. <!-- 加号按钮 -->
  186. </div>
  187. <div style="display: flex; justify-content: center">
  188. <el-button size="small" type="primary" @click="confirm"
  189. >确 定</el-button
  190. >
  191. </div>
  192. </el-dialog>
  193. </div>
  194. </div>
  195. </template>
  196. <script>
  197. export default {
  198. data() {
  199. return {
  200. dialogVisible: false,
  201. newVisible: false,
  202. zxqName: "",
  203. tableData: [
  204. { 0: "2023-12-01", 1: "2023-12-02", 2: "2023-12-03", 3: "2023-12-04" },
  205. { 0: "2023-12-01", 1: "2023-12-02", 2: "2023-12-03", 3: "2023-12-04" },
  206. { 0: "2023-12-01", 1: "2023-12-02", 2: "2023-12-03", 3: "2023-12-04" },
  207. ],
  208. columnKeys: [],
  209. form: {},
  210. fileList: [],
  211. tables: [],
  212. groups: [
  213. {
  214. inputValue: "", // 输入框默认值
  215. tables: [
  216. {
  217. columnKeys: ["0", "1", "2", "3"], // 默认的列
  218. data: [
  219. {
  220. 0: "2023-12-01",
  221. 1: "2023-12-02",
  222. 2: "2023-12-03",
  223. 3: "2023-12-04",
  224. },
  225. {
  226. 0: "2023-12-05",
  227. 1: "2023-12-06",
  228. 2: "2023-12-07",
  229. 3: "2023-12-08",
  230. },
  231. {
  232. 0: "2023-12-09",
  233. 1: "2023-12-10",
  234. 2: "2023-12-11",
  235. 3: "2023-12-12",
  236. },
  237. ],
  238. },
  239. ],
  240. },
  241. ],
  242. currentGroupIndex: 0, // 当前操作的执行器索引
  243. selectoptions: [],
  244. selectvalue: [],
  245. field: "",
  246. checkList: [],
  247. multipleSelection: [],
  248. checkOptions: [], // 循环的选项
  249. modelList: [
  250. { name: "模板1", val: [] },
  251. { name: "模板2", val: [] },
  252. ],
  253. inputList: [
  254. { value: "" }, // 默认有一个输入框
  255. ],
  256. };
  257. },
  258. watch: {
  259. // 监听 checkList 数组的变化,并更新 selectOptions
  260. // checkList(newValue) {
  261. // this.selectOptions = [...newValue]; // 将选中的复选框值复制到 selectOptions
  262. // },
  263. },
  264. mounted() {
  265. if (this.tableData.length > 0) {
  266. this.columnKeys = Object.keys(this.tableData[0]); // 动态提取列名
  267. }
  268. },
  269. methods: {
  270. // 获取默认表格模板
  271. getDefaultTable() {
  272. return {
  273. columnKeys: ["0", "1", "2", "3"],
  274. data: [
  275. {
  276. 0: "2023-12-01",
  277. 1: "2023-12-02",
  278. 2: "2023-12-03",
  279. 3: "2023-12-04",
  280. },
  281. {
  282. 0: "2023-12-05",
  283. 1: "2023-12-06",
  284. 2: "2023-12-07",
  285. 3: "2023-12-08",
  286. },
  287. {
  288. 0: "2023-12-09",
  289. 1: "2023-12-10",
  290. 2: "2023-12-11",
  291. 3: "2023-12-12",
  292. },
  293. ],
  294. };
  295. },
  296. // 上传操作
  297. onUpload() {
  298. this.dialogVisible = true;
  299. },
  300. // 仅在当前 group 下新增表格
  301. onSubmit() {
  302. const newTable = {
  303. columnKeys: ["0", "1", "2", "3"], // 默认列
  304. data: [
  305. {
  306. 0: "2023-12-01",
  307. 1: "2023-12-02",
  308. 2: "2023-12-03",
  309. 3: "2023-12-04",
  310. },
  311. {
  312. 0: "2023-12-01",
  313. 1: "2023-12-02",
  314. 2: "2023-12-03",
  315. 3: "2023-12-04",
  316. },
  317. {
  318. 0: "2023-12-01",
  319. 1: "2023-12-02",
  320. 2: "2023-12-03",
  321. 3: "2023-12-04",
  322. },
  323. ],
  324. };
  325. // 只在当前 group 的 tables 数组中新增表格
  326. this.groups[this.currentGroupIndex].tables.push(newTable);
  327. console.log("新增后的 groups 数据:", this.groups);
  328. this.dialogVisible = false;
  329. },
  330. // 切换当前 group
  331. changeCurrentGroup(groupIndex) {
  332. this.currentGroupIndex = groupIndex;
  333. },
  334. // 删除表格
  335. ondel(groupIndex, tableIndex) {
  336. this.groups[groupIndex].tables.splice(tableIndex, 1);
  337. },
  338. // 新增执行器组
  339. addGroup() {
  340. this.groups.push({
  341. inputValue: "",
  342. tables: [this.getDefaultTable()],
  343. });
  344. },
  345. handleSelectionChange(val, groupIndex, tableIndex) {
  346. const currentTable = this.groups[groupIndex].tables[tableIndex]; // 获取当前表格
  347. // 提取每行所有字段的值(不管字段名是什么)
  348. currentTable.selectedValues = val.flatMap((item) => Object.values(item)); // 获取每一行的所有值
  349. // 计算新增和移除的选项
  350. const added = currentTable.selectedValues.filter(
  351. (item) =>
  352. !this.checkOptions.includes(item) &&
  353. !this.inputList.some((input) => input.value === item) // 排除掉 confirm 添加的值
  354. );
  355. const removed = this.checkOptions.filter(
  356. (item) =>
  357. !currentTable.selectedValues.includes(item) &&
  358. !this.inputList.some((input) => input.value === item) // 排除掉 confirm 添加的值
  359. );
  360. // 更新 checkOptions
  361. if (added.length) {
  362. this.checkOptions.push(...added);
  363. }
  364. if (removed.length) {
  365. this.checkOptions = this.checkOptions.filter(
  366. (item) => !removed.includes(item)
  367. );
  368. }
  369. // 重新计算 checkOptions,包含所有选中行的所有字段值
  370. this.checkOptions = this.groups
  371. .flatMap((group) => group.tables) // 遍历所有组的所有表格
  372. .flatMap((table) => table.selectedValues || []); // 合并所有表格的选中行的字段值
  373. },
  374. duoxuan(val) {
  375. console.log(val);
  376. this.selectoptions = val;
  377. },
  378. addInput() {
  379. this.$set(this.inputList, this.inputList.length, { value: "" });
  380. },
  381. // 删除指定的输入框
  382. removeInput(index) {
  383. if (this.inputList.length > 1) {
  384. this.inputList.splice(index, 1); // 从 inputList 中删除指定的输入框
  385. }
  386. },
  387. confirm() {
  388. this.newVisible = false;
  389. this.inputList.forEach((item) => {
  390. if (item.value) {
  391. // 如果有值才添加
  392. this.checkOptions.push(item.value);
  393. }
  394. });
  395. console.log(this.selectoptions);
  396. },
  397. handleClose(done) {
  398. done();
  399. },
  400. handleRemove(file, fileList) {
  401. console.log(file, fileList);
  402. },
  403. handlePreview(file) {
  404. console.log(file);
  405. },
  406. handleExceed(files, fileList) {
  407. this.$message.warning(
  408. `当前限制选择 3 个文件,本次选择了 ${files.length} 个文件,共选择了 ${
  409. files.length + fileList.length
  410. } 个文件`
  411. );
  412. },
  413. beforeRemove(file, fileList) {
  414. return this.$confirm(`确定移除 ${file.name}?`);
  415. },
  416. },
  417. };
  418. </script>
  419. <style lang="scss" scoped>
  420. .parcel {
  421. display: flex;
  422. justify-content: space-between;
  423. .controlling {
  424. .hade {
  425. display: flex;
  426. justify-content: space-between;
  427. }
  428. .SP1 {
  429. display: flex;
  430. justify-content: space-between;
  431. margin: 10px 0;
  432. }
  433. width: 75.5%;
  434. height: 760px;
  435. overflow: hidden;
  436. overflow-y: auto;
  437. // border: 1px solid #aaaaaa;
  438. padding: 10px;
  439. }
  440. .database {
  441. width: 24%;
  442. // border: 1px solid #aaaaaa;
  443. }
  444. }
  445. .el-input {
  446. width: 200px;
  447. }
  448. .pair {
  449. height: 350px;
  450. overflow: hidden;
  451. overflow: auto;
  452. p {
  453. margin-bottom: 10px;
  454. display: flex;
  455. span {
  456. display: inline-block;
  457. width: 150px;
  458. }
  459. .el-select {
  460. width: 180px;
  461. }
  462. }
  463. }
  464. .pair::-webkit-scrollbar {
  465. display: none;
  466. }
  467. .repetition {
  468. height: 240px;
  469. overflow: hidden;
  470. overflow: auto;
  471. }
  472. .repetition::-webkit-scrollbar {
  473. display: none;
  474. }
  475. .fixed-button {
  476. width: 100%;
  477. }
  478. .el-checkbox {
  479. margin-right: 10px;
  480. margin-bottom: 5px;
  481. }
  482. </style>