index.vue 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591
  1. <template>
  2. <div ref="commonTable">
  3. <!-- 搜索栏 -->
  4. <el-form
  5. v-if="formList.length > 0"
  6. :inline="true"
  7. :model="searchDataClone"
  8. label-width="130px"
  9. ref="searchDataClone"
  10. id="commonTable"
  11. class="device-wrapper"
  12. >
  13. <el-form-item
  14. v-for="f in formList"
  15. :key="f.prop"
  16. :label="f.label"
  17. :prop="f.prop"
  18. >
  19. <template>
  20. <template v-if="f.type === 'input'">
  21. <el-input
  22. clearable
  23. v-model.trim="searchDataClone[f.prop]"
  24. size="small"
  25. :placeholder="'请输入' + f.label"
  26. ></el-input>
  27. </template>
  28. <template v-else-if="f.type === 'company'">
  29. <el-select
  30. size="small"
  31. clearable
  32. v-model="searchDataClone[f.prop]"
  33. :placeholder="'请输入' + f.label"
  34. filterable
  35. >
  36. <el-option label="不限" value v-if="f.selectAuto"></el-option>
  37. <el-option
  38. v-for="(s, i) in InsCompanyList"
  39. :key="i"
  40. :label="s.name"
  41. :value="s.id"
  42. ></el-option>
  43. </el-select>
  44. </template>
  45. <template v-else-if="f.type === 'companyCheck'">
  46. <el-select
  47. class="selectLength"
  48. multiple
  49. collapse-tags
  50. size="small"
  51. v-model="searchDataClone[f.prop]"
  52. :placeholder="'请输入' + f.label"
  53. >
  54. <el-option label="不限" value v-if="f.selectAuto"></el-option>
  55. <el-option
  56. v-for="(s, i) in InsCompanyList"
  57. :key="i"
  58. :label="s.name"
  59. :value="s.id"
  60. ></el-option>
  61. </el-select>
  62. </template>
  63. <template v-else-if="f.type === 'select'">
  64. <el-select
  65. size="small"
  66. clearable
  67. filterable
  68. v-model="searchDataClone[f.prop]"
  69. :placeholder="'请输入' + f.label"
  70. >
  71. <el-option label="不限" value v-if="f.selectAuto"></el-option>
  72. <el-option
  73. v-for="(s, i) in f.options"
  74. :key="i"
  75. :label="s.label || s.dictTag"
  76. :value="s.value || s.dictValue"
  77. ></el-option>
  78. </el-select>
  79. </template>
  80. <template v-else-if="f.type === 'selectDept'">
  81. <el-select
  82. size="small"
  83. v-model="searchDataClone[f.prop]"
  84. filterable
  85. clearable
  86. :placeholder="'请选择' + f.label"
  87. @change="selectChange($event, f.prop)"
  88. >
  89. <el-option
  90. v-for="(option, index) in f.options"
  91. :key="index"
  92. :label="f.optionsIabel ? option[f.optionsIabel] : option.name"
  93. :value="f.optionsValue ? option[f.optionsValue] : option.id"
  94. ></el-option>
  95. </el-select>
  96. </template>
  97. <template v-else-if="f.type === 'selectCompany'">
  98. <el-select
  99. size="small"
  100. v-model="searchDataClone[f.prop]"
  101. filterable
  102. clearable
  103. :placeholder="'请选择' + f.label"
  104. @change="selectCompanyChange($event, f.prop)"
  105. >
  106. <el-option
  107. v-for="(option, index) in f.options"
  108. :key="index"
  109. :label="f.optionsIabel ? option[f.optionsIabel] : option.name"
  110. :value="f.optionsValue ? option[f.optionsValue] : option.id"
  111. ></el-option>
  112. </el-select>
  113. </template>
  114. <template v-else-if="f.type === 'datePicker'">
  115. <!-- 日期区间 -->
  116. <el-date-picker
  117. style="width: 215px"
  118. type="daterange"
  119. size="small"
  120. v-model="searchDataClone[f.prop]"
  121. align="right"
  122. unlink-panels
  123. range-separator="-"
  124. start-placeholder="开始时间"
  125. end-placeholder="结束时间"
  126. value-format="yyyy-MM-dd HH:mm:ss"
  127. :default-time="['00:00:00', '23:59:59']"
  128. :clearable="true"
  129. ></el-date-picker>
  130. </template>
  131. <template v-else-if="f.type === 'date'">
  132. <!-- 一天 -->
  133. <el-date-picker
  134. type="date"
  135. size="small"
  136. v-model="searchDataClone[f.prop]"
  137. placeholder="选择日期"
  138. value-format="yyyy-MM-dd"
  139. ></el-date-picker>
  140. </template>
  141. <!-- 年份 -->
  142. <template v-else-if="f.type === 'year'">
  143. <el-date-picker
  144. type="year"
  145. size="small"
  146. v-model="searchDataClone[f.prop]"
  147. placeholder="选择年"
  148. >
  149. </el-date-picker>
  150. </template>
  151. <template v-else-if="f.type === 'radio'">
  152. <el-radio-group
  153. v-model="searchDataClone[f.prop]"
  154. :placeholder="'请输入' + f.label"
  155. >
  156. <el-radio
  157. v-for="(r, i) in f.radioList"
  158. :key="i"
  159. :label="r.value"
  160. >{{ r.label }}</el-radio
  161. >
  162. </el-radio-group>
  163. </template>
  164. <template v-else-if="f.type === 'slot'">
  165. <slot show-overflow-tooltip :name="f.name"></slot>
  166. </template>
  167. </template>
  168. </el-form-item>
  169. <el-form-item>
  170. <el-button
  171. style="margin-left: 30px"
  172. size="small"
  173. @click="resetForm('searchDataClone')"
  174. >重置</el-button
  175. >
  176. <el-button type="primary" size="small" @click="handleSearchList()"
  177. >查询</el-button
  178. >
  179. <template v-if="btnGroup.length > 0">
  180. <span
  181. v-for="(val, idx) in btnGroup"
  182. :key="idx"
  183. style="margin-left: 10px"
  184. >
  185. <slot v-if="val.slot" show-overflow-tooltip :name="val.name"></slot>
  186. <el-button
  187. v-else
  188. :disabled="false || (val.disabled && val.disabled())"
  189. :type="val.type || 'primary'"
  190. size="small"
  191. @click="val.click()"
  192. >{{ val.name }}</el-button
  193. >
  194. </span>
  195. </template>
  196. </el-form-item>
  197. <!-- <el-form-item v-if="btnGroup.length>0" >
  198. <el-button v-for="(val, idx) in btnGroup" :key="idx" :type="val.type || 'primary'" size="small" @click="tabFun(val)">{{ val.name }}</el-button>
  199. </el-form-item> -->
  200. </el-form>
  201. <slot v-if="custom" show-overflow-tooltip></slot>
  202. <el-table
  203. ref="table"
  204. :show-summary="tableConfig.showSummary || false"
  205. :data="data"
  206. border
  207. size="small"
  208. style="width: 100%"
  209. :height="tableConfig.tableHeight || tableHeight"
  210. v-loading="tableConfig.loading"
  211. element-loading-text="数据加载中"
  212. element-loading-spinner="el-icon-loading"
  213. @selection-change="handleSelectionChange"
  214. @select-all="selectAll"
  215. :row-style="{ height: '55px' }"
  216. :cell-style="{ padding: '0px' }"
  217. @current-change="handleCurrentTableChange"
  218. :header-cell-style="{
  219. background: '#F2F7FC',
  220. fontWeight: '700',
  221. color: '#606266',
  222. }"
  223. :cell-class-name="rowClass"
  224. >
  225. <el-table-column
  226. type="selection"
  227. :width="tableConfig.selectionWidth || '50'"
  228. v-if="tableConfig.isCheckBox"
  229. align="center"
  230. />
  231. <el-table-column
  232. type="index"
  233. :width="tableConfig.indexWidth || '50'"
  234. v-if="tableConfig.isShowIndex"
  235. align="center"
  236. label="序号"
  237. />
  238. <template v-for="(item, index) in tableConfig.columns">
  239. <!-- 日期内容 -->
  240. <el-table-column
  241. v-if="item.type === 'date'"
  242. :align="'center'"
  243. :fixed="item.fixed"
  244. :width="item.width || 150"
  245. show-overflow-tooltip
  246. :label="item.label"
  247. :key="item.prop"
  248. >
  249. <template slot-scope="scope">
  250. <div>{{ scope.row[item.prop] | formateDate }}</div>
  251. </template>
  252. </el-table-column>
  253. <!-- 字典项 -->
  254. <el-table-column
  255. v-if="item.type === 'dic'"
  256. :align="'center'"
  257. :width="item.width || ''"
  258. :fixed="item.fixed"
  259. show-overflow-tooltip
  260. :label="item.label"
  261. :key="item.prop"
  262. :prop="item.prop"
  263. >
  264. <template slot-scope="scope">
  265. <span>{{
  266. selectDictLabel(dictData[item.dic], scope.row[item.prop])
  267. }}</span>
  268. </template>
  269. </el-table-column>
  270. <el-table-column
  271. v-if="item.type === 'statMap'"
  272. :align="'center'"
  273. :width="item.width || ''"
  274. :fixed="item.fixed"
  275. show-overflow-tooltip
  276. :label="item.label"
  277. :key="item.prop"
  278. :prop="item.prop"
  279. >
  280. <template slot-scope="scope">
  281. <span>
  282. {{ statMaps(item.options)[scope.row[item.prop]] || "--" }}</span
  283. >
  284. </template>
  285. </el-table-column>
  286. <!-- 自定义内容 -->
  287. <el-table-column
  288. v-if="item.type === 'slot'"
  289. :align="'center'"
  290. show-overflow-tooltip
  291. :name="item.name"
  292. :label="item.label"
  293. :key="item.prop"
  294. :prop="item.prop"
  295. >
  296. <template slot-scope="scope">
  297. <slot show-overflow-tooltip v-bind="scope" :name="item.name"></slot>
  298. </template>
  299. </el-table-column>
  300. <!-- 常规文本内容 -->
  301. <el-table-column
  302. v-if="item.type === 'text'"
  303. :align="'center'"
  304. :width="item.width || ''"
  305. :fixed="item.fixed"
  306. :label="item.label"
  307. :key="item.prop"
  308. :prop="item.prop"
  309. ></el-table-column>
  310. </template>
  311. <!-- <slot name="operate" :row="scope.row"></slot> -->
  312. <!-- 自定义操作栏 -->
  313. <el-table-column
  314. v-if="tableConfig.operateShow"
  315. label="操作"
  316. align="center"
  317. :min-width="tableConfig.operationWidth || '100'"
  318. fixed="right"
  319. >
  320. <template slot-scope="scope">
  321. <slot name="operate" :row="scope.row"></slot>
  322. </template>
  323. </el-table-column>
  324. <!-- 数组形式的操作栏,用于普通按钮 -->
  325. <!-- // optBtns:[
  326. // {
  327. // type:'primary',
  328. // label:'修改',
  329. // hide:(row) => {
  330. // return row.importStatus == 1?true:false
  331. // },
  332. // click:(row, index) => {return this.modifyFun(row)},
  333. // }
  334. // ] -->
  335. <el-table-column
  336. v-if="tableConfig.optBtns"
  337. :min-width="tableConfig.operationWidth || '100'"
  338. label="操作"
  339. fixed="right"
  340. header-align="center"
  341. align="center"
  342. >
  343. <template slot-scope="scope">
  344. <span v-for="(btn, index) in tableConfig.optBtns" :key="index">
  345. <!-- <el-button style="margin:0 10px" v-if="!btn.hide || (btn.hide && btn.hide(scope.row))" v-permission="btn.perm"
  346. @click="btn.click(scope.row, index)" :type="btn.type || 'primary'" :icon="btn.icon" size="small">{{
  347. btn.label
  348. }} </el-button> -->
  349. <kt-button
  350. style="margin: 0 10px"
  351. v-if="!btn.hide || (btn.hide && btn.hide(scope.row))"
  352. :icon="btn.icon"
  353. :label="btn.label"
  354. :type="btn.type || 'primary'"
  355. size="small"
  356. :perms="btn.perm"
  357. @click="btn.click(scope.row, index)"
  358. />
  359. </span>
  360. </template>
  361. </el-table-column>
  362. </el-table>
  363. <!-- 分页 -->
  364. <div class="block" ref="bottomFixed">
  365. <el-pagination
  366. v-if="tableConfig.isPaginationShow && pagination.totalSize"
  367. style="margin-top: 10px"
  368. :page-size="pagination.pageSize"
  369. :current-page.sync="pagination.pageNum"
  370. :total="pagination.totalSize"
  371. layout="total, sizes,prev, pager, next,jumper"
  372. :page-sizes="[10, 20, 50, 100]"
  373. @size-change="handleSizeChange"
  374. @current-change="handleCurrentChange"
  375. />
  376. </div>
  377. </div>
  378. </template>
  379. <script type="text/ecmascript-6">
  380. import KtButton from "@/views/Core/KtButton";
  381. export default {
  382. components: {
  383. KtButton,
  384. },
  385. props: {
  386. custom: {
  387. type: Boolean,
  388. default: () => {
  389. return false;
  390. },
  391. },
  392. formList: {
  393. type: Array,
  394. default: () => {
  395. return [];
  396. },
  397. },
  398. btnGroup: {
  399. type: Array,
  400. default: () => {
  401. return [];
  402. },
  403. },
  404. tableConfig: {
  405. type: Object,
  406. default: () => {
  407. return {};
  408. },
  409. },
  410. // searchDataClone: {
  411. // type: Object,
  412. // default: () => {
  413. // return {};
  414. // }
  415. // },
  416. pagination: {
  417. type: Object,
  418. default: () => ({
  419. pageNum: 1,
  420. pageSize: 20,
  421. totalSize: 0,
  422. }),
  423. },
  424. rowClass: {
  425. type: Function,
  426. default: () => "",
  427. },
  428. data: {
  429. type: Array,
  430. default: () => [],
  431. },
  432. },
  433. data() {
  434. return {
  435. tableHeight: 0,
  436. InsCompanyList: [],
  437. searchDataClone: {},
  438. };
  439. },
  440. created() {
  441. if (
  442. this.formList.length > 0 &&
  443. this.formList.find(
  444. (val) => val.type == "company" || val.type == "companyCheck"
  445. )
  446. ) {
  447. this.companyFun();
  448. }
  449. },
  450. mounted() {
  451. setTimeout(() => {
  452. var divHg = 0;
  453. if (document.getElementById("commonTable") != null) {
  454. divHg = document.getElementById("commonTable").clientHeight;
  455. } else {
  456. divHg = 100;
  457. }
  458. let bottomTop = this.$refs.bottomFixed.offsetTop;
  459. //160??待调整
  460. this.tableHeight = window.innerHeight - divHg - 210 + "px";
  461. }, 10);
  462. },
  463. filters: {
  464. formateDate(val) {
  465. return formatDateTime(val);
  466. },
  467. },
  468. methods: {
  469. selectChange(id, filed) {
  470. switch (filed) {
  471. case "provinceId":
  472. break;
  473. case "cityId":
  474. break;
  475. case "countyId":
  476. break;
  477. default:
  478. break;
  479. }
  480. if (id) {
  481. this.$emit("areaSelectChange", { id, filed });
  482. }
  483. },
  484. selectCompanyChange(id, filed) {
  485. if (id) {
  486. this.$emit("companySelectChange", { id, filed });
  487. }
  488. },
  489. formatDateTime(date) {
  490. let d = new Date(date),
  491. month = "" + (d.getMonth() + 1),
  492. day = "" + d.getDate(),
  493. year = d.getFullYear();
  494. if (month.length < 2) month = "0" + month;
  495. if (day.length < 2) day = "0" + day;
  496. return [year, month, day].join("-");
  497. },
  498. companyFun() {
  499. this.$api.cost.gainTopList({ type: 1 }).then((res) => {
  500. if (res.data) {
  501. this.InsCompanyList = res.data;
  502. }
  503. });
  504. },
  505. statMaps(list) {
  506. if (!list) return;
  507. let obj = {};
  508. list.forEach((item) => {
  509. obj[item.value || item.id] = item.label || item.value;
  510. });
  511. return obj;
  512. },
  513. selectDictLabel(dicts, value) {
  514. if (value === undefined) {
  515. return "";
  516. }
  517. if (dicts === undefined) {
  518. return "";
  519. }
  520. const actions = [];
  521. Object.keys(dicts).some((key) => {
  522. if (dicts[key].value === `${value}`) {
  523. actions.push(dicts[key].label);
  524. return true;
  525. }
  526. });
  527. if (actions.length === 0) {
  528. actions.push(value);
  529. }
  530. return actions.join("");
  531. },
  532. // 表格多选
  533. handleSelectionChange(currentRow) {
  534. this.$emit("selectionChange", currentRow, this.$refs.table);
  535. },
  536. selectAll(currentRow) {
  537. this.$emit("selectAll", currentRow, this.$refs.table);
  538. },
  539. handleSizeChange(value) {
  540. this.pagination.pageSize = value;
  541. this.pagination.pageNum = 1;
  542. this.$emit("getList", { ...this.pagination, ...this.searchDataClone });
  543. },
  544. handleCurrentChange(val) {
  545. this.pagination.pageNum = val;
  546. this.$emit("getList", { ...this.pagination, ...this.searchDataClone });
  547. },
  548. handleCurrentTableChange(val) {
  549. this.$emit("handleCurrentTableChange", val);
  550. },
  551. // 搜索
  552. handleSearchList() {
  553. // 更新父组件searchData
  554. this.pagination.pageNum = 1;
  555. this.pagination.pageSize = 10; //查询添加默认每页20条
  556. this.$emit("handleSearchList", this.searchDataClone);
  557. },
  558. // 重置
  559. resetForm(formName) {
  560. this.$emit("handleResetForm");
  561. this.searchDataClone = {};
  562. console.log(this.searchDataClone);
  563. // this.$refs[formName].resetFields();
  564. this.handleSearchList();
  565. },
  566. handleOpt(row, index) {
  567. this.$emit("handleOpt", row, index);
  568. },
  569. },
  570. };
  571. </script>
  572. <style scoped>
  573. .selectLength /deep/ .el-select__tags-text {
  574. display: inline-block;
  575. max-width: 110px;
  576. overflow: hidden;
  577. text-overflow: ellipsis;
  578. white-space: nowrap;
  579. }
  580. .device-wrapper /deep/ .el-form-item {
  581. margin-bottom: 12px;
  582. }
  583. </style>