index.vue 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931
  1. <template>
  2. <div class="app-container">
  3. <el-card style="margin-bottom: 15px">
  4. <el-form ref="form" :model="form" label-width="100px" :rules="rules">
  5. <!-- <el-form-item label="数据库名称" prop="dataBaseName">
  6. <el-input v-model="form.dataBaseName" style="width: 600px;"></el-input>
  7. </el-form-item> -->
  8. <el-form-item label="数据表名称" prop="tableName">
  9. <el-input
  10. v-model="form.tableName"
  11. :disabled="isEdited"
  12. style="width: 600px"
  13. ></el-input>
  14. </el-form-item>
  15. <el-form-item label="表描述">
  16. <el-input v-model="form.tableComment" style="width: 600px"></el-input>
  17. </el-form-item>
  18. </el-form>
  19. </el-card>
  20. <el-card>
  21. <div class="titleitem">
  22. <span>数据表字段</span>
  23. </div>
  24. <el-form ref="tableform" :rules="tableform" :model="experienceDataForm">
  25. <el-table
  26. ref="dragTable"
  27. :data="experienceData"
  28. stripe
  29. row-key="tag"
  30. style="width: 100%"
  31. >
  32. <el-table-column
  33. type="index"
  34. label="序号"
  35. width="50"
  36. class-name="allowDrag"
  37. />
  38. <el-table-column prop="fieldName" label="字段名称" width="200">
  39. <template slot-scope="scope">
  40. <el-form-item
  41. :prop="'fieldName' + scope.$index"
  42. :name="'fieldName' + scope.$index"
  43. style="margin: 0px; padding: 0px"
  44. >
  45. <el-input
  46. v-model="scope.row.fieldName"
  47. @blur="fieldNameChange(scope.row)"
  48. ></el-input>
  49. </el-form-item>
  50. </template>
  51. </el-table-column>
  52. <el-table-column prop="fieldType" label="字段类型" width="200">
  53. <template slot-scope="scope">
  54. <el-form-item
  55. :prop="'fieldType' + scope.$index"
  56. :name="'fieldType' + scope.$index"
  57. style="margin: 0px; padding: 0px"
  58. >
  59. <el-select
  60. :disabled="!scope.row.fieldName"
  61. v-model="scope.row.fieldType"
  62. filterable
  63. @blur="selectBlur(scope)"
  64. @change="
  65. handleSelected(
  66. dataType.find(
  67. (item) => item.label === scope.row.fieldType
  68. ),
  69. scope,
  70. scope.$index,
  71. scope.row
  72. )
  73. "
  74. >
  75. <!-- <el-option v-for="item in list" :key="item" :label="item" :value="item">
  76. </el-option> -->
  77. <!--
  78. <el-option v-for="item in dict.type.mysql_data_type" :label="item.dictLabel" :value="item.dictValue">
  79. </el-option> -->
  80. <el-option
  81. v-for="item in dataType"
  82. :key="item.value"
  83. :label="item.label"
  84. :value="item.value"
  85. />
  86. </el-select>
  87. </el-form-item>
  88. </template>
  89. </el-table-column>
  90. <el-table-column prop="fieldLength" label="长度" width="200">
  91. <template slot-scope="scope">
  92. <el-form-item
  93. :prop="'fieldLength' + scope.$index"
  94. :name="'fieldLength' + scope.$index"
  95. style="margin: 0px; padding: 0px"
  96. >
  97. <!-- <el-input v-model="scope.row.fieldLength"-->
  98. <!-- :disabled="handleSelected(dict.type.mysql_data_type.find(item => item.label === scope.row.fieldType), scope)"></el-input>-->
  99. <el-input
  100. v-model="scope.row.fieldLength"
  101. @blur="fieldLengthChange(scope.$index, scope.row)"
  102. :disabled="changduclick(scope.$index) || !scope.row.fieldName"
  103. @input="
  104. scope.row.fieldLength = scope.row.fieldLength.replace(
  105. /^(0+)|[^\d]+/g,
  106. ''
  107. )
  108. "
  109. ></el-input>
  110. </el-form-item>
  111. </template>
  112. </el-table-column>
  113. <el-table-column prop="isNull" label="不是null" width="100">
  114. <template slot-scope="scope">
  115. <el-checkbox
  116. :disabled="!scope.row.fieldName"
  117. @change="isNullChange(scope.row)"
  118. v-model="scope.row.isNull"
  119. ></el-checkbox>
  120. </template>
  121. </el-table-column>
  122. <el-table-column prop="isPrimary" label="主键" width="100">
  123. <template slot-scope="scope">
  124. <el-checkbox
  125. :disabled="!scope.row.fieldName"
  126. v-model="scope.row.isPrimary"
  127. @change="hanleCheckbox(scope.$index, scope.row)"
  128. ></el-checkbox>
  129. </template>
  130. </el-table-column>
  131. <el-table-column prop="isAuto" label="自增" width="100">
  132. <template slot-scope="scope">
  133. <el-checkbox
  134. :disabled="!scope.row.fieldName"
  135. @change="isAutoChange(scope.row)"
  136. v-model="scope.row.isAuto"
  137. ></el-checkbox>
  138. </template>
  139. </el-table-column>
  140. <el-table-column prop="fieldDescription" label="字段描述" width="200">
  141. <template slot-scope="scope">
  142. <el-input
  143. :disabled="!scope.row.fieldName"
  144. @change="fieldDescriptionChange(scope.row)"
  145. v-model="scope.row.fieldDescription"
  146. ></el-input>
  147. </template>
  148. </el-table-column>
  149. <el-table-column prop="operate" label="操作">
  150. <template slot-scope="scope">
  151. <!-- <el-button size="mini" type="success" icon="el-icon-save"
  152. @click="handlesaveExperience(scope.$index, scope.row)">保存
  153. </el-button> -->
  154. <el-button
  155. size="mini"
  156. type="danger"
  157. icon="el-icon-delete"
  158. @click="handleDeleteExperience(scope.$index, scope.row)"
  159. >删除
  160. </el-button>
  161. </template>
  162. </el-table-column>
  163. </el-table>
  164. </el-form>
  165. <div>
  166. <el-button
  167. type="primary"
  168. icon="el-icon-plus"
  169. size="mini"
  170. @click="handleAddExperienceline"
  171. >新增字段
  172. </el-button>
  173. </div>
  174. </el-card>
  175. <div style="margin-top: 15px">
  176. <el-button v-if="!isEdited" @click="add" type="primary">添加</el-button>
  177. <el-button v-else @click="edit" type="primary">修改</el-button>
  178. </div>
  179. </div>
  180. </template>
  181. <script>
  182. import { createDatabase } from "@/api/datasheet/index";
  183. import { tableInfo, editTable } from "@/api/dataEngine/index";
  184. import { mapState } from "vuex";
  185. import { getDicts } from "@/api/system/dict/data";
  186. import Sortable from "sortablejs";
  187. import { v4 as uuidv4 } from "uuid";
  188. export default {
  189. name: "Datasheet",
  190. // dicts: [
  191. // "dm_data_type",
  192. // "mysql_data_type",
  193. // "sqlserver_data_type",
  194. // "oracle_data_type",
  195. // ],
  196. data() {
  197. return {
  198. sqlStringList: [],
  199. isEdited: false,
  200. testzidian: null,
  201. form: {
  202. dataBaseName: "",
  203. tableName: "",
  204. tableComment: "",
  205. },
  206. experienceDataForm: {},
  207. experienceData: [
  208. // {
  209. // fieldName: "",
  210. // fieldType: "",
  211. // fieldLength: undefined,
  212. // isNull: false,
  213. // isPrimary: false,
  214. // fieldDescription: "",
  215. // isAuto: false,
  216. // },
  217. ],
  218. rules: {
  219. dataBaseName: {
  220. validator: this.checkDataBaseName,
  221. trigger: "blur",
  222. },
  223. tableName: {
  224. validator: this.checkTableName,
  225. trigger: "blur",
  226. },
  227. },
  228. tableform: {
  229. // fieldName0: { required: true, message: '请输入字段名称', trigger: 'blur' },
  230. // fieldType0: { required: true, message: '请选择', trigger: 'change' },
  231. // fieldLength0: { required: true, message: '请输入', trigger: 'blur' },
  232. },
  233. list: ["int", "varchar"],
  234. dataType: [], //数据类型字典
  235. Inoputdisabled: [],
  236. // 需要指定长度
  237. mysqlAllowLength: ["char", "varchar", "numeric", "decimal"],
  238. modifySQLString: {
  239. modify: {},
  240. delete: {},
  241. addNew: {},
  242. },
  243. };
  244. },
  245. async created() {
  246. await this.getDict();
  247. if (this.$route.query.tableName) {
  248. this.isEdited = true;
  249. this.info();
  250. } else {
  251. Object.keys(this.form).forEach((item) => {
  252. this.form[item] = "";
  253. });
  254. this.experienceData = [];
  255. }
  256. },
  257. mounted() {
  258. this.initDragTable();
  259. },
  260. computed: {
  261. ...mapState({
  262. databaseName: (state) => state.user.dataSource.databaseName,
  263. databaseType: (state) => state.user.dataSource.databaseType,
  264. }),
  265. },
  266. watch: {
  267. experienceData: {
  268. handler(n, o) {
  269. // do something
  270. // this.experienceDataForm = {};
  271. let rulesAdd = {};
  272. this.experienceData.forEach((item, index) => {
  273. this.$set(
  274. this.experienceDataForm,
  275. "fieldName" + index,
  276. item.fieldName
  277. );
  278. this.$set(
  279. this.experienceDataForm,
  280. "fieldType" + index,
  281. item.fieldType
  282. );
  283. this.$set(
  284. this.experienceDataForm,
  285. "fieldLength" + index,
  286. item.fieldLength
  287. );
  288. // rulesAdd['' + index] = item.fieldName
  289. // rulesAdd['fieldType' + index] = item.fieldType
  290. // rulesAdd['fieldLength' + index] = item.fieldLength
  291. // this.experienceDataForm = {...rulesAdd}
  292. });
  293. },
  294. deep: true, // 深度监听父组件传过来对象变化
  295. immediate: true,
  296. },
  297. },
  298. methods: {
  299. /* 修改记录回调start */
  300. // 字段名称修改回调
  301. fieldNameChange(row) {
  302. if (!row.fieldName) return;
  303. if (this.databaseType == "mysql") {
  304. if (row.oldVal) {
  305. if (!this.modifySQLString.modify[row.oldVal.fieldName]) {
  306. this.modifySQLString.modify[row.oldVal.fieldName] = {};
  307. }
  308. //更改
  309. this.modifySQLString.modify[row.oldVal.fieldName].fieldName =
  310. this.mysqlMotifySQLString("fieldName", row);
  311. this.sqlStringList.push(this.mysqlMotifySQLString("fieldName", row));
  312. } else if (row.fieldType) {
  313. //新增
  314. this.modifySQLString.addNew[row.fieldName] =
  315. this.mysqlMotifySQLString("addNew", row);
  316. this.sqlStringList.push(this.mysqlMotifySQLString("addNew", row));
  317. }
  318. }
  319. },
  320. // 字段类型改变回调
  321. fieldTypeChange(index, row) {
  322. if (!row.fieldType) return;
  323. if (this.databaseType == "mysql") {
  324. if (!this.modifySQLString.modify[row.fieldName]) {
  325. this.modifySQLString.modify[row.fieldName] = {};
  326. }
  327. if (row.oldVal) {
  328. this.modifySQLString.modify[row.fieldName].fieldType =
  329. this.mysqlMotifySQLString("fieldType", row);
  330. this.sqlStringList.push(this.mysqlMotifySQLString("fieldType", row));
  331. } else if (row.fieldName) {
  332. //新增
  333. this.modifySQLString.addNew[row.fieldName] =
  334. this.mysqlMotifySQLString("addNew", row);
  335. this.sqlStringList.push(this.mysqlMotifySQLString("addNew", row));
  336. }
  337. }
  338. },
  339. // 字段长度改变回调
  340. fieldLengthChange(idnex, row) {
  341. if (!row.fieldLength) return;
  342. if (this.databaseType == "mysql") {
  343. if (!this.modifySQLString.modify[row.fieldName]) {
  344. this.modifySQLString.modify[row.fieldName] = {};
  345. }
  346. if (row.oldVal) {
  347. this.modifySQLString.modify[row.fieldName].fieldLength =
  348. this.mysqlMotifySQLString("fieldLength", row);
  349. this.sqlStringList.push(
  350. this.mysqlMotifySQLString("fieldLength", row)
  351. );
  352. }
  353. }
  354. },
  355. //处理非空选框问题
  356. isNullChange(row) {
  357. if (!row.isNull) {
  358. row.isPrimary = false;
  359. }
  360. if (this.databaseType == "mysql") {
  361. if (row.oldVal) {
  362. if (!this.modifySQLString.modify[row.fieldName]) {
  363. this.modifySQLString.modify[row.fieldName] = {};
  364. }
  365. this.modifySQLString.modify[row.fieldName].isNull = row.isNull
  366. ? this.mysqlMotifySQLString("NOT NULL", row)
  367. : this.mysqlMotifySQLString("NULL", row);
  368. this.sqlStringList.push(
  369. row.isNull
  370. ? this.mysqlMotifySQLString("NOT NULL", row)
  371. : this.mysqlMotifySQLString("NULL", row)
  372. );
  373. }
  374. }
  375. },
  376. // 处理主键选框问题
  377. hanleCheckbox(ind, row) {
  378. if (!this.modifySQLString.modify[row.fieldName]) {
  379. this.modifySQLString.modify[row.fieldName] = {};
  380. }
  381. if (row.isPrimary && (!row.oldVal || !row.oldVal.isPrimary)) {
  382. //添加新的主键
  383. this.modifySQLString.modify[row.fieldName].addPrimary =
  384. this.mysqlMotifySQLString("primary", row);
  385. this.sqlStringList.push(this.mysqlMotifySQLString("primary", row));
  386. }
  387. this.experienceData.forEach((item, index) => {
  388. if (index != ind) {
  389. if (item.oldVal?.isPrimary) {
  390. if (!this.modifySQLString.delete[item.fieldName]) {
  391. this.modifySQLString.delete[item.fieldName] = {};
  392. }
  393. //去掉原来的主键
  394. this.modifySQLString.delete[item.fieldName].dropPrimary =
  395. this.mysqlMotifySQLString("drop primary", item);
  396. this.sqlStringList.push(
  397. this.mysqlMotifySQLString("drop primary", item)
  398. );
  399. }
  400. item.isPrimary = false;
  401. }
  402. if (index == ind && item.isPrimary == true) {
  403. item.isNull = true;
  404. }
  405. });
  406. },
  407. // 是否自增改变
  408. isAutoChange(row) {
  409. let sqlString = "";
  410. if (!this.modifySQLString.modify[row.fieldName]) {
  411. this.modifySQLString.modify[row.fieldName] = {};
  412. }
  413. if (row.oldVal) {
  414. if (row.oldVal.isAuto != row.isAuto) {
  415. this.modifySQLString.modify[row.fieldName].increment = row.isAuto
  416. ? this.mysqlMotifySQLString("increment", row)
  417. : this.mysqlMotifySQLString("no increment", row);
  418. sqlString = row.isAuto
  419. ? this.mysqlMotifySQLString("increment", row)
  420. : this.mysqlMotifySQLString("no increment", row);
  421. }
  422. } else {
  423. this.modifySQLString.modify[row.fieldName].increment = row.isAuto
  424. ? this.mysqlMotifySQLString("increment", row)
  425. : this.mysqlMotifySQLString("no increment", row);
  426. sqlString = row.isAuto
  427. ? this.mysqlMotifySQLString("increment", row)
  428. : this.mysqlMotifySQLString("no increment", row);
  429. }
  430. if (sqlString) {
  431. this.sqlStringList.push(sqlString);
  432. }
  433. },
  434. // 字段描述改变
  435. fieldDescriptionChange(row) {
  436. let sqlString = "";
  437. if (!this.modifySQLString.modify[row.fieldName]) {
  438. this.modifySQLString.modify[row.fieldName] = {};
  439. }
  440. if (row.oldVal) {
  441. if (row.oldVal.fieldDescription != row.fieldDescription) {
  442. this.modifySQLString.modify[row.fieldName].fieldDescription =
  443. this.mysqlMotifySQLString("describe", row);
  444. sqlString = this.mysqlMotifySQLString("describe", row);
  445. }
  446. } else {
  447. this.modifySQLString.modify[row.fieldName].fieldDescription =
  448. this.mysqlMotifySQLString("describe", row);
  449. sqlString = this.mysqlMotifySQLString("describe", row);
  450. }
  451. if (sqlString) {
  452. this.sqlStringList.push(sqlString);
  453. }
  454. },
  455. // 删除字段回调
  456. deleteField(row) {
  457. let sqlString = "";
  458. if (row.oldVal) {
  459. this.modifySQLString.delete[row.fieldName] = this.mysqlMotifySQLString(
  460. "deleteField",
  461. row
  462. );
  463. sqlString = this.mysqlMotifySQLString("deleteField", row);
  464. }
  465. delete this.modifySQLString.modify[row.fieldName];
  466. delete this.modifySQLString.addNew[row.fieldName];
  467. // delete this.modifySQLString.delete[row.fieldName];
  468. if (sqlString) {
  469. this.sqlStringList.push(sqlString);
  470. }
  471. },
  472. // 拼接mysql的修改语句
  473. mysqlMotifySQLString(type, row) {
  474. let table_name = this.form.tableName,
  475. res = "ALTER TABLE";
  476. switch (type) {
  477. case "fieldName": //改字段
  478. res += ` ${table_name} CHANGE ${row.oldVal.fieldName} ${row.fieldName} ${row.fieldType};`;
  479. break;
  480. case "fieldLength": //改长度
  481. res += ` ${table_name} MODIFY ${row.fieldName} ${row.fieldType}(${row.fieldLength});`;
  482. break;
  483. case "fieldType": //改类型
  484. res += ` ${table_name} MODIFY ${row.fieldName} ${row.fieldType};`;
  485. break;
  486. case "NULL": //改允许为NULL
  487. res += ` ${table_name} MODIFY ${row.fieldName} ${row.fieldType} NULL;`;
  488. break;
  489. case "NOT NULL": //改不允许为NULL
  490. res += ` ${table_name} MODIFY ${row.fieldName} ${row.fieldType} NOT NULL;`;
  491. break;
  492. case "primary": //设为主键
  493. res += ` ${table_name} ADD PRIMARY KEY (${row.fieldName});`;
  494. break;
  495. case "drop primary": //删除主键
  496. res += ` ${table_name} DROP PRIMARY KEY;`;
  497. break;
  498. case "increment": //添加自增
  499. res += ` ${table_name} MODIFY ${row.fieldName} INT AUTO_INCREMENT;`;
  500. break;
  501. case "no increment": //删除自增属性
  502. res += ` ${table_name} MODIFY ${row.fieldName} INT;`;
  503. break;
  504. case "describe": //修改字段描述
  505. res += ` ${table_name} MODIFY ${row.fieldName} ${row.fieldType}${
  506. row.fieldLength ? "" : "(" + row.fieldLength + ")"
  507. } comment '${row.fieldDescription}';`;
  508. break;
  509. case "deleteField":
  510. res += ` ${table_name} DROP ${row.fieldName};`;
  511. break;
  512. case "addNew": //新增列
  513. res += ` ${table_name} ADD ${row.fieldName} ${row.fieldType};`;
  514. break;
  515. default:
  516. break;
  517. }
  518. return res;
  519. },
  520. // 获取sql列表
  521. getSQLStringList() {
  522. let res = [];
  523. console.log(this.modifySQLString);
  524. let deleteList = Object.values(this.modifySQLString.delete);
  525. if (deleteList.length) {
  526. for (const value of deleteList) {
  527. res.push(Object.values(value)[0]);
  528. }
  529. }
  530. let addNewList = Object.values(this.modifySQLString.addNew);
  531. if (addNewList.length) {
  532. res = [...res, ...addNewList];
  533. }
  534. let modifyList = Object.values(this.modifySQLString.modify);
  535. if (modifyList.length) {
  536. for (const value of modifyList) {
  537. res.push(Object.values(value)[0]);
  538. }
  539. }
  540. console.log(res);
  541. return res;
  542. },
  543. /* 修改记录回调start */
  544. // 加载数据字典
  545. async getDict() {
  546. let res = await this.getDicts(this.databaseType + "_data_type");
  547. if (res.code == 200) {
  548. this.dataType = res.data.map((item) => {
  549. return {
  550. raw: item,
  551. value: item.dictValue,
  552. label: item.dictLabel,
  553. };
  554. });
  555. } else {
  556. console.log(res.msg);
  557. }
  558. },
  559. // 初始化表格数据
  560. info() {
  561. const tableName = this.$route.query.tableName;
  562. const tableComment = this.$route.query.tableComment;
  563. this.form.tableName = tableName;
  564. this.form.tableComment = tableComment;
  565. let data = {
  566. tableName,
  567. databaseType: this.databaseType,
  568. databaseName: this.databaseName,
  569. };
  570. tableInfo(data).then((response) => {
  571. response.data.forEach((item, index) => {
  572. item.oldVal = JSON.parse(JSON.stringify(item)); // 保留原始数据
  573. // item.sort = index;
  574. item.tag = uuidv4();
  575. this.experienceData.push(item);
  576. this.handleRules("add");
  577. });
  578. // 初始化校验规则
  579. this.experienceData.map((val, index) => {
  580. let temp = JSON.parse(JSON.stringify(this.dataType));
  581. let targetDictItem = temp.find((item) => {
  582. return item.label === val.fieldType;
  583. });
  584. this.handleSelected(targetDictItem, { $index: index, row: val });
  585. });
  586. });
  587. },
  588. // 处理长度框是否可输入
  589. changduclick(inputIndex) {
  590. return this.Inoputdisabled[inputIndex];
  591. },
  592. // 下拉选中事件 // 处理选中类型后长度输入框是否禁用
  593. handleSelected(tem, scope, index, val) {
  594. if (val) {
  595. //判断是否是由change事件触发的函数
  596. this.fieldTypeChange(index, val);
  597. }
  598. if (tem == undefined) return;
  599. if (!this.tableform["fieldLength" + scope.$index]) {
  600. this.tableform["fieldLength" + scope.$index] = {};
  601. }
  602. if (tem.raw.listClass === "success") {
  603. this.Inoputdisabled[scope.$index] = true; // 禁用长度输入框
  604. scope.row.fieldLength = "";
  605. this.tableform["fieldLength" + scope.$index].required = false; // 禁用长度输入框的校验
  606. return this.$set(
  607. this.experienceDataForm,
  608. "fieldType" + scope.$index,
  609. scope.row.fieldType
  610. );
  611. }
  612. this.Inoputdisabled[scope.$index] = false; // 解除禁用
  613. this.tableform["fieldLength" + scope.$index].required = true; // 启用长度输入框的校验
  614. return this.$set(
  615. this.experienceDataForm,
  616. "fieldType" + scope.$index,
  617. scope.row.fieldType
  618. );
  619. },
  620. // 下拉选中事件
  621. selectBlur(aa) {
  622. if (aa.row.fieldType == "") {
  623. aa.row.fieldType = undefined;
  624. }
  625. },
  626. //判断一个字符串是否只包含数字、下划线和小写字母
  627. isValidString(str) {
  628. const regex = /^[a-z0-9_]+$/;
  629. return regex.test(str);
  630. },
  631. // 字段名规则校验
  632. checkFieldName(rule, value, callback) {
  633. let msg = "";
  634. if (!value.trim().length) {
  635. msg = "请输入字段名称";
  636. this.$message.error(msg);
  637. callback(new Error(msg));
  638. } else if (value[0] == "_") {
  639. msg = "请不要以下划线开头";
  640. this.$message.error(msg);
  641. callback(new Error(msg));
  642. } else if (!isNaN(value[0])) {
  643. msg = "请不要以数字开头";
  644. this.$message.error(msg);
  645. callback(new Error(msg));
  646. } else if (!this.isValidString(value)) {
  647. msg = "字段名应该只有下划线,数字和小写字母";
  648. this.$message.error(msg);
  649. callback(new Error(msg));
  650. } else {
  651. //字段名去重校验
  652. if (
  653. this.experienceData.filter((item) => item.fieldName == value)
  654. .length == 1
  655. ) {
  656. callback();
  657. } else {
  658. callback(new Error("字段名称不能重复"));
  659. }
  660. }
  661. },
  662. // 校验数据表名称
  663. checkTableName(rule, value, callback) {
  664. let msg = "";
  665. if (!value.trim().length) {
  666. msg = "请输入数据表名称";
  667. this.$message.error(msg);
  668. callback(new Error(msg));
  669. } else if (value[0] == "_") {
  670. msg = "数据表名,请不要以下划线开头";
  671. this.$message.error(msg);
  672. callback(new Error(msg));
  673. } else if (!isNaN(value[0])) {
  674. msg = "数据表名,请不要以数字开头";
  675. this.$message.error(msg);
  676. callback(new Error(msg));
  677. } else if (!this.isValidString(value)) {
  678. msg = "数据表名,字段名应该只有下划线,数字和小写字母";
  679. this.$message.error(msg);
  680. callback(new Error(msg));
  681. } else {
  682. callback();
  683. }
  684. },
  685. //
  686. // 处理非空校验问题
  687. handleRules(type, delindex, addindex) {
  688. if (type == "add") {
  689. let rulesAdd = {};
  690. // 得到添加一行的下标
  691. let index = this.experienceData.length - 1;
  692. rulesAdd["fieldName" + index] = [
  693. {
  694. required: true,
  695. message: "请输入字段名称",
  696. trigger: "blur",
  697. },
  698. {
  699. validator: this.checkFieldName,
  700. trigger: "blur",
  701. },
  702. ];
  703. rulesAdd["fieldType" + index] = {
  704. required: true,
  705. message: "请选择",
  706. trigger: "change",
  707. };
  708. rulesAdd["fieldLength" + index] = {
  709. required: true,
  710. message: "请输入",
  711. trigger: "blur",
  712. };
  713. // 序列化当前校验规则对象
  714. this.tableform = {
  715. ...this.tableform,
  716. ...rulesAdd,
  717. };
  718. } else if (type == "del") {
  719. // 删除校验规则对象中的元素
  720. this.$delete(this.tableform, "fieldName" + delindex);
  721. this.$delete(this.tableform, "fieldType" + delindex);
  722. this.$delete(this.tableform, "fieldLength" + delindex);
  723. }
  724. },
  725. //增加经验行
  726. handleAddExperienceline() {
  727. if (this.experienceData == undefined) {
  728. this.experienceData = new Array();
  729. }
  730. let obj = {
  731. sort: this.experienceData.length + 1,
  732. tag: uuidv4(),
  733. fieldName: "",
  734. fieldType: "",
  735. fieldLength: undefined,
  736. isDisableFieldLength: true,
  737. isNull: false,
  738. isPrimary: false,
  739. fieldDescription: "",
  740. isAuto: false,
  741. };
  742. this.experienceData.push(obj);
  743. this.handleRules("add");
  744. this.Inoputdisabled.push(false);
  745. },
  746. //保存经验行
  747. handlesaveExperience(a, b) {
  748. // console.log(a + b);
  749. // console.log(b);
  750. },
  751. //删除经验行
  752. handleDeleteExperience(index, row) {
  753. this.experienceData.splice(index, 1);
  754. this.handleRules("del", index);
  755. this.deleteField(row);
  756. },
  757. add() {
  758. const rule1 = new Promise((resolve, reject) => {
  759. this.$refs["form"].validate((valid) => {
  760. if (valid) {
  761. resolve();
  762. } else {
  763. return false;
  764. }
  765. });
  766. });
  767. const rule2 = new Promise((resolve, reject) => {
  768. this.$refs["tableform"].validate((valid) => {
  769. if (valid) {
  770. resolve();
  771. } else {
  772. return false;
  773. }
  774. });
  775. });
  776. Promise.all([rule1, rule2]).then(() => {
  777. if (this.experienceData.length == 0) {
  778. this.$modal.msgWarning("字段不可为空!");
  779. return;
  780. }
  781. this.experienceData.forEach((field) => {
  782. if (field.fieldLength) {
  783. field.fieldType = `${field.fieldType}(${field.fieldLength})`;
  784. }
  785. });
  786. let query = {
  787. databaseType: this.$store.state.user.dataSource.databaseType,
  788. databaseName: this.$store.state.user.dataSource.databaseName,
  789. tableName: this.form.tableName,
  790. tableComment: this.form.tableComment,
  791. field: this.experienceData,
  792. };
  793. createDatabase(query)
  794. .then((res) => {
  795. this.$modal.msgSuccess(res.msg);
  796. if (res.code === 200) {
  797. this.visible = false;
  798. this.$emit("ok");
  799. Object.keys(this.form).forEach((key) => (this.form[key] = ""));
  800. this.experienceData = [];
  801. this.$tab.closePage().then(() => {
  802. this.$router.push({
  803. path: "/data/datamodeling",
  804. });
  805. });
  806. // 新增成功之后关闭当前页面
  807. // this.$router.replace({
  808. // path: "/data/datamodeling",
  809. // });
  810. }
  811. })
  812. .catch((err) => {
  813. console.log(err);
  814. });
  815. });
  816. },
  817. edit() {
  818. const rule1 = new Promise((resolve, reject) => {
  819. this.$refs["form"].validate((valid) => {
  820. if (valid) {
  821. resolve();
  822. } else {
  823. return false;
  824. }
  825. });
  826. });
  827. const rule2 = new Promise((resolve, reject) => {
  828. this.$refs["tableform"].validate((valid) => {
  829. if (valid) {
  830. resolve();
  831. } else {
  832. return false;
  833. }
  834. });
  835. });
  836. Promise.all([rule1, rule2]).then(() => {
  837. if (this.experienceData.length == 0) {
  838. this.$modal.msgWarning("字段不可为空!");
  839. return;
  840. }
  841. this.experienceData = this.experienceData.filter((item) => {
  842. return item.fieldName && item.fieldType;
  843. });
  844. this.experienceData.forEach((field) => {
  845. if (field.fieldLength) {
  846. field.fieldType = `${field.fieldType}(${field.fieldLength})`;
  847. }
  848. });
  849. // console.log(this.sqlStringList);
  850. // return;
  851. let query = {
  852. databaseType: this.$store.state.user.dataSource.databaseType,
  853. databaseName: this.$store.state.user.dataSource.databaseName,
  854. tableName: this.form.tableName,
  855. tableComment: this.form.tableComment,
  856. field: this.experienceData,
  857. };
  858. editTable(query)
  859. .then((res) => {
  860. this.$modal.msgSuccess(res.msg);
  861. if (res.code === 200) {
  862. this.visible = false;
  863. this.$emit("ok");
  864. Object.keys(this.form).forEach((key) => (this.form[key] = ""));
  865. this.experienceData = [];
  866. this.$tab.closePage().then(() => {
  867. this.$router.push({
  868. path: "/data/datamodeling",
  869. });
  870. });
  871. }
  872. })
  873. .catch((err) => {
  874. console.log(err);
  875. });
  876. // 关闭当前页面
  877. this.$tab.closePage();
  878. });
  879. },
  880. //处理表格行拖拽
  881. initDragTable() {
  882. const el = this.$refs.dragTable.$el.querySelectorAll(
  883. ".el-table__body-wrapper > table > tbody"
  884. )[0];
  885. const sortable = Sortable.create(el, {
  886. handle: ".allowDrag",
  887. onEnd: (evt) => {
  888. const targetRow = this.experienceData.splice(evt.oldIndex, 1)[0];
  889. this.experienceData.splice(evt.newIndex, 0, targetRow);
  890. for (let index in this.experienceData) {
  891. this.experienceData[index].sort = parseInt(index) + 1;
  892. }
  893. // 初始化校验规则
  894. this.experienceData.map((val, index) => {
  895. let temp = JSON.parse(JSON.stringify(this.dataType));
  896. let targetDictItem = temp.find((item) => {
  897. return item.label === val.fieldType;
  898. });
  899. this.handleSelected(targetDictItem, { $index: index, row: val });
  900. });
  901. this.$nextTick(() => {
  902. this.$refs.dragTable.doLayout();
  903. });
  904. },
  905. });
  906. },
  907. },
  908. };
  909. </script>
  910. <style scoped lang="scss"></style>