index.vue 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902
  1. <template>
  2. <div class="header-actions" v-if="getActionList.length != 0 &&getActionList.length>2">
  3. <div class="overflow-box">
  4. <el-button v-for="(item, index) in getActionList" :key="index" :type="item.type || 'primary'" :plain="item.plain || false"
  5. v-bind="getHeaderActions(item)" @click="item.action" :disabled="item.disabled || false">
  6. {{ item.text }}
  7. </el-button>
  8. </div>
  9. </div>
  10. <div class="stat-warp" v-if="statConfig.length != 0" :class="statWarpHeight > 200 && isMore ? 'show-more' : ''">
  11. <div class="title">
  12. <select v-model="statSelectVal" v-if="statConfig.length > 1" @change="changeStatData">
  13. <option :value="index" v-for="(i, index) in statConfig" :key="index">
  14. {{ i.label }}
  15. </option>
  16. </select>
  17. <div v-if="statConfig.length === 1">{{ statConfig[0].label }}</div>
  18. </div>
  19. <div class="more-btn" @click="isMore = !isMore" v-if="statWarpHeight > 200">
  20. <span>
  21. <i v-if="!isMore" class="iconfont icon-btn_xiala22"></i>
  22. <i v-else class="iconfont icon-btn_shouqi22"></i>
  23. </span>
  24. </div>
  25. <ul id="statWarp">
  26. <li v-show="!i.data" :class="'theme' + i.type" v-for="(i, index) in statConfig[statSelectVal].data" :key="index"
  27. @click="i.click ? i.click(i, index) : ''" :style="i.click ? 'cursor: pointer' : ''">
  28. <div class="label">{{ i.label }}</div>
  29. <div class="num">{{ i.num }}</div>
  30. </li>
  31. <li v-show="i.data" v-for="(i, index) in statConfig[statSelectVal].data" :key="index" class="multi-data" :class="'theme' + i.type"
  32. @click="i.click ? i.click(i, index) : ''" :style="i.click ? 'cursor: pointer' : ''">
  33. <div class="label">{{ i.label }}</div>
  34. <div class="num-warp">
  35. <div class="num-box" v-for="(j, jindex) in i.data" :key="jindex">
  36. <div class="num-small" :style="'color:' + j.color">
  37. {{ j.num }}
  38. </div>
  39. <div class="label-small">{{ j.label }}</div>
  40. </div>
  41. </div>
  42. </li>
  43. </ul>
  44. </div>
  45. <div class="table-list-container by-table" v-loading="loading" v-if="!hideAll">
  46. <!-- v-if="!hideHeader" -->
  47. <header v-if="false" class="header">
  48. <h2>{{ title }}</h2>
  49. </header>
  50. <div class="by-search" v-if="!hideSearch">
  51. <div style="display: flex">
  52. <div v-if="getActionList.length != 0 &&getActionList.length <=2" style="margin-right:10px">
  53. <el-button v-for="(item, index) in getActionList" :key="index" :type="item.type || 'primary'" :plain="item.plain || false"
  54. v-bind="getHeaderActions(item)" @click="item.action" :disabled="item.disabled || false">
  55. {{ item.text }}
  56. </el-button>
  57. </div>
  58. <div class="by-dropdown" v-for="(i, index) in selectConfigCopy" :key="i.prop" style="margin-right: 10px">
  59. <div v-if="i.type" class="selectTime" style="display:flex;align-items:center">
  60. <span style="font-size:12px;height:32px;margin-right:15px">{{i.label || ''}}</span>
  61. <el-date-picker v-model="pagination[i.prop]" :type="i.itemType?i.itemType:'date'" size="small" :placeholder="i.placeholder"
  62. style="width:120px" :value-format="dateFormatInit(i.itemType)"
  63. @change="i.fn?i.fn(pagination[i.prop]):searchItemSelctOne(i,pagination[i.prop],pagination[i.propOne])"
  64. :clearable="i.clearable!=undefined?i.clearable :true" />
  65. <span style="margin-right:25px" v-if="i.propOne">-</span>
  66. <el-date-picker v-model="pagination[i.propOne]" v-if="i.propOne" :type="i.itemType?i.itemType:'date'" size="small"
  67. :placeholder="i.placeholderOne" style="width:120px" :value-format="dateFormatInit(i.itemType)"
  68. @change="i.fn?i.fn(pagination[i.propOne]):searchItemSelctOne(i,pagination[i.prop],pagination[i.propOne])"
  69. :clearable="i.clearable!=undefined?i.clearable :true" />
  70. </div>
  71. <div v-else>
  72. <div class="by-dropdown-title">
  73. {{getSelectLabel(pagination[i.prop],i) || i.label || i.labelCopy}}
  74. <i style="margin-left: 5px" class="iconfont icon-iconm_xialan1"></i>
  75. </div>
  76. <ul class="by-dropdown-lists">
  77. <li @click="searchItemSelct('all', i, index)" v-if="i.isShowAll === false ? i.isShowAll : true" style="">
  78. {{ $t("common.all") }}
  79. </li>
  80. <li v-for="j in i.data" :key="j.value || j.dictKey" @click="searchItemSelct(j, i)" style="">
  81. {{ j.label || j.dictValue }}
  82. </li>
  83. </ul>
  84. </div>
  85. </div>
  86. </div>
  87. <div style="display: flex;align-items:center">
  88. <el-input :placeholder="$t('common.pleaseEnterKeywords')" style="font-size:12px" suffix-icon="search" size="mini" v-model="pagination.keyword"
  89. @keyup.enter="searchFn">
  90. </el-input>
  91. <el-icon :size="16" style="cursor:pointer;margin-left: 10px" @click="searchFn">
  92. <Search />
  93. </el-icon>
  94. <el-icon :size="16" style="cursor:pointer;margin-left: 10px" @click="searchReset">
  95. <Refresh />
  96. </el-icon>
  97. <div class="more-icon" @click="retrievalModalFn" v-if="false">
  98. <i class="iconfont icon-iconx_saixuan"></i>
  99. </div>
  100. </div>
  101. </div>
  102. <component :is="containerTag">
  103. <div class="filter-form-container">
  104. <slot />
  105. </div>
  106. <el-table ref="hocElTable" :data="source" v-if="!hideTable" style="width: 100%" v-bind="$attrs" v-on="tableEvents" row-key="id" :tree-props="{
  107. children: 'children',
  108. hasChildren: 'hasChildren',
  109. }" :height="tableHeight">
  110. <el-table-column v-for="(item, index) in configData" :key="index" v-bind="getAttrsValue(item)" :type="item.type || ''" :selectable="
  111. (rowData, rowIndex) => isSelectable(rowData, rowIndex, item)
  112. ">
  113. <template #header v-if="item.attrs.isNeedHeaderSlot">
  114. <slot :name="item.attrs.headerSlot" :headerLabel="item.attrs.label" v-if="item.attrs.headerSlot">
  115. 头部插槽占位符
  116. </slot>
  117. </template>
  118. <template #default="scope" v-if="!item.type">
  119. <slot :name="item.attrs.slot" :item="scope.row" :headerLabel="item.attrs.label" v-if="item.attrs.slot">
  120. 插槽占位符
  121. </slot>
  122. <div v-else-if="isFunction(getValue(scope, item))">
  123. <component :is="renderTypeList[getMatchRenderFunction(item)].target" :cell-list="getValue(scope, item)()" :row="scope.row"
  124. :parent="getParent" @click="
  125. ($event) => {
  126. handleNativeClick(getAttrsValue(item), $event, item);
  127. }
  128. " />
  129. </div>
  130. <div v-else>
  131. {{ getValue(scope, item) }}
  132. </div>
  133. </template>
  134. </el-table-column>
  135. </el-table>
  136. <el-row v-if="!hidePagination" class="table-pagination" justify="end" type="flex">
  137. <el-pagination background layout="total, sizes, prev, pager, next, jumper" :current-page="getPagination.pageNum"
  138. :page-size="getPagination.pageSize" :total="getPagination.total" @size-change="handleSizeChange"
  139. @current-change="handlePageChange" />
  140. </el-row>
  141. </component>
  142. </div>
  143. </template>
  144. <script>
  145. import { isFunction as isFn, isBoolean } from "./type";
  146. import ElementsMapping from "./ElementsMapping";
  147. import ComponentsMapping from "./ComponentsMapping";
  148. import { computed, defineComponent, getCurrentInstance, ref, watch } from "vue";
  149. import expand from "./expand";
  150. import Sortable from "sortablejs";
  151. export default defineComponent({
  152. name: "Table",
  153. components: {
  154. ElementsMapping,
  155. ComponentsMapping,
  156. },
  157. props: {
  158. hideSearch: {
  159. type: Boolean,
  160. default: false,
  161. },
  162. onMoreSearch: {
  163. type: Boolean,
  164. default: false,
  165. },
  166. hideAll: {
  167. type: Boolean,
  168. default: false,
  169. },
  170. hideTable: {
  171. type: Boolean,
  172. default: false,
  173. },
  174. //顶部搜索下拉配置
  175. selectConfig: {
  176. type: Array,
  177. default() {
  178. return [];
  179. },
  180. },
  181. // 获取表格元数据时携带的参数
  182. filterParams: {
  183. type: Object,
  184. default() {
  185. return {};
  186. },
  187. },
  188. // 表格加载 loading
  189. loading: {
  190. type: Boolean,
  191. default: false,
  192. },
  193. // 表格名称
  194. title: {
  195. type: String,
  196. default: "",
  197. },
  198. // 表格元数据
  199. source: {
  200. type: Array,
  201. required: true,
  202. default() {
  203. return [];
  204. },
  205. },
  206. // tableHeight: {
  207. // type: Number,
  208. // required: false,
  209. // },
  210. searchConfig: {
  211. type: Object,
  212. default() {
  213. return {
  214. keyword: "",
  215. };
  216. },
  217. },
  218. statConfig: {
  219. type: Array,
  220. default() {
  221. return [];
  222. },
  223. },
  224. // 指定外层容器的渲染组件
  225. containerTag: {
  226. type: String,
  227. default: "div",
  228. },
  229. // 是否隐藏表头
  230. hideHeader: {
  231. type: Boolean,
  232. default: false,
  233. },
  234. // 是否隐藏分页
  235. hidePagination: {
  236. type: Boolean,
  237. default: false,
  238. },
  239. // 分页配置
  240. pagination: {
  241. type: Object,
  242. default() {
  243. return {};
  244. },
  245. },
  246. // 表格配置文件
  247. config: {
  248. type: Array,
  249. default() {
  250. return [];
  251. },
  252. },
  253. // 表头右上方的按钮组
  254. actionList: {
  255. type: Array,
  256. default() {
  257. return [{ text: "", action: () => {} }];
  258. },
  259. },
  260. // element table 原生事件
  261. tableEvents: {
  262. type: Object,
  263. default() {
  264. return {};
  265. },
  266. },
  267. searchKey: {
  268. type: String,
  269. default: "keyword",
  270. },
  271. // 是否显示过滤的全部选项
  272. // isShowAll: {
  273. // type: Boolean,
  274. // default: true,
  275. // },
  276. },
  277. setup(props) {
  278. const tableHeight = ref(0);
  279. const getTableHeight = () => {
  280. // if (window.innerHeight >= 920) {
  281. // tableHeight.value = 650;
  282. // } else {
  283. // tableHeight.value = 550;
  284. // }
  285. tableHeight.value = window.innerHeight - 225;
  286. };
  287. getTableHeight();
  288. window.addEventListener("resize", () => {
  289. getTableHeight();
  290. });
  291. const { proxy } = getCurrentInstance();
  292. // 过滤出有属性的
  293. // const configData = ref([]);
  294. // configData.value = proxy.config.filter((x) => x && x.attrs);
  295. const configData = computed(() => proxy.config.filter((x) => x && x.attrs));
  296. // console.log(configData.value, "ssssssssss");
  297. const selectConfigCopy = computed(() => {
  298. return props.selectConfig.map((item) => {
  299. if (!item.labelCopy) item.labelCopy = { ...item }.label;
  300. return item;
  301. });
  302. });
  303. let isMore = ref(false);
  304. const changeStatData = () => {
  305. statWarpHeight.value = document.getElementById("statWarp").offsetHeight;
  306. };
  307. let statWarpHeight = ref(0);
  308. watch(
  309. proxy.statConfig,
  310. (newValue, oldValue) => {
  311. setTimeout(() => {
  312. //获取statWarp的height
  313. statWarpHeight.value =
  314. document.getElementById("statWarp").offsetHeight;
  315. }, 500);
  316. },
  317. { immediate: true }
  318. );
  319. let statSelectVal = ref(0);
  320. const retrievalModal = ref(false);
  321. const getAttrsValue = (item) => {
  322. const { attrs } = item;
  323. const result = {
  324. ...attrs,
  325. };
  326. delete result.prop;
  327. return result;
  328. };
  329. const renderTypeList = ref({
  330. render: {},
  331. renderHTML: {
  332. target: "elements-mapping",
  333. },
  334. renderComponent: {
  335. target: "components-mapping",
  336. },
  337. renderMoreBtn: {
  338. target: "more-btn",
  339. },
  340. });
  341. const getParent = computed(() => {
  342. return proxy.$parent;
  343. });
  344. // 复制过滤条件
  345. // const firstValue = ref(true);
  346. const paginationCopy = ref({});
  347. // if (firstValue.value) {
  348. // paginationCopy.value = Object.freeze(proxy.deepClone(props.pagination));
  349. // firstValue.value = false;
  350. // }
  351. paginationCopy.value = Object.freeze(proxy.deepClone(props.pagination));
  352. const getPagination = computed(() => {
  353. const params = {
  354. pageNum: 1,
  355. pageSize: 10,
  356. total: 0,
  357. };
  358. return Object.assign({}, params, props.pagination);
  359. });
  360. const getActionList = computed(() => {
  361. return props.actionList
  362. .slice()
  363. .reverse()
  364. .filter((it) => it.text);
  365. });
  366. const getValue = (scope, configItem) => {
  367. const prop = configItem.attrs.prop;
  368. const renderName = getMatchRenderFunction(configItem);
  369. const renderObj = renderTypeList.value[renderName];
  370. if (renderObj && isFunction(configItem[renderName])) {
  371. return renderObj.target
  372. ? getRenderValue(scope, configItem, {
  373. name: renderName,
  374. type: "bind",
  375. })
  376. : getRenderValue(scope, configItem);
  377. }
  378. return scope.row[prop];
  379. };
  380. const getRenderValue = (
  381. scope,
  382. item,
  383. fn = { name: "render", type: "call" }
  384. ) => {
  385. const prop = item.attrs.prop;
  386. const propValue = prop && scope.row[prop];
  387. scope.row.$index = scope.$index;
  388. const args = propValue !== undefined ? propValue : scope.row;
  389. return item[fn.name][fn.type](getParent.value, args);
  390. };
  391. // 匹配 render 开头的函数
  392. const getMatchRenderFunction = (obj) => {
  393. return Object.keys(obj).find((key) => {
  394. const matchRender = key.match(/^render.*/);
  395. return matchRender && matchRender[0];
  396. });
  397. };
  398. const isFunction = (fn) => {
  399. return isFn(fn);
  400. };
  401. const searchFn = (val) => {
  402. if (props.loading) return;
  403. proxy.$emit(
  404. "getList",
  405. Object.assign(props.filterParams, {
  406. [props.searchKey]: props.pagination.keyword,
  407. })
  408. );
  409. };
  410. const retrievalModalFn = () => {
  411. proxy.$emit("moreSearch", "");
  412. //获取父组件定义的moreSearch方法
  413. };
  414. const searchReset = () => {
  415. proxy.$emit(
  416. "getList",
  417. Object.assign(props.filterParams, {
  418. type: "",
  419. status: "",
  420. ...paginationCopy.value,
  421. })
  422. );
  423. };
  424. const handlePageChange = (val) => {
  425. proxy.$emit(
  426. "getList",
  427. Object.assign(props.filterParams, { pageNum: val })
  428. );
  429. };
  430. const handleSizeChange = (val) => {
  431. proxy.$emit(
  432. "getList",
  433. Object.assign(props.filterParams, { pageSize: val })
  434. );
  435. };
  436. const getHeaderActions = (item) => {
  437. return {
  438. ...item.attrs,
  439. };
  440. };
  441. const stopBubbles = (e) => {
  442. const event = e || window.event;
  443. if (event && event.stopPropagation) {
  444. event.stopPropagation();
  445. } else {
  446. event.cancelBubble = true;
  447. }
  448. };
  449. const handleNativeClick = ({ isBubble }, e, item) => {
  450. // 考虑到单元格内渲染了组件,并且组件自身可能含有点击事件,故添加了阻止冒泡机制
  451. // 若指定 isBubble 为 false,则当前单元格恢复冒泡机制
  452. if (isBoolean(isBubble) && !isBubble) return;
  453. stopBubbles(e);
  454. };
  455. //下拉搜索相关
  456. const searchItemSelct = (item, i, index) => {
  457. if (item == "all") {
  458. // i.label = { ...props.selectConfig[index] }.labelCopy;
  459. i.label = props.selectConfig[index].labelCopy;
  460. proxy.$emit(
  461. "getList",
  462. Object.assign(props.filterParams, { [i.prop]: "" })
  463. );
  464. return;
  465. }
  466. i.label = item.label || item.dictValue;
  467. let value = null;
  468. if (item.value !== "" && item.value != undefined) {
  469. value = item.value;
  470. } else if (item.dictKey !== "" && item.dictKey != undefined) {
  471. value = item.dictKey;
  472. } else {
  473. console.log("过滤");
  474. }
  475. proxy.$emit(
  476. "getList",
  477. Object.assign(props.filterParams, {
  478. [i.prop]: value,
  479. })
  480. );
  481. };
  482. const getSelectLabel = (value, item) => {
  483. if (value !== "" && value != undefined) {
  484. let current = item.data.find(
  485. (x) => x.value == value || x.dictKey == value
  486. );
  487. if (current) {
  488. if (current.label) {
  489. return current.label;
  490. }
  491. if (current.dictValue) {
  492. return current.dictValue;
  493. }
  494. }
  495. } else {
  496. return item.labelCopy;
  497. }
  498. };
  499. const dateFormatInit = (itemType) => {
  500. if (!itemType) {
  501. return "YYYY-MM-DD HH:mm:ss";
  502. }
  503. const formatObj = {
  504. year: "YYYY",
  505. month: "YYYY-MM",
  506. date: "YYYY-MM-DD HH:mm:ss",
  507. dates: "YYYY-MM-DD",
  508. datetime: "YYYY-MM-DD HH:mm:ss",
  509. monthrange: "YYYY-MM-DD HH:mm:ss",
  510. datetimerange: "YYYY-MM-DD HH:mm:ss",
  511. daterange: "YYYY-MM-DD HH:mm:ss",
  512. };
  513. return formatObj[itemType];
  514. };
  515. const searchItemSelctOne = (item, prop, propOne) => {
  516. if (prop && propOne) {
  517. let str = "";
  518. let end = "";
  519. if (prop.includes(":")) {
  520. str = prop.substr(0, 10);
  521. }
  522. if (propOne.includes(":")) {
  523. end = propOne.substr(0, 10);
  524. }
  525. proxy.$emit(
  526. "getList",
  527. Object.assign(props.filterParams, {
  528. [item.prop]: str + " 00:00:00",
  529. [item.propOne]: end + " 23:59:59",
  530. })
  531. );
  532. } else if (prop == null && propOne == null) {
  533. proxy.$emit(
  534. "getList",
  535. Object.assign(props.filterParams, {
  536. [item.prop]: "",
  537. [item.propOne]: "",
  538. })
  539. );
  540. }
  541. };
  542. const isSelectable = (row, index, item) => {
  543. if (item.type === "selection") {
  544. if (item.attrs && item.attrs.checkAtt) {
  545. if (row[item.attrs.checkAtt]) {
  546. return row[item.attrs.checkAtt];
  547. }
  548. } else {
  549. return true;
  550. }
  551. }
  552. };
  553. const hocElTable = ref();
  554. return {
  555. tableHeight,
  556. configData,
  557. getParent,
  558. getPagination,
  559. renderTypeList,
  560. getActionList,
  561. getAttrsValue,
  562. getValue,
  563. getRenderValue,
  564. getMatchRenderFunction,
  565. isFunction,
  566. handlePageChange,
  567. handleSizeChange,
  568. getHeaderActions,
  569. stopBubbles,
  570. handleNativeClick,
  571. searchFn,
  572. searchItemSelct,
  573. getSelectLabel,
  574. dateFormatInit,
  575. searchItemSelctOne,
  576. selectConfigCopy,
  577. isSelectable,
  578. retrievalModal,
  579. retrievalModalFn,
  580. searchReset,
  581. statSelectVal,
  582. statWarpHeight,
  583. isMore,
  584. changeStatData,
  585. hocElTable,
  586. };
  587. },
  588. });
  589. </script>
  590. <style>
  591. .table-list-container th {
  592. color: #333 !important;
  593. }
  594. .by-table td .el-button + .el-button {
  595. margin-left: 0 !important;
  596. }
  597. .by-table td .el-button {
  598. background: none !important;
  599. margin: 0 !important;
  600. padding: 8px 6px !important;
  601. }
  602. .el-checkbox__input.is-disabled .el-checkbox__inner {
  603. background-color: #dee1e6;
  604. border-color: #b2b4b9;
  605. }
  606. .el-table .cell {
  607. line-height: 34px;
  608. }
  609. </style>
  610. <style lang="scss" scoped>
  611. .sortableActive {
  612. background: #f5f7fa !important;
  613. }
  614. .show-more {
  615. height: auto !important;
  616. }
  617. .stat-warp {
  618. margin-bottom: 20px;
  619. background: #fff;
  620. padding: 0 20px;
  621. height: 200px;
  622. overflow: hidden;
  623. position: relative;
  624. .more-btn {
  625. position: absolute;
  626. right: 0;
  627. bottom: 0;
  628. left: 0;
  629. height: 40px;
  630. cursor: pointer;
  631. font-size: 12px;
  632. line-height: 30px;
  633. text-align: center;
  634. background: linear-gradient(
  635. 180deg,
  636. rgba(255, 255, 255, 0) 0%,
  637. rgba(255, 255, 255, 0.8) 100%
  638. );
  639. i {
  640. color: #999;
  641. }
  642. }
  643. .title {
  644. height: 60px;
  645. select {
  646. height: 60px;
  647. border: none;
  648. outline: none;
  649. -webkit-appearance: none;
  650. appearance: none;
  651. font-size: 12px;
  652. font-weight: bold;
  653. background: url("@/assets/images/sanjiao.png") no-repeat right center;
  654. padding-right: 20px;
  655. }
  656. div {
  657. height: 60px;
  658. font-size: 12px;
  659. font-weight: bold;
  660. line-height: 60px;
  661. }
  662. }
  663. ul {
  664. padding: 0;
  665. overflow: hidden;
  666. margin: 0;
  667. li {
  668. list-style: none;
  669. min-width: 285px;
  670. box-sizing: border-box;
  671. margin: 0 20px 20px 0;
  672. background: #eff6ff;
  673. float: left;
  674. overflow: hidden;
  675. padding: 20px;
  676. color: #333333;
  677. border-radius: 10px;
  678. .label {
  679. font-size: 12px;
  680. }
  681. .label::before {
  682. width: 10px;
  683. height: 10px;
  684. content: "";
  685. border-radius: 50%;
  686. background: #0084ff;
  687. display: inline-block;
  688. margin-right: 10px;
  689. }
  690. .num {
  691. margin-top: 10px;
  692. font-size: 24px;
  693. font-weight: bold;
  694. }
  695. }
  696. //#F5F3FF #9E64ED
  697. .theme2 {
  698. background: #f5f3ff;
  699. .label::before {
  700. background: #9e64ed;
  701. }
  702. }
  703. //#FFF1E1 #FF9315
  704. .theme3 {
  705. background: #fff1e1;
  706. .label::before {
  707. background: #ff9315;
  708. }
  709. }
  710. //#E2FBE8 #39C55A
  711. .theme4 {
  712. background: #e2fbe8;
  713. .label::before {
  714. background: #39c55a;
  715. }
  716. }
  717. .theme5 {
  718. background: #ffebe9;
  719. .label::before {
  720. background: #f94539;
  721. }
  722. }
  723. .theme6 {
  724. background: #e4f9f9;
  725. .label::before {
  726. background: #53cbcb;
  727. }
  728. }
  729. .multi-data {
  730. .label::before {
  731. display: none;
  732. }
  733. .label {
  734. font-size: 12px;
  735. font-weight: bold;
  736. color: #333;
  737. margin-bottom: 8px;
  738. }
  739. .num-warp {
  740. overflow: hidden;
  741. .num-box {
  742. float: left;
  743. min-width: 80px;
  744. margin-right: 20px;
  745. .num-small {
  746. font-size: 16px;
  747. font-weight: bold;
  748. margin-bottom: 8px;
  749. }
  750. .label-small {
  751. color: #666;
  752. font-size: 12px;
  753. }
  754. }
  755. }
  756. }
  757. }
  758. }
  759. .by-search {
  760. display: flex;
  761. justify-content: space-between;
  762. margin-bottom: 10px;
  763. .more-icon {
  764. float: right;
  765. cursor: pointer;
  766. line-height: 32px;
  767. text-align: center;
  768. margin-left: 5px;
  769. }
  770. }
  771. .by-dropdown {
  772. position: relative;
  773. text-align: left;
  774. height: 32px;
  775. z-index: 1010;
  776. padding: 0 10px;
  777. transition: all 0.5s ease;
  778. cursor: pointer;
  779. line-height: 32px;
  780. .by-dropdown-title {
  781. font-size: 12px;
  782. background-color: #fff;
  783. }
  784. ul {
  785. position: absolute;
  786. left: 0;
  787. top: 32px;
  788. padding: 0;
  789. margin: 0;
  790. z-index: 100;
  791. display: none;
  792. white-space: nowrap;
  793. min-width: 80px;
  794. li {
  795. list-style: none;
  796. font-size: 12px;
  797. height: 30px;
  798. padding: 0 10px;
  799. text-align: left;
  800. line-height: 30px;
  801. }
  802. li:hover {
  803. background-color: #eff6ff;
  804. color: #0084ff;
  805. }
  806. }
  807. }
  808. .by-dropdown::before {
  809. display: block;
  810. width: 1px;
  811. content: " ";
  812. position: absolute;
  813. height: 14px;
  814. top: 8px;
  815. background-color: #ddd;
  816. right: 0;
  817. z-index: 1011;
  818. }
  819. .by-dropdown:hover {
  820. background: #ffffff;
  821. border-radius: 2px 2px 2px 2px;
  822. opacity: 1;
  823. ul {
  824. background: #ffffff;
  825. box-shadow: 0px 2px 16px 1px rgba(0, 0, 0, 0.06);
  826. border-radius: 2px 2px 2px 2px;
  827. opacity: 1;
  828. display: block;
  829. text-align: left;
  830. }
  831. }
  832. .header-actions {
  833. flex: 1;
  834. overflow-x: auto;
  835. padding: 20px;
  836. background: #fff;
  837. margin-bottom: 20px;
  838. .overflow-box {
  839. :deep() .el-button:nth-child(1) {
  840. margin-left: 10px;
  841. }
  842. }
  843. }
  844. .table-list-container {
  845. background: #fff;
  846. padding: 15px 15px 10px 15px;
  847. .table-pagination {
  848. padding-top: 5px;
  849. }
  850. .header {
  851. display: flex;
  852. padding-bottom: 20px;
  853. }
  854. .el-table {
  855. :deep() th {
  856. font-size: 12px;
  857. }
  858. :deep() td {
  859. font-size: 12px;
  860. }
  861. }
  862. }
  863. .by-dropdown-lists {
  864. max-height: 50vh;
  865. overflow-y: auto;
  866. line-height: 1;
  867. }
  868. :deep(.selectTime .el-input__wrapper) {
  869. box-shadow: none;
  870. }
  871. :deep(.selectTime .el-input__inner) {
  872. color: #000 !important;
  873. font-size: 12px !important;
  874. }
  875. :deep(.selectTime .el-input .el-input__icon) {
  876. color: #000 !important;
  877. font-size: 12px !important;
  878. }
  879. </style>