index.vue 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378
  1. <template>
  2. <div ref="commonTable">
  3. <!-- 搜索栏 -->
  4. <el-form v-if="formList.length > 0" :inline="true" :model="searchDataClone" label-width="130px" ref="searchDataClone"
  5. id="commonTable" class="device-wrapper">
  6. <el-form-item v-for="f in formList" :key="f.prop" :label="f.label" :prop="f.prop">
  7. <template>
  8. <template v-if="f.type === 'input'">
  9. <el-input clearable v-model.trim="searchDataClone[f.prop]" size="small"
  10. :placeholder="'请输入' + f.label"></el-input>
  11. </template>
  12. <template v-else-if="f.type === 'company'">
  13. <el-select size="small" clearable v-model="searchDataClone[f.prop]" :placeholder="'请输入' + f.label" filterable >
  14. <el-option label="不限" value v-if="f.selectAuto"></el-option>
  15. <el-option v-for="(s, i) in InsCompanyList" :key="i" :label="s.name" :value="s.id"></el-option>
  16. </el-select>
  17. </template>
  18. <template v-else-if="f.type === 'companyCheck'">
  19. <el-select class="selectLength" multiple collapse-tags size="small" v-model="searchDataClone[f.prop]"
  20. :placeholder="'请输入' + f.label">
  21. <el-option label="不限" value v-if="f.selectAuto"></el-option>
  22. <el-option v-for="(s, i) in InsCompanyList" :key="i" :label="s.name" :value="s.id"></el-option>
  23. </el-select>
  24. </template>
  25. <template v-else-if="f.type === 'select'">
  26. <el-select size="small" clearable v-model="searchDataClone[f.prop]" :placeholder="'请输入' + f.label">
  27. <el-option label="不限" value v-if="f.selectAuto"></el-option>
  28. <el-option v-for="(s, i) in f.options" :key="i" :label="s.label || s.dictTag"
  29. :value="s.value || s.dictValue"></el-option>
  30. </el-select>
  31. </template>
  32. <template v-else-if="f.type === 'selectDept'">
  33. <el-select size="small" v-model="searchDataClone[f.prop]" filterable clearable :placeholder="'请选择' + f.label"
  34. @change="selectChange($event, f.prop)">
  35. <el-option v-for="(option, index) in f.options" :key="index"
  36. :label="f.optionsIabel ? option[f.optionsIabel] : option.name"
  37. :value="f.optionsValue ? option[f.optionsValue] : option.id"></el-option>
  38. </el-select>
  39. </template>
  40. <template v-else-if="f.type === 'selectCompany'">
  41. <el-select size="small" v-model="searchDataClone[f.prop]" filterable clearable :placeholder="'请选择' + f.label"
  42. @change="selectCompanyChange($event, f.prop)">
  43. <el-option v-for="(option, index) in f.options" :key="index"
  44. :label="f.optionsIabel ? option[f.optionsIabel] : option.name"
  45. :value="f.optionsValue ? option[f.optionsValue] : option.id"></el-option>
  46. </el-select>
  47. </template>
  48. <template v-else-if="f.type === 'datePicker'">
  49. <!-- 日期区间 -->
  50. <el-date-picker style="width: 215px;" type="daterange" size="small" v-model="searchDataClone[f.prop]" align="right" unlink-panels
  51. range-separator="-" start-placeholder="开始时间" end-placeholder="结束时间" value-format="yyyy-MM-dd HH:mm:ss"
  52. :default-time="['00:00:00', '23:59:59']" :clearable="true"></el-date-picker>
  53. </template>
  54. <template v-else-if="f.type === 'date'">
  55. <!-- 一天 -->
  56. <el-date-picker type="date" size="small" v-model="searchDataClone[f.prop]" placeholder="选择日期"
  57. value-format="yyyy-MM-dd"></el-date-picker>
  58. </template>
  59. <!-- 年份 -->
  60. <template v-else-if="f.type === 'year'">
  61. <el-date-picker type="year" size="small" v-model="searchDataClone[f.prop]" placeholder="选择年">
  62. </el-date-picker>
  63. </template>
  64. <template v-else-if="f.type === 'radio'">
  65. <el-radio-group v-model="searchDataClone[f.prop]" :placeholder="'请输入' + f.label">
  66. <el-radio v-for="(r, i) in f.radioList" :key="i" :label="r.value">{{ r.label }}</el-radio>
  67. </el-radio-group>
  68. </template>
  69. <template v-else-if="f.type === 'slot'">
  70. <slot show-overflow-tooltip :name="f.name" ></slot>
  71. </template>
  72. </template>
  73. </el-form-item>
  74. <el-form-item>
  75. <el-button style="margin-left:30px" size="small" @click="resetForm('searchDataClone')">重置</el-button>
  76. <el-button type="primary" size="small" @click="handleSearchList()">查询</el-button>
  77. <template v-if="btnGroup.length > 0">
  78. <span v-for="(val, idx) in btnGroup" :key="idx" style="margin-left:10px">
  79. <slot v-if="val.slot" show-overflow-tooltip :name="val.name"></slot>
  80. <el-button v-else :disabled="false || (val.disabled && val.disabled())" :type="val.type || 'primary'" size="small" @click="val.click()">{{ val.name }}</el-button>
  81. </span>
  82. </template>
  83. </el-form-item>
  84. <!-- <el-form-item v-if="btnGroup.length>0" >
  85. <el-button v-for="(val, idx) in btnGroup" :key="idx" :type="val.type || 'primary'" size="small" @click="tabFun(val)">{{ val.name }}</el-button>
  86. </el-form-item> -->
  87. </el-form>
  88. <slot v-if="custom" show-overflow-tooltip ></slot>
  89. <el-table ref="table" :show-summary="tableConfig.showSummary||false" :data="data" border size="small" style="width: 100%" :height="tableConfig.tableHeight ||tableHeight" v-loading="tableConfig.loading"
  90. element-loading-text="数据加载中" element-loading-spinner="el-icon-loading" @selection-change="handleSelectionChange" @select-all="selectAll"
  91. :row-style="{ height: '55px' }" :cell-style="{ padding: '0px' }"
  92. :header-cell-style="{ background: '#F2F7FC', fontWeight: '700', color: '#606266' }" :cell-class-name="rowClass">
  93. <el-table-column type="selection" :width="tableConfig.selectionWidth || '50'" v-if="tableConfig.isCheckBox"
  94. align="center" />
  95. <el-table-column type="index" :width="tableConfig.indexWidth || '50'" v-if="tableConfig.isShowIndex" align="center"
  96. label="序号" />
  97. <template v-for="(item, index) in tableConfig.columns">
  98. <!-- 日期内容 -->
  99. <el-table-column v-if="item.type === 'date'" :align="'center'" :fixed="item.fixed" :width="item.width || 150"
  100. show-overflow-tooltip :label="item.label" :key="item.prop">
  101. <template slot-scope="scope">
  102. <div>{{ scope.row[item.prop] | formateDate }}</div>
  103. </template>
  104. </el-table-column>
  105. <!-- 字典项 -->
  106. <el-table-column v-if="item.type === 'dic'" :align="'center'" :width="item.width || ''" :fixed="item.fixed"
  107. show-overflow-tooltip :label="item.label" :key="item.prop" :prop="item.prop">
  108. <template slot-scope="scope">
  109. <span>{{ selectDictLabel(dictData[item.dic], scope.row[item.prop]) }}</span>
  110. </template>
  111. </el-table-column>
  112. <el-table-column v-if="item.type === 'statMap'" :align="'center'" :width="item.width || ''" :fixed="item.fixed"
  113. show-overflow-tooltip :label="item.label" :key="item.prop" :prop="item.prop">
  114. <template slot-scope="scope">
  115. <span> {{ statMaps(item.options)[scope.row[item.prop]] || '--' }}</span>
  116. </template>
  117. </el-table-column>
  118. <!-- 自定义内容 -->
  119. <el-table-column v-if="item.type === 'slot'" :align="'center'" show-overflow-tooltip :name="item.name"
  120. :label="item.label" :key="item.prop" :prop="item.prop">
  121. <template slot-scope="scope">
  122. <slot show-overflow-tooltip v-bind="scope" :name="item.name"></slot>
  123. </template>
  124. </el-table-column>
  125. <!-- 常规文本内容 -->
  126. <el-table-column v-if="item.type === 'text'" :align="'center'" :width="item.width || ''" :fixed="item.fixed"
  127. :label="item.label" :key="item.prop" :prop="item.prop"></el-table-column>
  128. </template>
  129. <!-- <slot name="operate" :row="scope.row"></slot> -->
  130. <!-- 自定义操作栏 -->
  131. <el-table-column v-if="tableConfig.operateShow" label="操作" align="center"
  132. :min-width="tableConfig.operationWidth || '100'" fixed="right">
  133. <template slot-scope="scope">
  134. <slot name="operate" :row="scope.row"></slot>
  135. </template>
  136. </el-table-column>
  137. <!-- 数组形式的操作栏,用于普通按钮 -->
  138. <!-- // optBtns:[
  139. // {
  140. // type:'primary',
  141. // label:'修改',
  142. // hide:(row) => {
  143. // return row.importStatus == 1?true:false
  144. // },
  145. // click:(row, index) => {return this.modifyFun(row)},
  146. // }
  147. // ] -->
  148. <el-table-column v-if="tableConfig.optBtns" :min-width="tableConfig.operationWidth || '100'" label="操作"
  149. fixed="right" header-align="center" align="center">
  150. <template slot-scope="scope">
  151. <span v-for="(btn, index) in tableConfig.optBtns" :key="index">
  152. <!-- <el-button style="margin:0 10px" v-if="!btn.hide || (btn.hide && btn.hide(scope.row))" v-permission="btn.perm"
  153. @click="btn.click(scope.row, index)" :type="btn.type || 'primary'" :icon="btn.icon" size="small">{{
  154. btn.label
  155. }} </el-button> -->
  156. <kt-button style="margin:0 10px" v-if="!btn.hide || (btn.hide && btn.hide(scope.row))" :icon="btn.icon" :label="btn.label"
  157. :type="btn.type || 'primary'" size="small" :perms="btn.perm" @click="btn.click(scope.row, index)" />
  158. </span>
  159. </template>
  160. </el-table-column>
  161. </el-table>
  162. <!-- 分页 -->
  163. <div class="block" ref="bottomFixed">
  164. <el-pagination v-if="tableConfig.isPaginationShow && pagination.totalSize" style="margin-top: 10px"
  165. :page-size="pagination.pageSize" :current-page.sync="pagination.pageNum" :total="pagination.totalSize"
  166. layout="total, sizes,prev, pager, next,jumper" :page-sizes="[10, 20, 50, 100]" @size-change="handleSizeChange"
  167. @current-change="handleCurrentChange" />
  168. </div>
  169. </div>
  170. </template>
  171. <script type="text/ecmascript-6">
  172. import KtButton from "@/views/Core/KtButton";
  173. export default {
  174. components: {
  175. KtButton,
  176. },
  177. props: {
  178. custom: {
  179. type: Boolean,
  180. default: () => {
  181. return false;
  182. }
  183. },
  184. formList: {
  185. type: Array,
  186. default: () => {
  187. return [];
  188. }
  189. },
  190. btnGroup: {
  191. type: Array,
  192. default: () => {
  193. return [];
  194. }
  195. },
  196. tableConfig: {
  197. type: Object,
  198. default: () => {
  199. return {};
  200. }
  201. },
  202. // searchDataClone: {
  203. // type: Object,
  204. // default: () => {
  205. // return {};
  206. // }
  207. // },
  208. pagination: {
  209. type: Object,
  210. default: () => ({
  211. pageNum: 1,
  212. pageSize: 20,
  213. totalSize: 0,
  214. }),
  215. },
  216. rowClass: {
  217. type: Function,
  218. default: () => '',
  219. },
  220. data: {
  221. type: Array,
  222. default: () => []
  223. },
  224. },
  225. data() {
  226. return {
  227. tableHeight: 0,
  228. InsCompanyList: [],
  229. searchDataClone: {}
  230. };
  231. },
  232. created() {
  233. if(this.formList.length>0 && this.formList.find(val=>val.type=='company' || val.type=='companyCheck')){
  234. this.companyFun()
  235. }
  236. },
  237. mounted() {
  238. setTimeout(() => {
  239. var divHg = 0;
  240. if (document.getElementById("commonTable") != null) {
  241. divHg = document.getElementById("commonTable").clientHeight
  242. } else {
  243. divHg = 100
  244. }
  245. let bottomTop = this.$refs.bottomFixed.offsetTop;
  246. this.tableHeight = window.innerHeight - divHg -160 + "px";
  247. }, 10);
  248. },
  249. filters: {
  250. formateDate(val) {
  251. return formatDateTime(val)
  252. }
  253. },
  254. methods: {
  255. selectChange(id, filed) {
  256. switch (filed) {
  257. case 'provinceId':
  258. break;
  259. case 'cityId':
  260. break;
  261. case 'countyId':
  262. break;
  263. default:
  264. break;
  265. }
  266. if (id) {
  267. this.$emit('areaSelectChange', { id, filed });
  268. }
  269. },
  270. selectCompanyChange(id, filed) {
  271. if (id) {
  272. this.$emit('companySelectChange', { id, filed });
  273. }
  274. },
  275. formatDateTime(date) {
  276. let d = new Date(date),
  277. month = '' + (d.getMonth() + 1),
  278. day = '' + d.getDate(),
  279. year = d.getFullYear();
  280. if (month.length < 2) month = '0' + month;
  281. if (day.length < 2) day = '0' + day;
  282. return [year, month, day].join('-');
  283. },
  284. companyFun() {
  285. this.$api.cost.gainTopList({ type: 1 }).then(res => {
  286. if (res.data) {
  287. this.InsCompanyList = res.data;
  288. }
  289. });
  290. },
  291. statMaps(list) {
  292. if (!list) return;
  293. let obj = {};
  294. list.forEach(item => {
  295. obj[item.value || item.id] = item.label || item.value;
  296. });
  297. return obj;
  298. },
  299. selectDictLabel(dicts, value) {
  300. if (value === undefined) {
  301. return '';
  302. }
  303. if (dicts === undefined) {
  304. return '';
  305. }
  306. const actions = [];
  307. Object.keys(dicts).some((key) => {
  308. if (dicts[key].value === `${value}`) {
  309. actions.push(dicts[key].label);
  310. return true;
  311. }
  312. });
  313. if (actions.length === 0) {
  314. actions.push(value);
  315. }
  316. return actions.join('');
  317. },
  318. // 表格多选
  319. handleSelectionChange(currentRow) {
  320. this.$emit('selectionChange', currentRow,this.$refs.table);
  321. },
  322. selectAll(currentRow) {
  323. this.$emit('selectAll', currentRow,this.$refs.table);
  324. },
  325. handleSizeChange(value) {
  326. this.pagination.pageSize = value;
  327. this.pagination.pageNum = 1;
  328. this.$emit('getList',{...this.pagination,...this.searchDataClone});
  329. },
  330. handleCurrentChange(val) {
  331. this.pagination.pageNum = val;
  332. this.$emit('getList',{...this.pagination,...this.searchDataClone});
  333. },
  334. // 搜索
  335. handleSearchList() {
  336. // 更新父组件searchData
  337. this.pagination.pageNum = 1;
  338. this.pagination.pageSize = 20;
  339. this.$emit("handleSearchList", this.searchDataClone);
  340. },
  341. // 重置
  342. resetForm(formName) {
  343. this.searchDataClone = {}
  344. // this.$refs[formName].resetFields();
  345. this.handleSearchList();
  346. },
  347. handleOpt(row, index) {
  348. this.$emit('handleOpt', row, index)
  349. },
  350. }
  351. };
  352. </script>
  353. <style scoped>
  354. .selectLength /deep/ .el-select__tags-text {
  355. display: inline-block;
  356. max-width: 110px;
  357. overflow: hidden;
  358. text-overflow: ellipsis;
  359. white-space: nowrap;
  360. }
  361. .device-wrapper /deep/ .el-form-item {
  362. margin-bottom: 12px;
  363. }
  364. </style>