ListViewTemplate.ftl 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  1. <template>
  2. <div class="list-view">
  3. <page-title>
  4. <el-button @click="addRow" type="primary" icon="el-icon-plus" :disabled="fetchingData || downloading" class="filter-item">
  5. 新增
  6. </el-button>
  7. <el-button @click="download" icon="el-icon-upload2" :loading="downloading" :disabled="fetchingData" class="filter-item">
  8. 导出
  9. </el-button>
  10. </page-title>
  11. <div class="filters-container">
  12. <el-input
  13. placeholder="搜索..."
  14. v-model="search"
  15. clearable
  16. class="filter-item search"
  17. @keyup.enter.native="getData"
  18. >
  19. <el-button @click="getData" slot="append" icon="el-icon-search"> </el-button>
  20. </el-input>
  21. </div>
  22. <el-table :data="tableData" row-key="id" ref="table"
  23. header-row-class-name="table-header-row"
  24. header-cell-class-name="table-header-cell"
  25. row-class-name="table-row" cell-class-name="table-cell"
  26. :height="tableHeight" v-loading="fetchingData">
  27. <el-table-column v-if="multipleMode" align="center" type="selection"
  28. width="50">
  29. </el-table-column>
  30. <el-table-column prop="id" label="ID" width="100">
  31. </el-table-column>
  32. <#list model.fields as field>
  33. <#if field.showInList>
  34. <el-table-column prop="${field.modelName!''}" label="${field.remark!field.modelName}"
  35. <#if field.formType == 'select' && field.apiFlag == '1'>
  36. :formatter="${field.modelName}Formatter"
  37. </#if>>
  38. <#if field.sortable!false>
  39. <template slot="header" slot-scope="{column}">
  40. <sortable-header :column="column" :current-sort="sort" @changeSort="changeSort">
  41. </sortable-header>
  42. </template>
  43. </#if>
  44. <#if field.formType == 'singleImage'>
  45. <template slot-scope="{row}">
  46. <el-image style="width: 30px; height: 30px"
  47. :src="row.${field.modelName}" fit="cover"
  48. :preview-src-list="[row.${field.modelName}]"></el-image>
  49. </template>
  50. <#elseif field.formType == 'multiImage'>
  51. <template slot-scope="{row}">
  52. <el-image style="width: 30px; height: 30px"
  53. :src="row.${field.modelName}[0]" fit="cover"
  54. :preview-src-list="row.${field.modelName}"></el-image>
  55. </template>
  56. <#elseif field.formType == 'switch'>
  57. <template slot-scope="{row}">
  58. <el-tag :type="row.${field.modelName}?'':'info'">{{row.${field.modelName}}}</el-tag>
  59. </template>
  60. </#if>
  61. </el-table-column>
  62. </#if>
  63. </#list>
  64. <el-table-column
  65. label="操作"
  66. align="center"
  67. fixed="right"
  68. width="150">
  69. <template slot-scope="{row}">
  70. <#list model.subtables as subtable>
  71. <el-button @click="$router.push({path:'/${subtable.subCode}List',query:{column:row.${subtable.column}+',${subtable.subColumn}'}})" type="primary" size="small" plain>${subtable.name}
  72. </el-button>
  73. </#list>
  74. <el-button @click="editRow(row)" type="primary" size="mini" plain>编辑</el-button>
  75. <el-button @click="deleteRow(row)" type="danger" size="mini" plain>删除</el-button>
  76. </template>
  77. </el-table-column>
  78. </el-table>
  79. <div class="pagination-wrapper">
  80. <!-- <div class="multiple-mode-wrapper">
  81. <el-button v-if="!multipleMode" @click="toggleMultipleMode(true)">批量编辑</el-button>
  82. <el-button-group v-else>
  83. <el-button @click="operation1">批量操作1</el-button>
  84. <el-button @click="operation2">批量操作2</el-button>
  85. <el-button @click="toggleMultipleMode(false)">取消</el-button>
  86. </el-button-group>
  87. </div> -->
  88. <el-pagination background @size-change="onSizeChange"
  89. @current-change="onCurrentChange" :current-page="page"
  90. :page-sizes="[10, 20, 30, 40, 50]" :page-size="pageSize"
  91. layout="total, sizes, prev, pager, next, jumper"
  92. :total="totalElements">
  93. </el-pagination>
  94. </div>
  95. </div>
  96. </template>
  97. <script>
  98. import { mapState } from "vuex";
  99. import pageableTable from "@/mixins/pageableTable";
  100. export default {
  101. name: '${model.className}List',
  102. mixins: [pageableTable],
  103. data() {
  104. return {
  105. multipleMode: false,
  106. search: "",
  107. url: "/${model.className?uncap_first}/all",
  108. downloading: false,
  109. <#list model.fields as field>
  110. <#if field.formType == 'select' && field.apiFlag == '1'>
  111. ${field.modelName}Options:${field.optionsValue},
  112. </#if>
  113. </#list>
  114. }
  115. },
  116. computed: {
  117. selection() {
  118. return this.$refs.table.selection.map(i => i.id);
  119. }
  120. },
  121. methods: {
  122. <#list model.fields as field>
  123. <#if field.formType == 'select' && field.apiFlag == '1'>
  124. ${field.modelName}Formatter(row, column, cellValue, index) {
  125. let selectedOption = this.${field.modelName}Options.find(i => i.value === cellValue);
  126. if (selectedOption) {
  127. return selectedOption.label;
  128. }
  129. return '';
  130. },
  131. </#if>
  132. </#list>
  133. beforeGetData() {
  134. return { search: this.search, query: { del: false } };
  135. },
  136. toggleMultipleMode(multipleMode) {
  137. this.multipleMode = multipleMode;
  138. if (!multipleMode) {
  139. this.$refs.table.clearSelection();
  140. }
  141. },
  142. addRow() {
  143. this.$router.push({
  144. path: "/${model.className?uncap_first}Edit",
  145. query: {
  146. ...this.$route.query
  147. }
  148. });
  149. },
  150. editRow(row) {
  151. this.$router.push({
  152. path: "/${model.className?uncap_first}Edit",
  153. query: {
  154. id: row.id
  155. }
  156. });
  157. },
  158. download() {
  159. this.downloading = true;
  160. this.$axios
  161. .get("/${model.className?uncap_first}/excel", {
  162. responseType: "blob",
  163. params: { size: 10000 }
  164. })
  165. .then(res => {
  166. console.log(res);
  167. this.downloading = false;
  168. const downloadUrl = window.URL.createObjectURL(new Blob([res.data]));
  169. const link = document.createElement("a");
  170. link.href = downloadUrl;
  171. link.setAttribute(
  172. "download",
  173. res.headers["content-disposition"].split("filename=")[1]
  174. );
  175. document.body.appendChild(link);
  176. link.click();
  177. link.remove();
  178. })
  179. .catch(e => {
  180. console.log(e);
  181. this.downloading = false;
  182. this.$message.error(e.error);
  183. });
  184. },
  185. operation1() {
  186. this.$notify({
  187. title: '提示',
  188. message: this.selection
  189. });
  190. },
  191. operation2() {
  192. this.$message('操作2');
  193. },
  194. deleteRow(row) {
  195. this.$alert('删除将无法恢复,确认要删除么?', '警告', {type: 'error'}).then(() => {
  196. return this.$http.post(`/${model.className?uncap_first}/del/${r'${row.id}'}`)
  197. }).then(() => {
  198. this.$message.success('删除成功');
  199. this.getData();
  200. }).catch(e => {
  201. if (e !== 'cancel') {
  202. this.$message.error(e.error);
  203. }
  204. })
  205. },
  206. }
  207. }
  208. </script>
  209. <style lang="less" scoped>
  210. </style>