securityCheckHeader.vue 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588
  1. <template>
  2. <div class="security-check-header">
  3. <template v-if="title">
  4. <div class="title">{{ title }}</div>
  5. </template>
  6. <a-form
  7. ref="form"
  8. class="form"
  9. name="basic"
  10. :model="formData"
  11. @keyup.enter.native="search"
  12. >
  13. <template v-if="withChangeButton">
  14. <a-form-item style="margin-right: 16px">
  15. <a-button
  16. size="small"
  17. :class="['btn-icon-only', { 'icon-change': !changeButtonLoading }]"
  18. :loading="changeButtonLoading"
  19. @click="change"
  20. />
  21. </a-form-item>
  22. </template>
  23. <template v-if="withDatePicker">
  24. <a-form-item prop="beginDate" style="margin-right: 8px">
  25. <a-date-picker
  26. v-model="formData.beginDate"
  27. type="date"
  28. size="small"
  29. format="YYYY-MM-DD"
  30. />
  31. </a-form-item>
  32. <a-form-item prop="endDate" style="margin-right: 36px">
  33. <a-date-picker
  34. v-model="formData.endDate"
  35. type="date"
  36. size="small"
  37. format="YYYY-MM-DD"
  38. />
  39. </a-form-item>
  40. <a-form-item
  41. prop="dateRangeRadio"
  42. class="radio-wrapper"
  43. style="margin-right: 36px"
  44. >
  45. <a-radio-group v-model="formData.dateRangeRadio" size="small">
  46. <a-radio-button
  47. value="当日"
  48. :class="formData.dateRangeRadio == '当日' ? 'btn-mo' : 'btn-mos'"
  49. style="border-right: none"
  50. ><div class="btn-day">当日</div></a-radio-button
  51. >
  52. <a-radio-button
  53. value="当月"
  54. :class="formData.dateRangeRadio == '当月' ? 'btn-mo' : 'btn-mos'"
  55. ><div class="btn-day">当月</div></a-radio-button
  56. >
  57. <a-radio-button
  58. value="当年"
  59. style="border-left: none"
  60. :class="formData.dateRangeRadio == '当年' ? 'btn-mo' : 'btn-mos'"
  61. ><div class="btn-day">当年</div></a-radio-button
  62. >
  63. </a-radio-group>
  64. </a-form-item>
  65. </template>
  66. <template v-if="withSelect">
  67. <a-form-item prop="selection" style="margin-right: 16px">
  68. <a-select :default-value="optionLists[0].name" @change="handleChange">
  69. <a-select-option
  70. v-for="item in optionLists"
  71. :key="item.name"
  72. :value="item.name"
  73. :title="item.label"
  74. >
  75. {{ item.name }}
  76. </a-select-option>
  77. </a-select>
  78. <!-- <a-select
  79. v-model="formData.selection"
  80. size="small"
  81. :default-value="optionLists[0]"
  82. >
  83. <a-select-option
  84. v-for="option in optionList"
  85. :key="option.value"
  86. :value="option.value"
  87. :label="option.label"
  88. />
  89. </a-select> -->
  90. </a-form-item>
  91. </template>
  92. <template v-if="withInput">
  93. <a-form-item prop="searchText" style="margin-right: 8px">
  94. <a-auto-complete
  95. ref="autocomplete"
  96. v-model="formData.searchText"
  97. size="small"
  98. prefix-icon="el-icon-search"
  99. :trigger-on-focus="false"
  100. :fetch-suggestions="querySearch"
  101. value-key="name"
  102. :placeholder="searchPlaceholder"
  103. clearable
  104. @clear="inputClearHandler"
  105. />
  106. </a-form-item>
  107. </template>
  108. <template v-if="withSearchButton">
  109. <a-form-item style="margin-right: 16px">
  110. <a-button size="small" type="primary" @click="search">查询</a-button>
  111. </a-form-item>
  112. <!-- <a-form-item style="margin-right: 24px">
  113. <a-button size="small" class="btn-white" @click="resetSearch"
  114. >重置</a-button
  115. >
  116. </a-form-item> -->
  117. </template>
  118. <template v-if="withExportButton">
  119. <a-form-item>
  120. <a-button size="small" class="btn-icon-only icon-export" />
  121. </a-form-item>
  122. </template>
  123. </a-form>
  124. </div>
  125. </template>
  126. <script>
  127. export default {
  128. props: {
  129. title: {
  130. type: String,
  131. default: "",
  132. },
  133. withChangeButton: {
  134. type: Boolean,
  135. default: true,
  136. },
  137. withDatePicker: {
  138. type: Boolean,
  139. default: true,
  140. },
  141. withSelect: {
  142. type: Boolean,
  143. default: true,
  144. },
  145. // 传入下拉选项
  146. selectOptions: {
  147. type: Array,
  148. default: () => [],
  149. },
  150. selectPlaceholder: {
  151. type: String,
  152. default: "全部代理人等级",
  153. },
  154. withInput: {
  155. type: Boolean,
  156. default: true,
  157. },
  158. searchPlaceholder: {
  159. type: String,
  160. default: "请输入代理人名称",
  161. },
  162. // 传入输入框自动填充项
  163. inputOptions: {
  164. type: Array,
  165. default: () => [],
  166. },
  167. withSearchButton: {
  168. type: Boolean,
  169. default: true,
  170. },
  171. withExportButton: {
  172. type: Boolean,
  173. default: true,
  174. },
  175. },
  176. data() {
  177. return {
  178. changeButtonLoading: false,
  179. optionLists: [
  180. {
  181. name: "全部",
  182. lable: "",
  183. },
  184. {
  185. name: "A",
  186. lable: "A",
  187. },
  188. {
  189. name: "B",
  190. lable: "B",
  191. },
  192. {
  193. name: "C",
  194. lable: "C",
  195. },
  196. {
  197. name: "D",
  198. lable: "D",
  199. },
  200. ],
  201. // optionLists: ["", "A", "B", "C", "D"],
  202. formData: {
  203. beginDate: "",
  204. endDate: "",
  205. dateRangeRadio: "",
  206. selection: "",
  207. searchText: "",
  208. },
  209. optionList: [],
  210. inputList: [
  211. {
  212. id: 1,
  213. name: "陈睿",
  214. },
  215. {
  216. id: 2,
  217. name: "赵科",
  218. },
  219. ],
  220. };
  221. },
  222. watch: {
  223. "formData.dateRangeRadio": {
  224. handler(val) {
  225. function formatNumber(num) {
  226. return num < 10 ? "0" + num : num;
  227. }
  228. function getLastDayOfMonth(year, month) {
  229. if (month === 2) {
  230. if ((year % 4 === 0 && year % 100 !== 0) || year % 400 === 0) {
  231. return 29;
  232. } else {
  233. return 28;
  234. }
  235. } else if ([1, 3, 5, 7, 8, 10, 12].includes(month)) {
  236. return 31;
  237. } else {
  238. return 30;
  239. }
  240. }
  241. const now = new Date();
  242. const year = now.getFullYear();
  243. const month = now.getMonth() + 1;
  244. const date = now.getDate();
  245. switch (val) {
  246. case "当日":
  247. this.formData.beginDate =
  248. this.formData.endDate = `${year}-${formatNumber(
  249. month
  250. )}-${formatNumber(date)}`;
  251. break;
  252. case "当月":
  253. this.formData.beginDate = `${year}-${formatNumber(month)}-01`;
  254. this.formData.endDate = `${year}-${formatNumber(
  255. month
  256. )}-${getLastDayOfMonth(year, month)}`;
  257. break;
  258. case "当年":
  259. this.formData.beginDate = `${year}-01-01`;
  260. this.formData.endDate = `${year}-12-31`;
  261. break;
  262. default:
  263. break;
  264. }
  265. this.search();
  266. },
  267. },
  268. "formData.beginDate": {
  269. handler(val) {
  270. this.search();
  271. },
  272. },
  273. "formData.endDate": {
  274. handler(val) {
  275. this.search();
  276. },
  277. },
  278. selectOptions: {
  279. handler(val) {
  280. if (val.length) {
  281. this.optionList = val;
  282. }
  283. },
  284. deep: true,
  285. immediate: true,
  286. },
  287. inputOptions: {
  288. handler(val) {
  289. if (val.length) {
  290. this.inputList = val;
  291. }
  292. },
  293. deep: true,
  294. immediate: true,
  295. },
  296. },
  297. mounted() {
  298. this.formData.selection = this.optionLists[0].name;
  299. this.formData.dateRangeRadio = "当日";
  300. },
  301. methods: {
  302. handleChange(data) {
  303. this.formData.selection = data;
  304. },
  305. change() {
  306. this.changeButtonLoading = true;
  307. this.$emit("change");
  308. },
  309. querySearch(queryString, callback) {
  310. const inputList = this.inputList;
  311. const results = queryString
  312. ? inputList.filter((option) =>
  313. option.name.toLowerCase().includes(queryString.toLowerCase())
  314. )
  315. : inputList;
  316. callback(results);
  317. },
  318. inputClearHandler() {
  319. this.$refs["autocomplete"].activated = true;
  320. },
  321. search() {
  322. const searchArray = [];
  323. this.withDatePicker &&
  324. searchArray.push([this.formData.beginDate, this.formData.endDate]);
  325. this.withSelect && searchArray.push(this.formData.selection);
  326. this.withInput && searchArray.push(this.formData.searchText);
  327. this.$emit("search", searchArray);
  328. },
  329. resetSearch() {
  330. this.$refs["form"].resetFields();
  331. this.$nextTick(() => {
  332. this.formData.dateRangeRadio = "当日";
  333. this.search();
  334. });
  335. },
  336. },
  337. };
  338. </script>
  339. <style lang="scss" scoped>
  340. .security-check-header {
  341. display: flex;
  342. justify-content: space-between;
  343. align-items: flex-start;
  344. ::v-deep .ant-form-item-control {
  345. // height: 32px;
  346. // line-height: 30px;
  347. }
  348. ::v-deep .ant-calendar-picker-icon {
  349. display: none;
  350. }
  351. .ant-btn-primary {
  352. background-color: #2d67e3;
  353. }
  354. .ant-form-item-control {
  355. border: 1px solid #a4bdf3;
  356. color: #2d67e3;
  357. }
  358. ::v-deep .ant-select-selection__rendered {
  359. line-height: 30px;
  360. }
  361. ::v-deep .ant-form-item-children {
  362. height: 30px;
  363. line-height: 30px;
  364. .ant-btn {
  365. padding: 0 10px;
  366. height: 32px;
  367. line-height: 30px;
  368. font-size: 14px;
  369. font-family: Microsoft YaHei;
  370. font-weight: bold;
  371. // color: #ffffff;
  372. }
  373. }
  374. .btn-icon-only {
  375. width: 32px;
  376. border: none;
  377. background-color: #383c54;
  378. background-size: cover;
  379. }
  380. .icon-change {
  381. background-image: url("../../../assets/logo/ic_change_default.png");
  382. }
  383. .icon-export {
  384. background-image: url("../../../assets/logo/ic_export_default.png");
  385. }
  386. ::v-deep .ant-radio-group {
  387. line-height: 1;
  388. vertical-align: middle;
  389. display: inline-block;
  390. .btn-mo {
  391. background-color: #ffffff;
  392. color: #303133;
  393. }
  394. .btn-mo:hover {
  395. background-color: #ffffff;
  396. color: #303133;
  397. }
  398. .btn-mos {
  399. background-color: #383c54;
  400. color: #ffffff;
  401. }
  402. .btn-mos:hover {
  403. background-color: #ffffff;
  404. color: #303133;
  405. }
  406. .ant-radio-button-wrapper {
  407. height: 32px;
  408. padding: 8px 9px;
  409. // background-color: #383c54;
  410. border: 2px solid #383c54;
  411. // border-right: none;
  412. // color: #ffffff;
  413. -webkit-box-shadow: unset;
  414. box-shadow: unset;
  415. font-size: 14px;
  416. font-family: Microsoft YaHei;
  417. .btn-day {
  418. width: 100%;
  419. height: 100%;
  420. display: flex;
  421. align-items: center;
  422. }
  423. .btn-days {
  424. width: 100%;
  425. height: 100%;
  426. display: flex;
  427. align-items: center;
  428. }
  429. }
  430. .ant-radio-button-checked + .ant-radio-button__inner {
  431. // background-color: #ffffff;
  432. color: #303133;
  433. }
  434. // .ant-radio-button-wrapper {
  435. // .ant-radio-button-inner {
  436. // height: 32px;
  437. // padding: 8px 9px;
  438. // background-color: #383c54;
  439. // border: 2px solid #383c54;
  440. // border-right: none;
  441. // color: #ffffff;
  442. // -webkit-box-shadow: unset;
  443. // box-shadow: unset;
  444. // font-size: 14px;
  445. // font-family: Microsoft YaHei;
  446. // }
  447. // }
  448. }
  449. ::v-deep .ant-form-item-control {
  450. height: 32px;
  451. line-height: 30px;
  452. .ant-form-item-children {
  453. height: 100%;
  454. }
  455. .ant-calendar-picker-input {
  456. height: 32px;
  457. line-height: 30px;
  458. border: none;
  459. }
  460. }
  461. ::v-deep .ant-select {
  462. width: 192px;
  463. height: 32px;
  464. line-height: 30px;
  465. .ant-select-selection--single {
  466. width: 192px;
  467. height: 32px;
  468. line-height: 30px;
  469. }
  470. }
  471. ::v-deep .ant-select-search__field__wrap {
  472. width: 192px;
  473. height: 32px;
  474. line-height: 30px;
  475. .ant-input {
  476. height: 100%;
  477. }
  478. }
  479. .title {
  480. margin-right: 24px;
  481. padding-left: 16px;
  482. min-width: 176px;
  483. height: 32px;
  484. line-height: 32px;
  485. font-size: 20px;
  486. font-family: Helvetica, "Microsoft YaHei";
  487. font-weight: bold;
  488. position: relative;
  489. &::before {
  490. content: "";
  491. width: 4px;
  492. height: 20px;
  493. background: #2d67e3;
  494. position: absolute;
  495. top: 0;
  496. bottom: 0;
  497. left: 0;
  498. margin: auto;
  499. }
  500. }
  501. ::v-deep .form {
  502. display: flex;
  503. flex-wrap: wrap;
  504. .ant-form {
  505. margin-bottom: 24px;
  506. .ant-form-item__content {
  507. height: 32px;
  508. line-height: 30px;
  509. .ant-input .ant-input__inner {
  510. border-radius: 4px;
  511. }
  512. .ant-input .ant-input__inner {
  513. font-family: Helvetica, "Microsoft YaHei";
  514. color: #101116;
  515. border-color: #ffffff;
  516. &:hover {
  517. border-color: #c0c4cc;
  518. }
  519. &:focus {
  520. border-color: #409eff;
  521. }
  522. }
  523. .ant-btn {
  524. padding: 0 10px;
  525. height: 32px;
  526. line-height: 30px;
  527. font-size: 14px;
  528. font-family: Microsoft YaHei;
  529. font-weight: bold;
  530. color: #ffffff;
  531. border: none;
  532. .btn-white {
  533. background-color: #ffffff;
  534. border: 1px solid #a4bdf3;
  535. color: #2d67e3;
  536. }
  537. }
  538. .ant-date-editor {
  539. .ant-input__inner {
  540. padding-left: 15px;
  541. }
  542. .ant-input__prefix {
  543. display: none;
  544. }
  545. }
  546. .ant-radio-button {
  547. .ant-radio-button__inner {
  548. height: 32px;
  549. padding: 8px 9px;
  550. background-color: #383c54;
  551. border: 2px solid #383c54;
  552. border-right: none;
  553. color: #ffffff;
  554. box-shadow: unset;
  555. font-size: 14px;
  556. font-family: Microsoft YaHei;
  557. &:hover {
  558. background-color: #ffffff;
  559. color: #303133;
  560. }
  561. }
  562. &:last-child .ant-radio-button__inner {
  563. border-right: 2px solid #383c54;
  564. }
  565. .ant-radio-button__orig-radio:checked + .ant-radio-button__inner {
  566. background-color: #ffffff;
  567. color: #303133;
  568. }
  569. }
  570. .ant-select .ant-input {
  571. .ant-input__icon::before {
  572. content: "\e78f";
  573. }
  574. .ant-input__icon,
  575. .ant-input__inner::-webkit-input-placeholder {
  576. color: #303133;
  577. }
  578. }
  579. }
  580. &.radio-wrapper .ant-form-item__content {
  581. line-height: 28px;
  582. }
  583. }
  584. }
  585. }
  586. </style>