index.vue 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310
  1. <template>
  2. <div>
  3. <el-table
  4. ref="multipleTable"
  5. v-loading="dataLoading"
  6. stripe
  7. border
  8. :header-cell-style="{background:'#F5F7FA'}"
  9. :data="tableData"
  10. :selection-data="selectionData"
  11. :height="tableMaxHeight"
  12. @selection-change="selectionChange"
  13. @row-click="rowdata"
  14. @cell-mouse-enter="cellMouseEnter"
  15. >
  16. <el-table-column fixed :type="selectType" align="center" width="50" />
  17. <el-table-column v-if="showCover" label="Cover" :align="columns[0].align">
  18. <template slot-scope="scope">
  19. <img :src="src+scope.row.cover" width="40" height="40">
  20. </template>
  21. </el-table-column>
  22. <el-table-column v-if="showFace" label="Cover" :align="columns[0].align">
  23. <template slot-scope="scope">
  24. <img :src="src+scope.row.face" width="40" height="40">
  25. </template>
  26. </el-table-column>
  27. <template v-for="(column, index) in columns">
  28. <el-table-column :key="column.label" :prop="column.prop" :label="column.label" :align="column.align" :min-width="column.minWidth" :max-width="column.maxWidth">
  29. <template slot-scope="scope">
  30. <template v-if="!column.render">
  31. <template v-if="typeof column.formatter == 'string'">
  32. <span v-html="formatter(scope.row, column)" />
  33. </template>
  34. <template v-else-if="typeof column.formatter == 'function'">
  35. <span v-html="column.formatter(scope.row, column)" />
  36. </template>
  37. <template v-else>
  38. <span>{{ scope.row[column.prop] }}</span>
  39. </template>
  40. </template>
  41. <template v-else>
  42. <expand-dom :column="column" :row="scope.row" :render="column.render" :index="index" />
  43. </template>
  44. </template>
  45. </el-table-column>
  46. </template>
  47. <el-table-column
  48. v-if="operates.list.length > 0 && (operates.list.filter(_x=>_x.show === true).length > 0 || operates.dropdown.filter(_x=>_x.show === true).length > 0) "
  49. ref="fixedColumn"
  50. label="Operate"
  51. align="center"
  52. :width="operates.width"
  53. :fixed="operates.fixed"
  54. >
  55. <template slot-scope="scope">
  56. <div class="operate-group">
  57. <template v-for="btn in operates.list">
  58. <el-button
  59. v-if="btn.show"
  60. :key="btn.id"
  61. :type="btn.type"
  62. size="mini"
  63. :icon="btn.icon"
  64. :disabled="btn.disabled"
  65. :plain="btn.plain"
  66. @click.native.prevent="btn.method(scope.row)"
  67. >{{ btn.label }}</el-button>
  68. </template>
  69. <div v-if="operates.dropdown != undefined && operates.dropdown.filter(_x=>_x.show === true).length > 0" style="display: inline-block;">
  70. <el-dropdown style="font-size: 12px" size="mini">
  71. <el-button type="primary" size="mini">More</el-button>
  72. <el-dropdown-menu slot="dropdown">
  73. <el-dropdown-item
  74. v-for="dropbtn in operates.dropdown"
  75. :key="dropbtn.id"
  76. @click.native.prevent="dropbtn.method(scope.row)"
  77. >{{ dropbtn.label }}</el-dropdown-item>
  78. </el-dropdown-menu>
  79. </el-dropdown>
  80. </div>
  81. </div>
  82. </template>
  83. </el-table-column>
  84. </el-table>
  85. <div class="clearfix" style="height: 32px;margin: 10px 24px 0 10px;">
  86. <el-pagination
  87. class="pagination-site"
  88. background
  89. :class="floatType"
  90. :current-page="dataQuery.page"
  91. :page-sizes="page.pageSizes"
  92. :page-size="dataQuery.size"
  93. layout="total, sizes, prev, pager, next, jumper"
  94. :total="page.dataTotal"
  95. @size-change="sizeChange"
  96. @current-change="currentChange"
  97. />
  98. </div>
  99. </div>
  100. </template>
  101. <script>
  102. import { scrollTo } from '@/utils/scroll-to'
  103. import download from '@/utils/download'
  104. import { deepClone } from '@/utils/index'
  105. export default {
  106. name: 'Sheet',
  107. props: {
  108. showFace: {
  109. type: Boolean,
  110. default: false
  111. },
  112. showCover: {
  113. type: Boolean,
  114. default: false
  115. },
  116. headerName: {
  117. type: String,
  118. default: () => 'searchForm'
  119. },
  120. callBack: {
  121. type: Function,
  122. default: () => {}
  123. },
  124. api: {
  125. type: Function,
  126. default: () => {}
  127. },
  128. columns: {
  129. type: Array,
  130. default: () => []
  131. },
  132. floatType: {
  133. type: String,
  134. default: () => ''
  135. },
  136. clearSelection: {
  137. type: String,
  138. default: () => ''
  139. },
  140. selectType: {
  141. type: String,
  142. default: () => ''
  143. },
  144. dataQuery: {
  145. type: Object,
  146. default: () => {
  147. return { page: 1, size: 10 }
  148. }
  149. },
  150. page: {
  151. type: Object,
  152. default: () => {
  153. return {
  154. pageSizes: [5, 10, 20, 50, 100],
  155. dataTotal: 0
  156. }
  157. }
  158. },
  159. operates: {
  160. type: Object,
  161. default: () => {
  162. return {
  163. list: [],
  164. width: 150
  165. }
  166. }
  167. }
  168. },
  169. data: function() {
  170. return {
  171. src: window.Domain.static_url,
  172. tableData: [],
  173. dataLoading: false,
  174. optionsets: {},
  175. selectionData: []
  176. }
  177. },
  178. computed: {
  179. tableMaxHeight() {
  180. if (this.$store === undefined || this.$store.getters.pageTableHeaderHeight === 0) { return null }
  181. const height = 210 + this.$store.getters.pageTableHeaderHeight
  182. return 'calc(100vh - ' + height + 'px)'
  183. }
  184. },
  185. watch: {
  186. clearSelection(newdata, olddata) {
  187. this.$refs.multipleTable.clearSelection()
  188. }
  189. },
  190. created() {
  191. this.getData()
  192. },
  193. methods: {
  194. cellMouseEnter(row, column) {
  195. this.$emit('cell-mouse-enter', row, column)
  196. },
  197. formatter(row, column) {
  198. if (this.optionsets[column.formatter] !== undefined) {
  199. const colValue = row[column.prop]
  200. for (var i = 0; i < this.optionsets[column.formatter].length; i++) {
  201. if (this.optionsets[column.formatter][i].value === colValue) {
  202. return this.optionsets[column.formatter][i].text
  203. }
  204. }
  205. }
  206. return ''
  207. },
  208. rowdata(row, column, event) {
  209. if (column.label !== '操作') {
  210. this.$refs.multipleTable.toggleRowSelection(row)
  211. this.$emit('getRow', row)
  212. }
  213. },
  214. toggleRowSelection(row) {
  215. this.$refs.multipleTable.toggleRowSelection(row)
  216. },
  217. selectionChange(selection) {
  218. this.selectionData = selection
  219. this.$emit('update:selectionData', selection)
  220. },
  221. checkFunc(data) {
  222. return typeof data === 'function' ? data() : data
  223. },
  224. deepCopy(data) {
  225. if (typeof data !== 'object') {
  226. return data
  227. }
  228. if (Array.isArray(data)) {
  229. return data.map(this.deepCopy)
  230. }
  231. const copyData = {}
  232. for (const [key, value] of Object.entries(data)) {
  233. copyData[key] = this.deepCopy(value)
  234. }
  235. return copyData
  236. },
  237. getExportColumns() {
  238. const columns = this.deepCopy(this.checkFunc(this.columns))
  239. return columns
  240. .filter(column => typeof column.show === 'undefined' || column.show)
  241. .map(column => {
  242. if (column.width) {
  243. column.width = column.width * 0.125 || 0
  244. }
  245. return column
  246. })
  247. },
  248. async getData(obj = {}) {
  249. const dataQuery = Object.assign(deepClone(this.dataQuery), obj)
  250. const codes = []
  251. this.columns.forEach(item => {
  252. if (item.formatter !== undefined && typeof item.formatter === 'string') {
  253. codes.push(item.formatter)
  254. }
  255. })
  256. for (var i = 0; i < codes.length; i++) {
  257. this.optionsets[codes[i]] = await this.$store.dispatch('optionset/formatterData', codes[i])
  258. }
  259. if (dataQuery.__export__) {
  260. this.isExporting = true
  261. dataQuery.__columns__ = JSON.stringify(this.getExportColumns())
  262. this.api(dataQuery).then(({ data }) => {
  263. download(data).then(() => {
  264. this.isExporting = false
  265. })
  266. })
  267. } else {
  268. this.dataLoading = true
  269. this.api(dataQuery).then(res => {
  270. if (res.code === 200) {
  271. this.page.dataTotal = res.data.totalrecords
  272. this.tableData = res.data.data
  273. this.$emit('callBack', res.data.content)
  274. } else {
  275. this.page.dataTotal = 0
  276. this.tableData = []
  277. }
  278. this.dataLoading = false
  279. return res
  280. })
  281. }
  282. },
  283. sizeChange(val) {
  284. scrollTo(0, 600)
  285. this.dataQuery.size = val
  286. this.dataQuery.page = 1
  287. this.getData()
  288. },
  289. currentChange(val) {
  290. scrollTo(0, 600)
  291. this.dataQuery.page = val
  292. this.getData()
  293. }
  294. }
  295. }
  296. </script>
  297. <style>
  298. .right {
  299. float: right;
  300. }
  301. .left {
  302. float: left;
  303. }
  304. .el-table--border th.gutter:last-of-type {
  305. display: block !important;
  306. width: 17px !important;
  307. }
  308. </style>