index.vue 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631
  1. <template>
  2. <div class="Box">
  3. <el-form
  4. :model="FormData"
  5. :rules="rules"
  6. ref="ruleForm"
  7. label-width="100px"
  8. class="demo-ruleForm"
  9. >
  10. <div class="topBox">
  11. <div class="titleBtn">
  12. <span class="titleStyle">策略信息新增 </span>
  13. <el-button @click="save()">保存</el-button>
  14. </div>
  15. <!-- 第一排 -->
  16. <div class="fristLine">
  17. <div class="inputBox">
  18. <el-form-item label="策略名称" prop="TacName">
  19. <el-input
  20. placeholder="请输入"
  21. v-model="FormData.TacName"
  22. ></el-input>
  23. </el-form-item>
  24. </div>
  25. <div class="inputBox">
  26. <el-form-item label="IP类型" prop="IpType">
  27. <el-select v-model="FormData.IpType" placeholder="请选择类型">
  28. <el-option
  29. v-for="item in options"
  30. :key="item.value"
  31. :label="item.label"
  32. :value="item.value"
  33. >
  34. </el-option>
  35. </el-select>
  36. </el-form-item>
  37. </div>
  38. <div class="block inputBox1">
  39. <el-form-item label="登录日期" prop="Date">
  40. <el-date-picker
  41. v-model="FormData.Date"
  42. type="daterange"
  43. range-separator="至"
  44. start-placeholder="开始日期"
  45. end-placeholder="结束日期"
  46. @change="dataChange"
  47. value-format="yyyy-MM-dd"
  48. >
  49. </el-date-picker>
  50. </el-form-item>
  51. </div>
  52. <div class="block inputBox1">
  53. <el-form-item label="登录时间" prop="Time">
  54. <el-time-picker
  55. is-range
  56. v-model="FormData.Time"
  57. range-separator="至"
  58. start-placeholder="开始时间"
  59. end-placeholder="结束时间"
  60. placeholder="选择时间范围"
  61. @change="timeChange"
  62. value-format="HH:mm:ss"
  63. >
  64. </el-time-picker>
  65. </el-form-item>
  66. </div>
  67. </div>
  68. <!-- 第二排 -->
  69. <div class="fristLine" style="margin-top: 24px">
  70. <div class="inputBox2">
  71. <el-form-item label="IP段" prop="IpList">
  72. <el-input
  73. placeholder="请输入IP,并以‘;’号隔开"
  74. v-model="FormData.IpList"
  75. ></el-input>
  76. </el-form-item>
  77. </div>
  78. <div class="inputBox3">
  79. <el-form-item label="描述" prop="IpList">
  80. <el-input
  81. placeholder="请输入"
  82. v-model="FormData.TacDesc"
  83. ></el-input>
  84. </el-form-item>
  85. </div>
  86. </div>
  87. </div>
  88. </el-form>
  89. <div class="centerBox">
  90. <div class="leftB">
  91. <div class="titleBtn">
  92. <span class="titleStyle">已分配职员 </span>
  93. </div>
  94. <div class="center-box">
  95. <el-row class="scCont" :gutter="16">
  96. <el-checkbox-group @change="UnchangeChecked" v-model="UncheckList">
  97. <el-col
  98. :span="4"
  99. v-for="(item, index) in FormData.UseList"
  100. :key="index"
  101. >
  102. <el-card class="box-card">
  103. <div class="lineTop"></div>
  104. <div class="text item">
  105. <div class="header-top">
  106. <div class="header-mid flex">
  107. <span class="title">{{ item.UserName }}</span>
  108. <el-checkbox checked></el-checkbox>
  109. </div>
  110. <!-- <el-checkbox-group v-model="UncheckList" @change="UnchangeChecked(item, index)">
  111. <el-checkbox checked></el-checkbox>
  112. </el-checkbox-group> -->
  113. </div>
  114. </div>
  115. </el-card>
  116. </el-col>
  117. </el-checkbox-group>
  118. </el-row>
  119. <el-empty
  120. v-if="FormData.UseList.length == 0"
  121. description="没有选取"
  122. style="margin: 0 auto"
  123. ></el-empty>
  124. </div>
  125. </div>
  126. <div class="rightB">
  127. <div class="titleBtn">
  128. <span class="titleStyle">选择职员 </span>
  129. <div class="searchBox">
  130. <el-input
  131. placeholder="请输入内容"
  132. clearable
  133. @clear="clearData"
  134. v-model="keyWords"
  135. ></el-input>
  136. <el-button @click="getUserData">搜索</el-button>
  137. </div>
  138. </div>
  139. <div class="center-box">
  140. <el-row
  141. v-infinite-scroll="load"
  142. :infinite-scroll-distance="20"
  143. infinite-scroll-disabled="disabled"
  144. class="scCont scrollbar"
  145. :gutter="16"
  146. >
  147. <el-checkbox-group @change="changeChecked" v-model="checkList">
  148. <el-col
  149. :span="6"
  150. v-for="(item, index) in FormData.Unuselist"
  151. :key="index"
  152. >
  153. <el-card class="box-card">
  154. <div class="lineTop"></div>
  155. <div class="text item">
  156. <div class="header-top">
  157. <div class="header-mid flex">
  158. <span class="title">{{ item.UserName }}</span>
  159. <el-checkbox :label="index"></el-checkbox>
  160. </div>
  161. <!-- <el-checkbox-group v-model="checkList" @change="changeChecked(item, index)">
  162. <el-checkbox></el-checkbox>
  163. </el-checkbox-group> -->
  164. </div>
  165. </div>
  166. </el-card>
  167. </el-col>
  168. </el-checkbox-group>
  169. </el-row>
  170. <template v-if="total > 1">
  171. <p class="center" v-if="loading">加载中...</p>
  172. <p class="center" v-if="noMore">没有更多数据了~</p>
  173. </template>
  174. <el-empty
  175. v-if="FormData.Unuselist.length == 0"
  176. description="没有内容"
  177. style="margin: 0 auto"
  178. ></el-empty>
  179. </div>
  180. </div>
  181. </div>
  182. </div>
  183. </template>
  184. <script>
  185. import { GetUserList } from "@/api/apiAuthority";
  186. import { SaveTac } from "@/api/systemConfiguration";
  187. export default {
  188. data() {
  189. return {
  190. keyWords: "",
  191. checkList: [],
  192. UncheckList: true,
  193. options: [
  194. {
  195. value: 0,
  196. label: "黑名单",
  197. },
  198. {
  199. value: 1,
  200. label: "白名单",
  201. },
  202. ],
  203. boxArr: [],
  204. boxArr1: [],
  205. FormData: {
  206. TacName: "",
  207. TacDesc: "",
  208. DateBegin: "",
  209. DateEnd: "",
  210. TimeBegin: "",
  211. TimeEnd: "",
  212. IpType: 1,
  213. IpList: "",
  214. UseList: [],
  215. Unuselist: [],
  216. Date: null,
  217. Time: null,
  218. },
  219. rules: {
  220. TacName: [
  221. { required: true, message: "请输入策略名称", trigger: "blur" },
  222. {
  223. min: 1,
  224. max: 16,
  225. message: "长度在 1 到 16 个字符",
  226. trigger: "blur",
  227. },
  228. ],
  229. Date: [
  230. { required: true, message: "请选择登录日期", trigger: "change" },
  231. ],
  232. Time: [
  233. { required: true, message: "请选择登录时间", trigger: "change" },
  234. ],
  235. },
  236. pageNum: 1,
  237. PageSize: 50,
  238. loading: false,
  239. total: null,
  240. arrList: [],
  241. dataList: [],
  242. checkData: [],
  243. };
  244. },
  245. created: function () {
  246. this.getUserList({
  247. QueryName: this.keyWords,
  248. PageSize: this.PageSize,
  249. PageIndex: this.pageNum,
  250. });
  251. },
  252. computed: {
  253. noMore() {
  254. return this.pageNum >= this.total;
  255. },
  256. disabled() {
  257. return this.loading || this.noMore;
  258. },
  259. },
  260. methods: {
  261. isValidIP: function (ip) {
  262. let reg =
  263. /^(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])$/;
  264. return reg.test(ip);
  265. },
  266. save() {
  267. let that = this;
  268. let ipArr = this.FormData.IpList.split(";");
  269. let isSave = true;
  270. if (ipArr.length >= 2) {
  271. ipArr.forEach((item) => {
  272. if (this.isValidIP(item) == false) {
  273. this.$message.error("请输入正确IP段,并以;号隔开");
  274. isSave = false;
  275. }
  276. });
  277. }
  278. this.$refs["ruleForm"].validate((valid) => {
  279. if (valid && isSave) {
  280. return new Promise((resolve, reject) => {
  281. SaveTac(this.FormData)
  282. .then((response) => {
  283. if (response.code === 0) {
  284. this.FormData = {
  285. TacName: "",
  286. TacDesc: "",
  287. DateBegin: "",
  288. DateEnd: "",
  289. TimeBegin: "",
  290. TimeEnd: "",
  291. IpType: 1,
  292. IpList: "",
  293. UseList: [],
  294. Unuselist: [],
  295. Date: null,
  296. Time: null,
  297. };
  298. this.$message.success("新增成功");
  299. this.$store.dispatch("tagsView/delView", this.$route);
  300. that.$router.push("/LoginPolicy");
  301. }
  302. resolve();
  303. })
  304. .catch((error) => {
  305. reject(error);
  306. });
  307. });
  308. } else {
  309. return false;
  310. }
  311. });
  312. },
  313. getUserList(obj) {
  314. return new Promise((resolve, reject) => {
  315. this.loading = true;
  316. GetUserList(obj)
  317. .then((res) => {
  318. if (res.code === 0) {
  319. const datas = res.returnData.records;
  320. const num = res.returnData.pages;
  321. this.arrList.push(datas);
  322. const arrs = this.arrList.flat();
  323. const msgs = _.unionBy(arrs, "UserId");
  324. this.FormData.Unuselist = msgs;
  325. this.dataList = msgs;
  326. this.total = num;
  327. this.loading = false;
  328. }
  329. resolve();
  330. })
  331. .catch((error) => {
  332. reject(error);
  333. this.loading = false;
  334. });
  335. });
  336. },
  337. changeChecked(arr) {
  338. const datas = this.dataList;
  339. datas.forEach((item, index) => {
  340. arr.forEach((p) => {
  341. if (index == p) {
  342. this.checkData.push(item);
  343. this.FormData.Unuselist.splice(index, 1);
  344. }
  345. });
  346. });
  347. this.FormData.UseList = this.checkData;
  348. this.checkList = [];
  349. },
  350. UnchangeChecked(val, index) {
  351. this.UncheckList = true;
  352. this.FormData.Unuselist.push(val);
  353. this.FormData.UseList.splice(index, 1);
  354. },
  355. dataChange: function (data) {
  356. this.FormData.DateBegin = data[0];
  357. this.FormData.DateEnd = data[1];
  358. },
  359. timeChange: function (data) {
  360. this.FormData.TimeBegin = data[0];
  361. this.FormData.TimeEnd = data[1];
  362. },
  363. load() {
  364. this.pageNum += 1;
  365. this.getUserList({
  366. QueryName: this.keyWords,
  367. PageSize: this.PageSize,
  368. PageIndex: this.pageNum,
  369. });
  370. },
  371. getUserData() {
  372. this.arrList = [];
  373. this.FormData.Unuselist = [];
  374. this.pageNum = 1;
  375. this.getUserList({
  376. QueryName: this.keyWords,
  377. PageSize: this.PageSize,
  378. PageIndex: this.pageNum,
  379. });
  380. },
  381. clearData() {
  382. this.arrList = [];
  383. this.FormData.Unuselist = [];
  384. this.pageNum = 1;
  385. this.getUserList({
  386. QueryName: "",
  387. PageSize: this.PageSize,
  388. PageIndex: this.pageNum,
  389. });
  390. },
  391. },
  392. };
  393. </script>
  394. <style lang="scss" scoped>
  395. .Box {
  396. width: 100%;
  397. height: 100%;
  398. padding: 0 64px;
  399. padding-top: 32px;
  400. }
  401. .topBox {
  402. width: 100%;
  403. height: 240px;
  404. background: #ffffff;
  405. box-shadow: 0px 6px 7px 0px rgba(0, 0, 0, 0.06);
  406. border-radius: 16px;
  407. }
  408. .fristLine {
  409. display: flex;
  410. margin-left: 33px;
  411. }
  412. .inputBox {
  413. display: flex;
  414. height: 32px;
  415. line-height: 32px;
  416. }
  417. .inputBox1 {
  418. display: flex;
  419. height: 32px;
  420. line-height: 32px;
  421. }
  422. .inputBox2 {
  423. display: flex;
  424. height: 32px;
  425. line-height: 32px;
  426. }
  427. .inputBox3 {
  428. display: flex;
  429. height: 32px;
  430. line-height: 32px;
  431. }
  432. .SystemName {
  433. width: 108px;
  434. height: 14px;
  435. font-size: 14px;
  436. font-weight: 400;
  437. color: #303133;
  438. }
  439. .SystemName1 {
  440. width: 70px;
  441. text-align: right;
  442. margin-left: -10px;
  443. height: 14px;
  444. font-size: 14px;
  445. font-weight: 400;
  446. color: #303133;
  447. cursor: pointer;
  448. }
  449. ::v-deep .topBox {
  450. .el-button--default {
  451. width: 80px;
  452. height: 40px;
  453. background: #6e81bc;
  454. color: #ffffff;
  455. border-radius: 6px;
  456. border: none;
  457. }
  458. .inputBox .el-input__inner {
  459. width: 184px;
  460. height: 32px;
  461. background: #f5f7fa;
  462. border: 1px solid #dcdfe6;
  463. border-radius: 6px;
  464. }
  465. .el-select__caret {
  466. text-align: center;
  467. height: 32px;
  468. line-height: 32px;
  469. }
  470. .inputBox1 .el-date-editor {
  471. width: 322px;
  472. height: 32px;
  473. line-height: 32px;
  474. background: #f5f7fa;
  475. border: 1px solid #dcdfe6;
  476. border-radius: 6px;
  477. .el-range-separator {
  478. height: 32px;
  479. line-height: 32px;
  480. }
  481. .el-range-input {
  482. background: #f5f7fa;
  483. }
  484. }
  485. .inputBox2 .el-input__inner {
  486. width: 480px;
  487. height: 32px;
  488. background: #f5f7fa;
  489. border: 1px solid #dcdfe6;
  490. border-radius: 6px;
  491. }
  492. .inputBox3 .el-input__inner {
  493. width: 500px;
  494. height: 32px;
  495. background: #f5f7fa;
  496. border: 1px solid #dcdfe6;
  497. border-radius: 6px;
  498. }
  499. }
  500. .titleBtn {
  501. display: flex;
  502. justify-content: space-between;
  503. padding: 20px;
  504. }
  505. .titleStyle {
  506. width: 200px;
  507. height: 24px;
  508. font-size: 24px;
  509. font-weight: bold;
  510. color: #303133;
  511. margin-left: 10px;
  512. }
  513. .centerBox {
  514. display: flex;
  515. margin-top: 23px;
  516. position: relative;
  517. }
  518. .leftB {
  519. width: 1242px;
  520. height: 760px;
  521. background: #ffffff;
  522. box-shadow: 0px 6px 7px 0px rgba(0, 0, 0, 0.06);
  523. border-radius: 4px;
  524. overflow: auto;
  525. }
  526. .center-box {
  527. // max-height: calc(100% - 105px);
  528. // margin-top: 12px;
  529. padding: 0 24px 24px 24px;
  530. // overflow: auto;
  531. }
  532. .colorTitle {
  533. margin-top: 20px;
  534. width: 195px;
  535. height: 20px;
  536. display: flex;
  537. justify-content: space-between;
  538. float: left;
  539. }
  540. ::v-deep .box-card {
  541. margin-top: 16px;
  542. height: 80px;
  543. background: #f5f7fa;
  544. box-shadow: 0px 2px 6px 0px rgba(0, 0, 0, 0.1);
  545. border-radius: 8px;
  546. .el-checkbox__label {
  547. display: none;
  548. }
  549. }
  550. // .center-box :hover {
  551. // box-shadow: 0 16px 32px 0 rgba(48, 55, 66, 0.15);
  552. // transform: translate(0, -5px);
  553. // transition-delay: 0s !important;
  554. // }
  555. .title {
  556. max-width: 60px;
  557. height: 16px;
  558. font-size: 16px;
  559. font-weight: 400;
  560. color: #303133;
  561. margin-right: 20px;
  562. display: block;
  563. white-space: nowrap;
  564. overflow: hidden;
  565. text-overflow: ellipsis;
  566. }
  567. // .box-card :hover {
  568. // box-shadow: none;
  569. // transform: none;
  570. // }
  571. .rightB {
  572. width: 670px;
  573. height: 760px;
  574. background: #ffffff;
  575. box-shadow: 0px 6px 7px 0px rgba(0, 0, 0, 0.06);
  576. border-radius: 16px;
  577. margin-left: 40px;
  578. overflow: auto;
  579. // position: relative;
  580. > .titleBtn {
  581. width: 610px;
  582. position: absolute;
  583. z-index: 99;
  584. top: 0;
  585. right: 0;
  586. background: #ffffff;
  587. }
  588. > .center-box {
  589. margin-top: 72px;
  590. }
  591. .searchBox {
  592. display: flex;
  593. }
  594. }
  595. ::v-deep .rightB {
  596. .el-input__inner {
  597. width: 200px;
  598. height: 32px;
  599. background: #f5f7fa;
  600. border: 1px solid #c0c4cc;
  601. border-radius: 6px;
  602. }
  603. .el-button--default {
  604. width: 64px;
  605. height: 32px;
  606. line-height: 8px;
  607. background: linear-gradient(0deg, #6983be, #777dba);
  608. border-radius: 6px;
  609. color: #ffffff;
  610. border: none;
  611. margin-left: 10px;
  612. }
  613. }
  614. ::-webkit-scrollbar-track-piece {
  615. background: #d3dce6;
  616. }
  617. ::-webkit-scrollbar {
  618. width: 6px;
  619. }
  620. ::-webkit-scrollbar-thumb {
  621. background: #99a9bf;
  622. border-radius: 20px;
  623. }
  624. </style>