You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

760 lines
38 KiB

  1. <template>
  2. <div>
  3. <div>
  4. <v-tabs
  5. v-model='currentTab'
  6. centered
  7. fixed-tabs
  8. background-color='grey lighten-4'
  9. show-arrows
  10. >
  11. <div class="d-flex align-center">
  12. <!--新增資產群駔對話-->
  13. <v-dialog
  14. v-model='dialogNewAssertGroup'
  15. @click:outside='close'
  16. :retain-focus="false"
  17. overlay-opacity="0"
  18. >
  19. <template v-slot:activator='{ on, attrs }'>
  20. <v-btn
  21. v-bind='attrs'
  22. v-on='on'
  23. icon
  24. >
  25. <v-icon>mdi-plus</v-icon>
  26. </v-btn>
  27. </template>
  28. <v-card>
  29. <v-card-title>
  30. <span class='headline font-weight-bold'>新增資產群組</span>
  31. </v-card-title>
  32. <v-card-text>
  33. <v-container>
  34. <v-row>
  35. <v-col
  36. cols='12'
  37. sm='6'
  38. md='4'
  39. class='d-flex'
  40. >
  41. <v-text-field
  42. v-model="insertAssertGroupDescript"
  43. label='群組名稱'
  44. hint='必填'
  45. />
  46. </v-col>
  47. <v-col
  48. cols='12'
  49. sm='6'
  50. md='4'
  51. class='d-flex'
  52. >
  53. <v-text-field
  54. v-model="insertAssertGroupTablename"
  55. label='資料庫表格名稱'
  56. hint='必填'
  57. />
  58. </v-col>
  59. </v-row>
  60. </v-container>
  61. </v-card-text>
  62. <v-card-actions>
  63. <v-spacer></v-spacer>
  64. <v-btn
  65. color='blue darken-1'
  66. text
  67. @click='close'
  68. >
  69. 取消
  70. </v-btn>
  71. <v-btn
  72. color='blue darken-1'
  73. text
  74. @click='insertAssertGroup'
  75. >
  76. 新增
  77. </v-btn>
  78. </v-card-actions>
  79. </v-card>
  80. </v-dialog>
  81. </div>
  82. <v-tab
  83. v-for='(item, index) in assertGroup'
  84. :key='index'
  85. class=' font-weight-bold'
  86. @mouseover="showTabOptionIcon(index)"
  87. @mouseleave="optionIconShow = -1"
  88. >
  89. <v-icon small>{{ item.text }}</v-icon>
  90. <v-spacer></v-spacer>
  91. <!--修改資產群駔對話-->
  92. <v-dialog
  93. :id="index"
  94. v-model='dialogModifyAssertGroupName'
  95. :retain-focus="false"
  96. overlay-opacity="0"
  97. @click:outside='close'
  98. >
  99. <template v-slot:activator='{ on, attrs }'>
  100. <v-btn
  101. v-bind='attrs'
  102. v-on='on'
  103. icon
  104. >
  105. <v-icon v-show="optionIconShow === index" small
  106. @click="modifyAssertGroup = JSON.parse(JSON.stringify(item))">mdi-pencil
  107. </v-icon>
  108. </v-btn>
  109. </template>
  110. <v-card>
  111. <v-card-title>
  112. <span class='headline font-weight-bold'>修改資產群組名稱</span>
  113. </v-card-title>
  114. <v-card-text>
  115. <v-container>
  116. <v-row>
  117. <v-col
  118. cols='12'
  119. sm='6'
  120. md='4'
  121. class='d-flex'
  122. >
  123. <v-text-field
  124. v-model="modifyAssertGroup.text"
  125. label='群組名稱'
  126. hint='必填'
  127. />
  128. </v-col>
  129. </v-row>
  130. </v-container>
  131. </v-card-text>
  132. <v-card-actions>
  133. <v-spacer></v-spacer>
  134. <v-btn
  135. color='blue darken-1'
  136. text
  137. @click='close'
  138. >
  139. 取消
  140. </v-btn>
  141. <v-btn
  142. color='blue darken-1'
  143. text
  144. @click='modifyAssertGroupName'
  145. >
  146. 修改
  147. </v-btn>
  148. </v-card-actions>
  149. </v-card>
  150. </v-dialog>
  151. <v-btn icon>
  152. <v-icon v-show="optionIconShow === index" small @click="deleteAssertGroup(item)">
  153. mdi-delete
  154. </v-icon>
  155. </v-btn>
  156. </v-tab>
  157. <div class="d-flex align-center">
  158. </div>
  159. <v-tabs-items v-model='currentTab'>
  160. <v-tab-item
  161. v-for='(item, index) in assertGroup'
  162. :key='index'
  163. >
  164. <v-data-table
  165. :items='allCols[item.value]'
  166. :headers='headers'
  167. hide-default-footer
  168. >
  169. <template v-slot:item.actions='{ item }'>
  170. <!--修改資產群駔欄位對話-->
  171. <v-dialog
  172. v-model='dialogModify'
  173. @click:outside='close'
  174. :retain-focus="false"
  175. overlay-opacity="0"
  176. >
  177. <template v-slot:activator='{ on, attrs }'>
  178. <v-btn
  179. v-bind='attrs'
  180. v-on='on'
  181. icon
  182. @click='modifyColItem = JSON.parse(JSON.stringify(item))'
  183. >
  184. <v-icon>mdi-pencil</v-icon>
  185. </v-btn>
  186. </template>
  187. <v-card>
  188. <v-card-title>
  189. <span class='headline font-weight-bold'>修改欄位</span>
  190. </v-card-title>
  191. <v-card-text>
  192. <v-container>
  193. <v-row>
  194. <v-col
  195. v-for='(header, index) in headers'
  196. :key='index'
  197. cols='12'
  198. sm='6'
  199. md='4'
  200. class='d-flex'
  201. >
  202. <v-text-field
  203. v-if="header.text !== '' && header.value !== 'isselect' && isBooleanCol.indexOf(header.value) < 0"
  204. :label='header.text'
  205. :value="modifyColItem[header.value]"
  206. hint='必填'
  207. v-on:input='oninput(modifyColItem, header.value, $event)'
  208. />
  209. <v-select
  210. v-if="header.value === 'isselect' && isBooleanCol.indexOf(header.value) < 0"
  211. :label='header.text' hint='必填'
  212. :value="modifyColItem[header.value]"
  213. v-on:input='oninput(modifyColItem, header.value, $event)'
  214. :items="selectColItem.isselect"
  215. :item-text="selectColItem.isselect.text"
  216. :item-value="selectColItem.isselect.value"
  217. />
  218. <v-select
  219. v-if="header.value && isBooleanCol.indexOf(header.value) >= 0"
  220. :label='header.text' hint='必填'
  221. :value="modifyColItem[header.value]"
  222. v-on:input='oninput(modifyColItem, header.value, $event)'
  223. :items="selectColItem.boolean"
  224. :item-text="selectColItem.boolean.text"
  225. :item-value="selectColItem.boolean.value"
  226. />
  227. <v-btn
  228. v-if="header.value === 'isselect' && modifyColItem.isselect === 'true'"
  229. @click='dialogModifySelectItem = true'
  230. >
  231. 編輯選項
  232. </v-btn>
  233. </v-col>
  234. </v-row>
  235. </v-container>
  236. </v-card-text>
  237. <v-card-actions>
  238. <v-spacer></v-spacer>
  239. <v-btn
  240. color='blue darken-1'
  241. text
  242. @click='close'
  243. >
  244. 取消
  245. </v-btn>
  246. <v-btn
  247. color='blue darken-1'
  248. text
  249. @click='modifyCol(modifyColItem)'
  250. >
  251. 修改
  252. </v-btn>
  253. </v-card-actions>
  254. </v-card>
  255. </v-dialog>
  256. <v-icon
  257. small
  258. @click='deleteCol(item)'
  259. >
  260. mdi-delete
  261. </v-icon>
  262. </template>
  263. <template v-slot:footer>
  264. <div class='d-flex ma-2'>
  265. <v-spacer/>
  266. <!--新增資產群駔欄位對話-->
  267. <v-dialog
  268. v-model='dialogInsert'
  269. @click:outside='close'
  270. :retain-focus="false"
  271. overlay-opacity="0"
  272. >
  273. <template v-slot:activator='{ on, attrs }'>
  274. <v-btn
  275. v-bind='attrs'
  276. v-on='on'
  277. color='primary'
  278. >
  279. 新增欄位
  280. </v-btn>
  281. </template>
  282. <v-card>
  283. <v-card-title>
  284. <span class='headline font-weight-bold'>新增欄位</span>
  285. </v-card-title>
  286. <v-card-text>
  287. <v-container>
  288. <v-row>
  289. <v-col
  290. v-for='(header, index) in headers'
  291. :key='index'
  292. cols='12'
  293. sm='6'
  294. md='4'
  295. class='d-flex'
  296. >
  297. <v-text-field
  298. v-if="header.text !== '' && header.value !== 'isselect' && isBooleanCol.indexOf(header.value) < 0"
  299. :label='header.text'
  300. hint='必填'
  301. v-on:input='oninput(insertColItem, header.value, $event)'
  302. />
  303. <v-select
  304. v-if="header.value === 'isselect' && isBooleanCol.indexOf(header.value) < 0"
  305. :label='header.text' hint='必填'
  306. v-on:input='oninput(insertColItem, header.value, $event)'
  307. :items="selectColItem.isselect"
  308. :item-text="selectColItem.isselect.text"
  309. :item-value="selectColItem.isselect.value"
  310. />
  311. <v-select
  312. v-if="header.value && isBooleanCol.indexOf(header.value) >= 0"
  313. :label='header.text' hint='必填'
  314. v-on:input='oninput(insertColItem, header.value, $event)'
  315. :items="selectColItem.boolean"
  316. :item-text="selectColItem.boolean.text"
  317. :item-value="selectColItem.boolean.value"
  318. />
  319. <v-btn
  320. v-if="header.value === 'isselect' && insertColItem.isselect === 'true'"
  321. @click='dialogInsertSelectItem = true'
  322. >
  323. 編輯選項
  324. </v-btn>
  325. </v-col>
  326. </v-row>
  327. </v-container>
  328. </v-card-text>
  329. <v-card-actions>
  330. <v-spacer></v-spacer>
  331. <v-btn
  332. color='blue darken-1'
  333. text
  334. @click='close'
  335. >
  336. 取消
  337. </v-btn>
  338. <v-btn
  339. color='blue darken-1'
  340. text
  341. @click='insertCol(item)'
  342. >
  343. 新增
  344. </v-btn>
  345. </v-card-actions>
  346. </v-card>
  347. </v-dialog>
  348. </div>
  349. </template>
  350. </v-data-table>
  351. </v-tab-item>
  352. </v-tabs-items>
  353. <!--新增資產群組欄位選項對話-->
  354. <v-dialog
  355. width="80%"
  356. v-model='dialogInsertSelectItem'
  357. @click:outside='closeDialogInsertSelectItem'
  358. :retain-focus="false"
  359. overlay-opacity="0"
  360. >
  361. <v-card>
  362. <v-card-title>
  363. <span class='headline font-weight-bold'>編輯選項</span>
  364. </v-card-title>
  365. <v-card-text>
  366. <v-container>
  367. <v-row>
  368. <v-col cols="3" class="d-flex align-center">
  369. <v-text-field outlined rounded hide-details
  370. v-model="insertSelectItem"/>
  371. <v-btn class="ml-2" @click='pushSelectItem'>新增</v-btn>
  372. </v-col>
  373. </v-row>
  374. <v-card class="mt-2 elevation-2"
  375. style="border: 1px solid grey;min-height: 250px;border-radius: 10px">
  376. <v-chip
  377. v-for="(insertSelectItem, index) in insertSelectItems"
  378. :key="index"
  379. class="ma-2"
  380. color="secondary"
  381. >
  382. {{insertSelectItem}}
  383. <v-icon small class="ml-4" @click="deleteSelectItem(index)">mdi-close</v-icon>
  384. </v-chip>
  385. </v-card>
  386. </v-container>
  387. </v-card-text>
  388. <v-card-actions>
  389. <v-spacer></v-spacer>
  390. <v-btn
  391. color='blue darken-1'
  392. text
  393. @click='closeDialogInsertSelectItem'
  394. >
  395. 關閉
  396. </v-btn>
  397. </v-card-actions>
  398. </v-card>
  399. </v-dialog>
  400. <!--修改資產群組欄位選項對話-->
  401. <v-dialog
  402. width="40%"
  403. v-model='dialogModifySelectItem'
  404. @click:outside='closeDialogModifySelectItem'
  405. :retain-focus="false"
  406. overlay-opacity="0"
  407. >
  408. <v-card>
  409. <v-card-title>
  410. <span class='headline font-weight-bold'>編輯選項</span>
  411. </v-card-title>
  412. <v-card-text>
  413. <v-container>
  414. <v-row>
  415. <v-col cols="11" class="d-flex align-center">
  416. <v-text-field outlined rounded hide-details
  417. v-model="insertSelectItem"/>
  418. <v-btn class="ml-2" @click='pushSelectItem'>新增</v-btn>
  419. </v-col>
  420. </v-row>
  421. <v-card
  422. max-width="80%"
  423. class="mt-2"
  424. style="border: 1px solid grey; border-radius: 10px"
  425. >
  426. <v-card-text>
  427. <v-chip-group
  428. v-model="selection"
  429. column
  430. >
  431. <draggable @start="dragStart" @end="dragEnd">
  432. <v-chip v-for="(modifySelectItem, i) in modifySelectItems" :key="i" color="secondary" class="col-12" draggable>
  433. {{ modifySelectItem }}
  434. </v-chip>
  435. </draggable>
  436. </v-chip-group>
  437. </v-card-text>
  438. </v-card>
  439. </v-container>
  440. </v-card-text>
  441. <v-card-actions>
  442. <v-spacer></v-spacer>
  443. <v-btn
  444. color='blue darken-1'
  445. text
  446. @click='closeDialogModifySelectItem'
  447. >
  448. 關閉
  449. </v-btn>
  450. </v-card-actions>
  451. </v-card>
  452. <div id="app">
  453. <v-app id="inspire">
  454. <v-card
  455. max-width="400"
  456. class="mx-auto"
  457. >
  458. <v-card-text>
  459. <v-chip-group
  460. v-model="selection"
  461. column
  462. active-class="primary--text"
  463. >
  464. <draggable v-model="tags" @start="dragStart" @end="dragEnd">
  465. <v-chip v-for="(tag, i) in tags" :key="i" draggable>
  466. {{ tag.name }}
  467. </v-chip>
  468. </draggable>
  469. </v-chip-group>
  470. </v-card-text>
  471. </v-card>
  472. </v-app>
  473. </div>
  474. </v-dialog>
  475. </v-tabs>
  476. </div>
  477. </div>
  478. </template>
  479. <script>
  480. import draggable from 'vuedraggable';
  481. export default {
  482. name: '',
  483. components: {
  484. draggable,
  485. },
  486. data() {
  487. return {
  488. dialogInsert: false,
  489. dialogModify: false,
  490. dialogNewAssertGroup: false,
  491. // dialogSearch: false,
  492. title: '資訊資產群組',
  493. headers: [
  494. {'text': '', 'value': 'actions', fixed: true, sortable: false},
  495. {'text': '中文名稱', 'value': 'descript'},
  496. {'text': '資料庫欄位名稱', 'value': 'colname'},
  497. // {'text': '型態', 'value': 'type'},
  498. {'text': '文字框或選項', 'value': 'isselect'},
  499. {'text': '順序', 'value': 'index'},
  500. {'text': '必填', 'value': 'isrequire'},
  501. {'text': '可匯出', 'value': 'isexport'},
  502. {'text': '可搜尋', 'value': 'issearch'},
  503. ],
  504. allCols: [],
  505. insertColItem: {
  506. 'tablename': '',
  507. 'descript': '',
  508. 'colname': '',
  509. 'level': null,
  510. // 'type': '',
  511. 'index': '',
  512. 'isselect': '',
  513. 'issearch': '',
  514. 'isexport': '',
  515. 'isrequire': ''
  516. },
  517. isBooleanCol: ['isexport', 'isrequire', 'issearch'],
  518. selectColItem: {
  519. 'isselect': [{'text': '文字', 'value': 'false'},
  520. {'text': '選項', 'value': 'true'}]
  521. , 'boolean': [{'text': '是', 'value': 'true'},
  522. {'text': '否', 'value': 'false'}]
  523. },
  524. modifyColItem: {},
  525. assertGroup: [],
  526. currentTab: 0,
  527. types: [],
  528. // selectItem: {},
  529. // searchItem: {},
  530. insertAssertGroupDescript: '',
  531. insertAssertGroupTablename: '',
  532. optionIconShow: -1,
  533. dialogModifyAssertGroupName: false,
  534. modifyAssertGroup: {
  535. text: '',
  536. valsue: '',
  537. },
  538. dialogInsertSelectItem: false,
  539. insertSelectItems: [],
  540. insertSelectItem: '',
  541. modifySelectItems: [],
  542. modifySelectItem: '',
  543. dialogModifySelectItem: false,
  544. selection: null,
  545. currentTag: null,
  546. tags: [{
  547. name: 'Shoping',
  548. },{
  549. name: 'Art',
  550. }, {
  551. name: 'Tech',
  552. }, {
  553. name: 'Creative Writing'
  554. }
  555. ],
  556. }
  557. },
  558. async mounted() {
  559. // this.getSelectItem();
  560. this.getTabs();
  561. this.getTypes();
  562. this.inventoryItems = [];
  563. this.getCols();
  564. },
  565. computed: {},
  566. watch: {
  567. currentTab() {
  568. this.getTypes();
  569. this.getCols();
  570. },
  571. dialogModifySelectItem() {
  572. this.getModifySelectItems();
  573. },
  574. },
  575. methods: {
  576. // eslint-disable-next-line no-unused-vars
  577. log() {
  578. // console.log(col);
  579. console.log(this.modifySelectItems);
  580. },
  581. dragStart() {
  582. if (this.modifySelectItems[this.selection]) {
  583. this.currentTag = this.modifySelectItems[this.selection];
  584. }
  585. else {
  586. this.currentTag = null;
  587. }
  588. // console.log(this.selection);
  589. // console.log(this.currentTag);
  590. // console.log(this.tags[0].name);
  591. },
  592. dragEnd() {
  593. var self = this;
  594. console.log(this.currentTag);
  595. if (this.currentTag) {
  596. this.modifySelectItems.forEach((x, i) => {
  597. if (x === self.currentTag) self.selection = i;
  598. });
  599. }
  600. // console.log(this.selection);
  601. // console.log(this.currentTag);
  602. console.log(this.modifySelectItems[0]);
  603. },
  604. closeDialogInsertSelectItem() {
  605. this.dialogInsertSelectItem = false
  606. this.insertSelectItems = [];
  607. },
  608. getModifySelectItems() {
  609. this.$axios.get(`/assert/selectItems?tablename=${this.modifyColItem.tablename}&&colname=${this.modifyColItem.colname}`).then((resp) => {
  610. console.log(resp.data.data);
  611. this.modifySelectItems = resp.data.data;
  612. });
  613. },
  614. closeDialogModifySelectItem() {
  615. this.dialogModifySelectItem = false;
  616. this.modifySelectItems = [];
  617. },
  618. pushSelectItem() {
  619. if (this.insertSelectItems.indexOf(this.insertSelectItem) >= 0 || this.insertSelectItem === '') {
  620. alert('選項不得重複或為空');
  621. } else {
  622. this.insertSelectItems.push(this.insertSelectItem);
  623. this.insertSelectItem = '';
  624. }
  625. },
  626. deleteSelectItem(index) {
  627. this.insertSelectItems.splice(index, 1);
  628. },
  629. oninput(item, key, val) {
  630. this.$set(item, key, val);
  631. },
  632. async getTabs() {
  633. await this.$axios.get(`/assert/assertGroups`).then((resp) => {
  634. this.assertGroup = [];
  635. resp.data.data.forEach((item) => {
  636. let header = {'text': null, 'value': null};
  637. header.text = item.descript;
  638. header.value = item.tablename;
  639. this.assertGroup.push(header);
  640. });
  641. // this.assertGroup.push({'text': 'mdi-plus', 'value': ''});
  642. });
  643. },
  644. getTypes() {
  645. const tablename = this.assertGroup[this.currentTab] ? this.assertGroup[this.currentTab].value : 'hardware';
  646. this.$axios.get(`/assert/Types?tablename=${tablename}`).then((resp) => {
  647. this.types = resp.data.data;
  648. });
  649. },
  650. getCols() {
  651. const tablename = this.assertGroup[this.currentTab] ? this.assertGroup[this.currentTab].value : 'hardware';
  652. this.$axios.get(`/assert/allCols?tablename=${tablename}`).then((resp) => {
  653. this.allCols = resp.data.data;
  654. });
  655. },
  656. insertCol() {
  657. for (const key in this.insertColItem) {
  658. if (this.insertColItem[key] === '') {
  659. alert('所有資料不可為空');
  660. return;
  661. } else {
  662. this.insertColItem.tablename = this.assertGroup[this.currentTab].value;
  663. this.insertColItem.insertselectItems = this.insertSelectItems;
  664. this.$axios.post(`/assert/col`, this.insertColItem).then(() => {
  665. this.getCols();
  666. this.close();
  667. this.insertSelectItems = [];
  668. }
  669. );
  670. }
  671. }
  672. },
  673. close() {
  674. this.dialogInsert = false;
  675. this.dialogModify = false;
  676. this.dialogNewAssertGroup = false;
  677. this.dialogModifyAssertGroupName = false;
  678. },
  679. isDisabled(key) {
  680. const disabledKey = ['id'];
  681. return disabledKey.indexOf(key) >= 0;
  682. },
  683. isTextField(key) {
  684. return this.select.indexOf(key) < 0;
  685. },
  686. isSelect(key) {
  687. return this.select.indexOf(key) >= 0;
  688. },
  689. isRequire(key) {
  690. return this.required.indexOf(key) >= 0;
  691. },
  692. getSelectItem() {
  693. this.$axios.get(`/selectItem?tablename=${this.tablename}`).then((resp) => {
  694. this.selectItem = resp.data.data;
  695. });
  696. },
  697. modifyCol(item) {
  698. console.log(item);
  699. item.tablename = this.tablename;
  700. this.$axios.put(`/assert/col`, item).then(() => {
  701. this.getCols();
  702. this.close();
  703. }
  704. );
  705. },
  706. deleteCol(item) {
  707. let yes = confirm('確定刪除');
  708. if (yes) {
  709. this.$axios.delete(`/assert/deleteCol?tablename=${item.tablename}&&colname=${item.colname}`).then(() => {
  710. this.getCols();
  711. alert('已刪除');
  712. });
  713. }
  714. },
  715. exportFile() {
  716. let yes = confirm('確定匯出');
  717. if (yes) {
  718. // this.$axios.delete(`/deleteOne?tablename=${this.tablename}&&id=${item.id}`).then(() => {
  719. // this.getInventories();
  720. // });
  721. }
  722. },
  723. async insertAssertGroup() {
  724. await this.$axios.post(`/assert/assertGroups`, {
  725. assertGroupDescript: this.insertAssertGroupDescript,
  726. assertGroupTablename: this.insertAssertGroupTablename
  727. });
  728. await this.getTabs();
  729. this.close();
  730. },
  731. showTabOptionIcon(index) {
  732. this.optionIconShow = index;
  733. },
  734. async deleteAssertGroup(item) {
  735. let yes = confirm('確認刪除此群組?');
  736. if (yes) {
  737. await this.$axios.delete(`/assert/assertGroups?tablename=${item.value}`).then(() => {
  738. this.getTabs();
  739. alert('已刪除');
  740. });
  741. }
  742. },
  743. async modifyAssertGroupName() {
  744. await this.$axios.put(`/assert/assertGroups?tablename=${this.modifyAssertGroup.value}&&newDescript=${this.modifyAssertGroup.text}`).then(() => {
  745. this.getTabs();
  746. alert('已修改');
  747. this.close();
  748. });
  749. },
  750. }
  751. }
  752. </script>