index.vue 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575
  1. <template>
  2. <div class="airportInfo scroll-y">
  3. <div class="wrap">
  4. <!-- powerData="new_login_policy_button" -->
  5. <Minheader :is-auth="true" :is-statuser="true" @addForm="addForm">
  6. <template #header>
  7. <div class="status flex-wrap">
  8. <div class="manageTitle">登录策略</div>
  9. </div>
  10. </template>
  11. </Minheader>
  12. <div class="app-containers">
  13. <el-table :data="tableData" style="width: 100%" :row-style="rowStyle" :row-class-name="tableRowClassName" :cell-class-name="cellClassName" :row-key="
  14. props.tableProperty.rowKey
  15. ? props.tableProperty.rowKey
  16. : tablePropertyDefault.rowKey
  17. " :height="
  18. props.tableProperty.height
  19. ? props.tableProperty.height
  20. : tablePropertyDefault.height
  21. " :max-height="
  22. props.tableProperty.maxHeight
  23. ? props.tableProperty.maxHeight
  24. : tablePropertyDefault.maxHeight
  25. " :stripe="
  26. props.tableProperty.stripe
  27. ? props.tableProperty.stripe
  28. : tablePropertyDefault.stripe
  29. " :border="
  30. props.tableProperty.border
  31. ? props.tableProperty.border
  32. : tablePropertyDefault.border
  33. " :highlight-current-row="
  34. props.tableProperty.highlightCurrentRow
  35. ? props.tableProperty.highlightCurrentRow
  36. : tablePropertyDefault.highlightCurrentRow
  37. " :header-cell-class-name="
  38. props.tableProperty.headerRowClassName
  39. ? props.tableProperty.headerRowClassName
  40. : tablePropertyDefault.headerRowClassName
  41. " :tooltip-effect="
  42. props.tableProperty.tooltipEffect
  43. ? props.tableProperty.tooltipEffect
  44. : tablePropertyDefault.tooltipEffect
  45. " :show-summary="
  46. props.tableProperty.showSummary
  47. ? props.tableProperty.showSummary
  48. : tablePropertyDefault.showSummary
  49. ">
  50. <el-table-column prop="name" label="名称" class="infinite-list-item" />
  51. <el-table-column label="有效日期" class="infinite-list-item">
  52. <el-table-column prop="begindate" label="开始日期" class="infinite-list-item" />
  53. <el-table-column prop="enddate" label="结束日期" class="infinite-list-item" />
  54. </el-table-column>
  55. <el-table-column label="有效时间" class="infinite-list-item">
  56. <el-table-column prop="begintime" label="开始时间" class="infinite-list-item" />
  57. <el-table-column prop="endtime" label="结束时间" class="infinite-list-item" />
  58. </el-table-column>
  59. <el-table-column prop="black" label="黑名单" class="infinite-list-item" />
  60. <el-table-column prop="white" label="白名单" class="infinite-list-item" />
  61. <el-table-column prop="remark" label="描述" class="infinite-list-item" />
  62. <el-table-column v-if="tableBtnGroup.length" label="操作" :align="props.tableColumnProperty.align">
  63. <template #default="scope">
  64. <el-button v-for="(btn, index) in tableBtnGroup" :key="index" size="small" @click="handleClick(scope.$index, scope.row, btn.param)" :class="btn.className">{{ btn.name }}</el-button>
  65. </template>
  66. </el-table-column>
  67. </el-table>
  68. <!-- <DataTable
  69. :tableHeader="state.list"
  70. :tableData="tableData"
  71. :tableBtnGroup="tableBtnGroup"
  72. :tableProperty="{ rowKey: 'ID' }"
  73. @btnClick="btnClick"
  74. /> -->
  75. </div>
  76. <Dialog width="628px" :flag="flag" :type="type" :msgTitle="msgTitle" :delName="tableForm.name" @submit-form="submitForm" @resetForm="resetForm" @delRest="delRest" @delRemove="delRemove">
  77. <div class="diacont">
  78. <el-form ref="securityPolicyForm" :rules="formRules" :model="tableForm">
  79. <el-row :gutter="24">
  80. <el-col>
  81. <el-form-item label="策略名称" prop="name" :rules="formRules.isNotNull" size="default">
  82. <el-input v-model="tableForm.name" placeholder="请输入策略名称" />
  83. </el-form-item>
  84. </el-col>
  85. <el-col>
  86. <div class="flex">
  87. <el-form-item label="有效日期" prop="begindate" :rules="formRules.isNotNull" size="default">
  88. <el-date-picker v-model="tableForm.begindate" format="YYYY-MM-DD" value-format="YYYY-MM-DD" type="date" placeholder="选择日期">
  89. </el-date-picker>
  90. </el-form-item>
  91. <el-form-item prop="enddate" :rules="formRules.isNotNull" size="default">
  92. <el-date-picker style="margin-left: 40px" format="YYYY-MM-DD" value-format="YYYY-MM-DD" v-model="tableForm.enddate" type="date" placeholder="选择日期">
  93. </el-date-picker>
  94. </el-form-item>
  95. </div>
  96. </el-col>
  97. <el-col>
  98. <el-form-item label="有效时间" size="default">
  99. <el-time-select v-model="tableForm.begintime" :picker-options="{
  100. start: '08:30',
  101. step: '00:15',
  102. end: '18:30',
  103. }" placeholder="选择时间">
  104. </el-time-select>
  105. <el-time-select style="margin-left: 40px" v-model="tableForm.endtime" :picker-options="{
  106. start: '08:30',
  107. step: '00:15',
  108. end: '18:30',
  109. }" placeholder="选择时间">
  110. </el-time-select>
  111. </el-form-item>
  112. </el-col>
  113. <el-col>
  114. <el-form-item label="黑名单" size="default">
  115. <div class="father_box">
  116. <!-- 生成的标签 -->
  117. <!-- <div v-for="(item, index) in TagsAll" :key="index" class="spanbox">
  118. <span class="tagspan">{{ item }}</span>
  119. <i class="span_close" @click="removeTag(index, item)"></i>
  120. </div> -->
  121. <!-- 输入框 -->
  122. <el-input style="width: 100%; border: none" placeholder="请输入黑名单" v-model="tableForm.black" @keyup.enter="addTags" @keyup.delete="deleteTags" class="inputTag" ref="inputTag" type="text" />
  123. </div>
  124. </el-form-item>
  125. </el-col>
  126. <el-col>
  127. <el-form-item label="白名单" size="default">
  128. <div class="father_box">
  129. <!-- 生成的标签 -->
  130. <!-- <div v-for="(item, index) in TagsAlls" :key="index" class="spanbox">
  131. <span class="tagspan">{{ item }}</span>
  132. <i class="span_close" @click="removeTags(index, item)"></i>
  133. </div> -->
  134. <!-- 输入框 -->
  135. <el-input style="width: 100%" placeholder="请输入白名单" v-model="tableForm.white" @keyup.enter="addTagss" @keyup.delete="deleteTagss" class="inputTag" ref="inputTag" type="text" />
  136. </div>
  137. </el-form-item>
  138. </el-col>
  139. <el-col>
  140. <el-form-item label="描述" size="default">
  141. <el-input type="textarea" v-model="tableForm.remark" placeholder="请输入描述" />
  142. </el-form-item>
  143. </el-col>
  144. </el-row>
  145. </el-form>
  146. </div>
  147. </Dialog>
  148. </div>
  149. </div>
  150. </template>
  151. <script setup lang="ts">
  152. import DataTable from "@/components/tableTemp/index.vue";
  153. import Minheader from "@/components/minheader/index.vue";
  154. import Dialog from "@/components/dialog/index.vue";
  155. import { onMounted } from "vue";
  156. import { GeneralDataReception, Query } from "@/api/webApi";
  157. import { ElMessage } from "element-plus";
  158. const formRules = useElement().formRules;
  159. const router = useRouter();
  160. const props = defineProps({
  161. //表格参数
  162. tableProperty: {
  163. type: Object,
  164. default: {
  165. height: "100%",
  166. maxHeight: "100%",
  167. stripe: true,
  168. border: true,
  169. highlightCurrentRow: false,
  170. rowClassName: "rowClass",
  171. headerRowClassName: "headerRowClass",
  172. tooltipEffect: "light",
  173. showSummary: false,
  174. rowKey: "",
  175. },
  176. },
  177. //公共表头参数
  178. tableColumnProperty: {
  179. type: Object,
  180. default: {
  181. width: "",
  182. fixed: "",
  183. sortable: false,
  184. showOverflowTooltip: false,
  185. align: "center",
  186. headerAlign: "",
  187. },
  188. },
  189. });
  190. //表格参数
  191. const tablePropertyDefault = {
  192. height: "100%",
  193. maxHeight: "100%",
  194. stripe: true,
  195. border: true,
  196. highlightCurrentRow: false,
  197. rowClassName: "rowClass",
  198. headerRowClassName: "headerRowClass",
  199. tooltipEffect: "light",
  200. showSummary: false,
  201. rowKey: "",
  202. };
  203. const flag = ref<boolean>(false); //弹窗开关
  204. const type = ref<string>(""); //判断是否删除
  205. const TagsAll = ref<any>([]);
  206. const serviceId = ref<number | null>(null);
  207. const currentval = ref<string>("");
  208. const TagsAlls = ref<any>([]);
  209. const currentvals = ref<string>("");
  210. const msgTitle = ref<string>("新增登录策略"); //弹窗标题
  211. const tableColsCopys = reactive<any>({}); //弹窗
  212. const tableForm = reactive({
  213. name: "",
  214. begindate: "",
  215. enddate: "",
  216. begintime: "",
  217. endtime: "",
  218. black: "",
  219. white: "",
  220. remark: "",
  221. event: <number | string>"",
  222. id: <number | string>"",
  223. IDKey: "id",
  224. }); //弹窗内容
  225. //列表
  226. const tableData = ref<any>([]);
  227. //表头
  228. const state = reactive({
  229. list: [
  230. { label: "名称", key: "name" },
  231. { label: "有效日期", key: "china" },
  232. { label: "有效时间", key: "englin" },
  233. { label: "黑名单", key: "two" },
  234. { label: "白名单", key: "three" },
  235. { label: "描述", key: "text" },
  236. ],
  237. listLoading: true,
  238. });
  239. const tableBtnGroup = ref([
  240. {
  241. name: "编辑",
  242. className: "editBtn",
  243. param: 2,
  244. is: "login_policy_edit_button",
  245. },
  246. {
  247. name: "删除",
  248. className: "delBtn",
  249. param: 3,
  250. is: "login_policy_deletion_button",
  251. },
  252. ]);
  253. const btnAuthMap = [
  254. ,
  255. "new_login_policy_button",
  256. "login_policy_edit_button",
  257. "login_policy_deletion_button",
  258. ];
  259. //新增-编辑-删除
  260. const generalDataReception = async (data: any) => {
  261. try {
  262. const ndata = { ...data };
  263. const { event }: { event: any } = ndata;
  264. if (event == 1) {
  265. delete ndata.id;
  266. }
  267. const { code } = await GeneralDataReception({
  268. serviceId: SERVICE_ID.loginPolicyScId,
  269. dataContent: JSON.stringify(ndata),
  270. btnAuth: btnAuthMap[ndata.event],
  271. });
  272. if (code == 0) {
  273. ElMessage.success(`操作成功`);
  274. // this.$message.success("操作成功");
  275. resetTable();
  276. getQuery();
  277. resetForm();
  278. flag.value = false;
  279. } else {
  280. flag.value = false;
  281. ElMessage.error(`操作失败`);
  282. resetForm();
  283. }
  284. } catch (error) {
  285. flag.value = false;
  286. resetForm();
  287. }
  288. };
  289. const resetTable = () => {
  290. tableData.value = [];
  291. };
  292. //新增
  293. const addForm = () => {
  294. msgTitle.value = "新增登录策略";
  295. for (const key in tableForm) {
  296. if (Object.prototype.hasOwnProperty.call(tableForm, key)) {
  297. if (key != "IDKey") {
  298. tableForm[key] = "";
  299. }
  300. }
  301. }
  302. tableForm.event = 1;
  303. flag.value = true;
  304. type.value = "";
  305. };
  306. //确认提交
  307. const securityPolicyForm: any = ref(null);
  308. const submitForm = () => {
  309. securityPolicyForm.value.validate((valid: any) => {
  310. if (valid) {
  311. generalDataReception(tableForm);
  312. } else {
  313. return false;
  314. }
  315. });
  316. };
  317. //取消
  318. const resetForm = () => {
  319. securityPolicyForm.value?.resetFields();
  320. flag.value = false;
  321. TagsAll.value = [];
  322. TagsAlls.value = [];
  323. };
  324. //删除
  325. const delRest = () => {
  326. flag.value = false;
  327. };
  328. const delRemove = () => {
  329. tableForm.event = 3;
  330. generalDataReception(tableForm);
  331. };
  332. //按钮点击index为当前行序号 row 为当前行 param按钮类型判断参数由父组件传过来
  333. const handleClick = (index: number, row: any, param: number) => {
  334. if (param === 2) {
  335. msgTitle.value = "修改登录策略";
  336. flag.value = true;
  337. type.value = "";
  338. for (const key in tableForm) {
  339. if (Object.prototype.hasOwnProperty.call(row, key)) {
  340. tableForm[key] = row[key];
  341. }
  342. }
  343. tableForm.event = 2;
  344. // router.push({ path: "/systemSettings/securityPolicyedit" });
  345. } else if (param === 3) {
  346. msgTitle.value = "删除航司信息维护";
  347. flag.value = true;
  348. type.value = "del";
  349. for (const key in tableForm) {
  350. if (Object.prototype.hasOwnProperty.call(row, key)) {
  351. tableForm[key] = row[key];
  352. }
  353. }
  354. }
  355. };
  356. //行公共样式
  357. const rowStyle = (row: Object, rowIndex: number) => {
  358. let styleJson: Object = {
  359. height: "50px",
  360. fontSize: "14px",
  361. color: "#101116",
  362. };
  363. return styleJson;
  364. };
  365. //表格行class样式 可通过父组件直接传class名称修改当前行样式
  366. const tableRowClassName = (row: any, rowIndex: number) => {
  367. if (row.row.rowClass) {
  368. return row.row.rowClass;
  369. }
  370. return "";
  371. };
  372. //向父组件传参 btnClick:点击按钮后 load 触发下拉加载 cellClass 修改某一行class的触发条件
  373. const emit = defineEmits(["btnClick", "load", "cellClass"]);
  374. //给某一格加class
  375. const cellClass = ref("");
  376. const cellClassName = (row: Object) => {
  377. emit("cellClass", row);
  378. return cellClass.value;
  379. };
  380. const removeTag = (index) => {
  381. TagsAll.value.splice(index, 1);
  382. };
  383. const addTags = () => {
  384. if (currentval) {
  385. TagsAll.value.push(currentval.value);
  386. currentval.value = "";
  387. }
  388. };
  389. const deleteTags = () => {
  390. TagsAlls.value.pop();
  391. };
  392. const removeTags = (index) => {
  393. TagsAlls.value.splice(index, 1);
  394. };
  395. const addTagss = () => {
  396. if (currentvals) {
  397. TagsAlls.value.push(currentvals.value);
  398. currentvals.value = "";
  399. }
  400. };
  401. const deleteTagss = () => {
  402. TagsAlls.value.pop();
  403. };
  404. // const inputStyle = () => {
  405. // let style = {};
  406. // style.width = `${inputLength}px`;
  407. // return style;
  408. // };
  409. defineExpose({
  410. cellClass,
  411. });
  412. //获取列表数据
  413. const getQuery = async () => {
  414. const res = await Query({
  415. id: DATACONTENT_ID.loginPolicyId,
  416. dataContent: [],
  417. });
  418. if (res.code == 0) {
  419. const { returnData } = res;
  420. tableData.value = returnData;
  421. } else {
  422. ElMessage.error(res.message);
  423. }
  424. };
  425. onMounted(() => {
  426. getQuery();
  427. });
  428. </script>
  429. <style lang="scss" scoped>
  430. ::v-deep .el-form-item__label {
  431. width: 100px;
  432. }
  433. .app-containers {
  434. height: calc(100vh - 180px);
  435. }
  436. .infinite-list {
  437. height: 300px;
  438. padding: 0;
  439. margin: 0;
  440. list-style: none;
  441. }
  442. .infinite-list .infinite-list-item {
  443. display: flex;
  444. align-items: center;
  445. justify-content: center;
  446. height: 50px;
  447. background: var(--el-color-primary-light-9);
  448. margin: 10px;
  449. color: var(--el-color-primary);
  450. }
  451. .infinite-list .infinite-list-item + .list-item {
  452. margin-top: 10px;
  453. }
  454. ::v-deep.el-table .rowClass {
  455. height: 40px;
  456. font-size: 14px;
  457. color: #101116;
  458. }
  459. ::v-deep.el-table .headerRowClass {
  460. height: 40px;
  461. background: #ffffff;
  462. font-size: 14px;
  463. font-weight: bold;
  464. color: #101116;
  465. }
  466. ::v-deep.el-table .cell {
  467. text-align: center;
  468. }
  469. ::v-deep.el-table .editBtn {
  470. background: #ffffff;
  471. border: 1px solid #f79ec6;
  472. box-shadow: 0px 3px 3px 0px rgba(0, 0, 0, 0.06);
  473. border-radius: 4px;
  474. font-size: 12px;
  475. font-weight: 400;
  476. color: #ac014d;
  477. }
  478. ::v-deep.el-table .delBtn {
  479. background: #eb2f3b;
  480. box-shadow: 0px 3px 3px 0px rgba(0, 0, 0, 0.06);
  481. border-radius: 4px;
  482. font-size: 12px;
  483. font-weight: 400;
  484. color: #ffffff;
  485. border: none;
  486. }
  487. ::v-deep.el-table--striped
  488. .el-table__body
  489. tr.el-table__row--striped
  490. td.el-table__cell {
  491. background-color: #f0f3f7;
  492. }
  493. ::v-deep.el-table thead.is-group th.el-table__cell {
  494. background: #fff;
  495. }
  496. .father_box {
  497. width: 100%;
  498. /* width: 300px; */
  499. box-sizing: border-box;
  500. background-color: white;
  501. border: 1px solid #dcdee2;
  502. border-radius: 4px;
  503. font-size: 12px;
  504. text-align: left;
  505. padding-left: 5px;
  506. word-wrap: break-word;
  507. overflow: hidden;
  508. }
  509. /* 标签 */
  510. .spanbox {
  511. display: inline-block;
  512. font-size: 14px;
  513. margin: 0px 4px 0px 0;
  514. background: #dfe3ea;
  515. border: 1px solid #e8eaec;
  516. border-radius: 3px;
  517. }
  518. .tagspan {
  519. height: 24px;
  520. line-height: 22px;
  521. max-width: 99%;
  522. position: relative;
  523. display: inline-block;
  524. padding-left: 8px;
  525. color: #495060;
  526. font-size: 14px;
  527. cursor: pointer;
  528. opacity: 1;
  529. vertical-align: middle;
  530. overflow: hidden;
  531. transition: 0.25s linear;
  532. color: rgb(26, 26, 26);
  533. font-weight: 600;
  534. }
  535. .span_close {
  536. padding: 0 4px 0 4px;
  537. opacity: 1;
  538. -webkit-filter: none;
  539. filter: none;
  540. color: rgb(26, 26, 26);
  541. font-weight: 600;
  542. }
  543. .span_close:after {
  544. content: "\00D7";
  545. -webkit-font-smoothing: antialiased;
  546. -moz-osx-font-smoothing: grayscale;
  547. /* line-height: 27px; */
  548. transition: 0.3s, color 0s;
  549. }
  550. /* input */
  551. .inputTag {
  552. font-size: 16px;
  553. border: none;
  554. box-shadow: none;
  555. outline: none;
  556. background-color: transparent;
  557. padding: 0;
  558. width: auto;
  559. min-width: 250px;
  560. vertical-align: top;
  561. height: 32px;
  562. color: #495060;
  563. line-height: 32px;
  564. }
  565. .father_box {
  566. ::v-deep .el-input__wrapper:hover {
  567. box-shadow: 0 0 0 0;
  568. }
  569. ::v-deep .el-input__wrapper {
  570. box-shadow: 0 0 0 0;
  571. }
  572. }
  573. </style>