index.vue 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544
  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 :data="experienceData" stripe style="width: 100%">
  26. <el-table-column prop="fieldName" label="字段名称" width="200">
  27. <template slot-scope="scope">
  28. <el-form-item
  29. :prop="'fieldName' + scope.$index"
  30. :name="'fieldName' + scope.$index"
  31. style="margin: 0px; padding: 0px"
  32. >
  33. <el-input v-model="scope.row.fieldName"></el-input>
  34. </el-form-item>
  35. </template>
  36. </el-table-column>
  37. <el-table-column prop="fieldType" label="字段类型" width="200">
  38. <template slot-scope="scope">
  39. <el-form-item
  40. :prop="'fieldType' + scope.$index"
  41. :name="'fieldType' + scope.$index"
  42. style="margin: 0px; padding: 0px"
  43. >
  44. <el-select
  45. v-model="scope.row.fieldType"
  46. filterable
  47. @blur="selectBlur(scope)"
  48. @change="
  49. handleSelected(
  50. dataType.find(
  51. (item) => item.label === scope.row.fieldType
  52. ),
  53. scope
  54. )
  55. "
  56. >
  57. <!-- <el-option v-for="item in list" :key="item" :label="item" :value="item">
  58. </el-option> -->
  59. <!--
  60. <el-option v-for="item in dict.type.mysql_data_type" :label="item.dictLabel" :value="item.dictValue">
  61. </el-option> -->
  62. <el-option
  63. v-for="item in dataType"
  64. :key="item.value"
  65. :label="item.label"
  66. :value="item.value"
  67. />
  68. </el-select>
  69. </el-form-item>
  70. </template>
  71. </el-table-column>
  72. <el-table-column prop="fieldLength" label="长度" width="200">
  73. <template slot-scope="scope">
  74. <el-form-item
  75. :prop="'fieldLength' + scope.$index"
  76. :name="'fieldLength' + scope.$index"
  77. style="margin: 0px; padding: 0px"
  78. >
  79. <!-- <el-input v-model="scope.row.fieldLength"-->
  80. <!-- :disabled="handleSelected(dict.type.mysql_data_type.find(item => item.label === scope.row.fieldType), scope)"></el-input>-->
  81. <el-input
  82. v-model="scope.row.fieldLength"
  83. :disabled="changduclick(scope.$index)"
  84. ></el-input>
  85. </el-form-item>
  86. </template>
  87. </el-table-column>
  88. <el-table-column prop="isNull" label="不是null" width="100">
  89. <template slot-scope="scope">
  90. <el-checkbox
  91. @change="isNullChange(scope.row)"
  92. v-model="scope.row.isNull"
  93. ></el-checkbox>
  94. </template>
  95. </el-table-column>
  96. <el-table-column prop="isPrimary" label="键" width="100">
  97. <template slot-scope="scope">
  98. <el-checkbox
  99. v-model="scope.row.isPrimary"
  100. @change="hanleCheckbox(scope.$index)"
  101. ></el-checkbox>
  102. </template>
  103. </el-table-column>
  104. <el-table-column prop="isAuto" label="自增" width="100">
  105. <template slot-scope="scope">
  106. <el-checkbox v-model="scope.row.isAuto"></el-checkbox>
  107. </template>
  108. </el-table-column>
  109. <el-table-column prop="fieldDescription" label="字段描述" width="200">
  110. <template slot-scope="scope">
  111. <el-input v-model="scope.row.fieldDescription"></el-input>
  112. </template>
  113. </el-table-column>
  114. <el-table-column prop="operate" label="操作">
  115. <template slot-scope="scope">
  116. <!-- <el-button size="mini" type="success" icon="el-icon-save"
  117. @click="handlesaveExperience(scope.$index, scope.row)">保存
  118. </el-button> -->
  119. <el-button
  120. size="mini"
  121. type="danger"
  122. icon="el-icon-delete"
  123. @click="handleDeleteExperience(scope.$index, scope.row)"
  124. >删除
  125. </el-button>
  126. </template>
  127. </el-table-column>
  128. </el-table>
  129. </el-form>
  130. <div>
  131. <el-button
  132. type="primary"
  133. icon="el-icon-plus"
  134. size="mini"
  135. @click="handleAddExperienceline"
  136. >新增字段
  137. </el-button>
  138. </div>
  139. </el-card>
  140. <div style="margin-top: 15px">
  141. <el-button v-if="!isEdited" @click="add" type="primary">添加</el-button>
  142. <el-button v-else @click="edit" type="primary">修改</el-button>
  143. </div>
  144. </div>
  145. </template>
  146. <script>
  147. import { createDatabase } from "@/api/datasheet/index";
  148. import { tableInfo, editTable } from "@/api/dataEngine/index";
  149. import { mapState } from "vuex";
  150. import { getDicts } from "@/api/system/dict/data";
  151. export default {
  152. name: "Datasheet",
  153. // dicts: [
  154. // "dm_data_type",
  155. // "mysql_data_type",
  156. // "sqlserver_data_type",
  157. // "oracle_data_type",
  158. // ],
  159. data() {
  160. return {
  161. isEdited: false,
  162. testzidian: null,
  163. form: {
  164. dataBaseName: "",
  165. tableName: "",
  166. tableComment: "",
  167. },
  168. experienceDataForm: {},
  169. experienceData: [
  170. // {
  171. // fieldName: '',
  172. // fieldType: '',
  173. // fieldLength: undefined,
  174. // isNull: false,
  175. // isPrimary: false,
  176. // fieldDescription: '',
  177. // isAuto: false
  178. // },
  179. ],
  180. rules: {
  181. dataBaseName: {
  182. required: true,
  183. message: "请输入数据库名称",
  184. trigger: "blur",
  185. },
  186. tableName: {
  187. required: true,
  188. message: "请输入数据库名称",
  189. trigger: "blur",
  190. },
  191. },
  192. tableform: {
  193. // fieldName0: { required: true, message: '请输入字段名称', trigger: 'blur' },
  194. // fieldType0: { required: true, message: '请选择', trigger: 'change' },
  195. // fieldLength0: { required: true, message: '请输入', trigger: 'blur' },
  196. },
  197. list: ["int", "varchar"],
  198. dataType: [], //数据类型字典
  199. Inoputdisabled: [],
  200. // 需要指定长度
  201. mysqlAllowLength: ["char", "varchar", "numeric", "decimal"],
  202. };
  203. },
  204. async created() {
  205. await this.getDict();
  206. if (this.$route.query.tableName) {
  207. this.isEdited = true;
  208. this.info();
  209. } else {
  210. Object.keys(this.form).forEach((item) => {
  211. this.form[item] = "";
  212. });
  213. this.experienceData = [];
  214. }
  215. },
  216. mounted() {},
  217. computed: {
  218. ...mapState({
  219. databaseName: (state) => state.user.dataSource.databaseName,
  220. databaseType: (state) => state.user.dataSource.databaseType,
  221. }),
  222. },
  223. watch: {
  224. experienceData: {
  225. handler(n, o) {
  226. // do something
  227. this.experienceDataForm = {};
  228. let rulesAdd = {};
  229. this.experienceData.forEach((item, index) => {
  230. this.$set(
  231. this.experienceDataForm,
  232. "fieldName" + index,
  233. item.fieldName
  234. );
  235. this.$set(
  236. this.experienceDataForm,
  237. "fieldType" + index,
  238. item.fieldType
  239. );
  240. this.$set(
  241. this.experienceDataForm,
  242. "fieldLength" + index,
  243. item.fieldLength
  244. );
  245. // rulesAdd['' + index] = item.fieldName
  246. // rulesAdd['fieldType' + index] = item.fieldType
  247. // rulesAdd['fieldLength' + index] = item.fieldLength
  248. // this.experienceDataForm = {...rulesAdd}
  249. });
  250. },
  251. deep: true, // 深度监听父组件传过来对象变化
  252. },
  253. },
  254. methods: {
  255. // 加载数据字典
  256. async getDict() {
  257. let res = await this.getDicts(this.databaseType + "_data_type");
  258. console.log(res);
  259. if (res.code == 200) {
  260. this.dataType = res.data.map((item) => {
  261. return {
  262. raw: item,
  263. value: item.dictValue,
  264. label: item.dictLabel,
  265. };
  266. });
  267. } else {
  268. console.log(res.msg);
  269. }
  270. },
  271. // 初始化表格数据
  272. info() {
  273. const tableName = this.$route.query.tableName;
  274. const tableComment = this.$route.query.tableComment;
  275. this.form.tableName = tableName;
  276. this.form.tableComment = tableComment;
  277. let data = {
  278. tableName,
  279. databaseType: this.databaseType,
  280. databaseName: this.databaseName,
  281. };
  282. tableInfo(data).then((response) => {
  283. this.experienceData = response.data;
  284. // 初始化校验规则
  285. this.experienceData.map((val, index) => {
  286. let temp = JSON.parse(JSON.stringify(this.dataType));
  287. console.log(temp);
  288. let targetDictItem = temp.find((item) => {
  289. return item.label === val.fieldType;
  290. });
  291. this.handleSelected(targetDictItem, { $index: index, row: val });
  292. });
  293. });
  294. },
  295. // 处理长度框是否可输入
  296. changduclick(inputIndex) {
  297. return this.Inoputdisabled[inputIndex];
  298. },
  299. // 下拉选中事件 // 处理选中类型后长度输入框是否禁用
  300. handleSelected(tem, scope) {
  301. if (tem == undefined) return;
  302. if (!this.tableform["fieldLength" + scope.$index]) {
  303. this.tableform["fieldLength" + scope.$index] = {};
  304. }
  305. if (tem.raw.listClass === "success") {
  306. this.Inoputdisabled[scope.$index] = true; // 禁用长度输入框
  307. scope.row.fieldLength = "";
  308. this.tableform["fieldLength" + scope.$index].required = false; // 禁用长度输入框的校验
  309. return this.$set(
  310. this.experienceDataForm,
  311. "fieldType" + scope.$index,
  312. scope.row.fieldType
  313. );
  314. }
  315. this.Inoputdisabled[scope.$index] = false; // 解除禁用
  316. this.tableform["fieldLength" + scope.$index].required = true; // 启用长度输入框的校验
  317. return this.$set(
  318. this.experienceDataForm,
  319. "fieldType" + scope.$index,
  320. scope.row.fieldType
  321. );
  322. },
  323. // 下拉选中事件
  324. selectBlur(aa) {
  325. if (aa.row.fieldType == "") {
  326. aa.row.fieldType = undefined;
  327. }
  328. },
  329. // 处理非空校验问题
  330. handleRules(type, delindex) {
  331. if (type == "add") {
  332. let rulesAdd = {};
  333. // 得到添加一行的下标
  334. let index = this.experienceData.length - 1;
  335. rulesAdd["fieldName" + index] = {
  336. required: true,
  337. message: "请输入字段名称",
  338. trigger: "blur",
  339. };
  340. rulesAdd["fieldType" + index] = {
  341. required: true,
  342. message: "请选择",
  343. trigger: "change",
  344. };
  345. rulesAdd["fieldLength" + index] = {
  346. required: true,
  347. message: "请输入",
  348. trigger: "blur",
  349. };
  350. // 序列化当前校验规则对象
  351. this.tableform = {
  352. ...this.tableform,
  353. ...rulesAdd,
  354. };
  355. } else if (type == "del") {
  356. // 删除校验规则对象中的元素
  357. this.$delete(this.tableform, "fieldName" + delindex);
  358. this.$delete(this.tableform, "fieldType" + delindex);
  359. this.$delete(this.tableform, "fieldLength" + delindex);
  360. }
  361. },
  362. // 处理主键选框问题
  363. hanleCheckbox(ind) {
  364. this.experienceData.forEach((item, index) => {
  365. if (index != ind) {
  366. item.isPrimary = false;
  367. }
  368. if (index == ind && item.isPrimary == true) {
  369. item.isNull = true;
  370. }
  371. });
  372. },
  373. //处理非空选框问题
  374. isNullChange(row) {
  375. if (!row.isNull) {
  376. row.isPrimary = false;
  377. }
  378. },
  379. //增加经验行
  380. handleAddExperienceline() {
  381. if (this.experienceData == undefined) {
  382. this.experienceData = new Array();
  383. }
  384. let obj = {
  385. fieldName: "",
  386. fieldType: "",
  387. fieldLength: undefined,
  388. isDisableFieldLength: true,
  389. isNull: false,
  390. isPrimary: false,
  391. fieldDescription: "",
  392. isAuto: false,
  393. };
  394. this.experienceData.push(obj);
  395. this.handleRules("add");
  396. this.Inoputdisabled.push(false);
  397. },
  398. //保存经验行
  399. handlesaveExperience(a, b) {
  400. // console.log(a + b);
  401. // console.log(b);
  402. },
  403. //删除经验行
  404. handleDeleteExperience(index) {
  405. this.experienceData.splice(index, 1);
  406. this.handleRules("del", index);
  407. },
  408. add() {
  409. const rule1 = new Promise((resolve, reject) => {
  410. this.$refs["form"].validate((valid) => {
  411. if (valid) {
  412. resolve();
  413. } else {
  414. return false;
  415. }
  416. });
  417. });
  418. const rule2 = new Promise((resolve, reject) => {
  419. this.$refs["tableform"].validate((valid) => {
  420. if (valid) {
  421. resolve();
  422. } else {
  423. return false;
  424. }
  425. });
  426. });
  427. Promise.all([rule1, rule2]).then(() => {
  428. if (this.experienceData.length == 0) {
  429. this.$modal.msgWarning("字段不可为空!");
  430. return;
  431. }
  432. this.experienceData.forEach((field) => {
  433. if (field.fieldLength) {
  434. field.fieldType = `${field.fieldType}(${field.fieldLength})`;
  435. }
  436. });
  437. let query = {
  438. databaseType: this.$store.state.user.dataSource.databaseType,
  439. databaseName: this.$store.state.user.dataSource.databaseName,
  440. tableName: this.form.tableName,
  441. tableComment: this.form.tableComment,
  442. field: this.experienceData,
  443. };
  444. createDatabase(query)
  445. .then((res) => {
  446. this.$modal.msgSuccess(res.msg);
  447. if (res.code === 200) {
  448. this.visible = false;
  449. this.$emit("ok");
  450. Object.keys(this.form).forEach((key) => (this.form[key] = ""));
  451. this.experienceData = [];
  452. this.$tab.closePage().then(() => {
  453. this.$router.push({
  454. path: "/data/datamodeling",
  455. });
  456. });
  457. // 新增成功之后关闭当前页面
  458. // this.$router.replace({
  459. // path: "/data/datamodeling",
  460. // });
  461. }
  462. })
  463. .catch((err) => {
  464. console.log(err);
  465. });
  466. });
  467. },
  468. edit() {
  469. const rule1 = new Promise((resolve, reject) => {
  470. this.$refs["form"].validate((valid) => {
  471. if (valid) {
  472. resolve();
  473. } else {
  474. return false;
  475. }
  476. });
  477. });
  478. const rule2 = new Promise((resolve, reject) => {
  479. this.$refs["tableform"].validate((valid) => {
  480. if (valid) {
  481. resolve();
  482. } else {
  483. return false;
  484. }
  485. });
  486. });
  487. Promise.all([rule1, rule2]).then(() => {
  488. if (this.experienceData.length == 0) {
  489. this.$modal.msgWarning("字段不可为空!");
  490. return;
  491. }
  492. this.experienceData = this.experienceData.filter((item) => {
  493. return item.fieldName && item.fieldType;
  494. });
  495. this.experienceData.forEach((field) => {
  496. if (field.fieldLength) {
  497. field.fieldType = `${field.fieldType}(${field.fieldLength})`;
  498. }
  499. });
  500. let query = {
  501. databaseType: this.$store.state.user.dataSource.databaseType,
  502. databaseName: this.$store.state.user.dataSource.databaseName,
  503. tableName: this.form.tableName,
  504. tableComment: this.form.tableComment,
  505. field: this.experienceData,
  506. };
  507. editTable(query)
  508. .then((res) => {
  509. this.$modal.msgSuccess(res.msg);
  510. if (res.code === 200) {
  511. this.visible = false;
  512. this.$emit("ok");
  513. Object.keys(this.form).forEach((key) => (this.form[key] = ""));
  514. this.experienceData = [];
  515. this.$tab.closePage().then(() => {
  516. this.$router.push({
  517. path: "/data/datamodeling",
  518. });
  519. });
  520. }
  521. })
  522. .catch((err) => {
  523. console.log(err);
  524. });
  525. // 关闭当前页面
  526. this.$tab.closePage();
  527. });
  528. },
  529. },
  530. };
  531. </script>
  532. <style scoped></style>