authRole.vue 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814
  1. <script>
  2. import publicFunc from "@/utils/publicFunc";
  3. import { requireImg } from "@/utils/requireImg";
  4. import authAction from "./authAction.vue";
  5. export default {
  6. components: { authAction },
  7. data() {
  8. const columns = [
  9. {
  10. title: "终端类型",
  11. dataIndex: "deviceType",
  12. },
  13. {
  14. title: "模块名称",
  15. dataIndex: "modelName",
  16. },
  17. {
  18. title: "功能权限",
  19. dataIndex: "functionAuth",
  20. },
  21. ];
  22. return {
  23. visible: {
  24. roleGroup: false,
  25. user: false,
  26. },
  27. inputName:"",
  28. columns,
  29. checkedObj: {
  30. groupChecked: "",
  31. systemChecked: "",
  32. },
  33. checkedUsers: [],
  34. userListGroup: [],
  35. keyDictObj: {},
  36. roleListData: [
  37. {
  38. id: publicFunc.buildGuid("group"),
  39. label: "普通员工角色组",
  40. type: "group",
  41. },
  42. ],
  43. systemListData: [
  44. {
  45. id: publicFunc.buildGuid("system"),
  46. label: "空间管理系统",
  47. type: "system",
  48. modelList: [
  49. {
  50. id: publicFunc.buildGuid("system"),
  51. deviceType: "PC",
  52. modelName: "智能看板",
  53. functionAuth: "信息查看,组织添加,人员更新,人员删除",
  54. },
  55. {
  56. id: publicFunc.buildGuid("system"),
  57. deviceType: "PC",
  58. modelName: "智享生活",
  59. functionAuth: "全部功能",
  60. },
  61. {
  62. id: publicFunc.buildGuid("system"),
  63. deviceType: "PC",
  64. modelName: "数智双探",
  65. functionAuth: "全部功能",
  66. },
  67. {
  68. id: publicFunc.buildGuid("system"),
  69. deviceType: "移动端",
  70. modelName: "智慧安防",
  71. functionAuth: "信息查看,组织添加,人员更新,人员删除",
  72. },
  73. ],
  74. },
  75. {
  76. id: publicFunc.buildGuid("system"),
  77. type: "system",
  78. label: "停车管理系统",
  79. modelList: [
  80. {
  81. id: publicFunc.buildGuid("system"),
  82. deviceType: "PC",
  83. modelName: "智能看板",
  84. functionAuth: "信息查看,组织添加,人员更新,人员删除",
  85. },
  86. {
  87. id: publicFunc.buildGuid("system"),
  88. deviceType: "PC",
  89. modelName: "智享生活",
  90. functionAuth: "信息查看,组织添加,人员更新,人员删除",
  91. },
  92. {
  93. id: publicFunc.buildGuid("system"),
  94. deviceType: "移动端",
  95. modelName: "智慧安防",
  96. functionAuth: "全部功能",
  97. },
  98. ],
  99. },
  100. {
  101. id: publicFunc.buildGuid("system"),
  102. type: "system",
  103. label: "能源管理系统",
  104. modelList: [
  105. {
  106. id: publicFunc.buildGuid("system"),
  107. deviceType: "PC",
  108. modelName: "智能看板",
  109. functionAuth: "全部功能",
  110. },
  111. {
  112. id: publicFunc.buildGuid("system"),
  113. deviceType: "PC",
  114. modelName: "智享生活",
  115. },
  116. {
  117. id: publicFunc.buildGuid("system"),
  118. deviceType: "移动端",
  119. modelName: "智慧安防",
  120. functionAuth: "全部功能",
  121. },
  122. {
  123. id: publicFunc.buildGuid("system"),
  124. deviceType: "移动端",
  125. modelName: "智慧安防",
  126. functionAuth: "全部功能",
  127. },
  128. ],
  129. },
  130. {
  131. id: publicFunc.buildGuid("system"),
  132. type: "system",
  133. label: "中枢",
  134. modelList: [
  135. {
  136. id: publicFunc.buildGuid("system"),
  137. deviceType: "PC",
  138. modelName: "智享生活",
  139. functionAuth: "全部功能",
  140. },
  141. {
  142. id: publicFunc.buildGuid("system"),
  143. deviceType: "移动端",
  144. modelName: "智慧安防",
  145. functionAuth: "全部功能",
  146. },
  147. ],
  148. },
  149. ],
  150. userListData: [
  151. {
  152. id: publicFunc.buildGuid("user"),
  153. label: "超级管理员",
  154. type: "user",
  155. },
  156. {
  157. id: publicFunc.buildGuid("user"),
  158. label: "普通管理员",
  159. type: "user",
  160. },
  161. {
  162. id: publicFunc.buildGuid("user"),
  163. label: "决策组",
  164. type: "user",
  165. },
  166. {
  167. id: publicFunc.buildGuid("user"),
  168. label: "普通用户",
  169. type: "user",
  170. },
  171. ],
  172. tableData: [],
  173. // 选中后添加的角色权限组
  174. addedRoleMap: new Map(),
  175. addedRoleArr: [],
  176. // 树选择
  177. treeData: [],
  178. value: undefined,
  179. };
  180. },
  181. created() {
  182. this.initData();
  183. },
  184. mounted() {
  185. // this.initRoleData();
  186. },
  187. watch: {
  188. checkedObj: {
  189. handler(value) {
  190. if (value.groupChecked != "" && value.systemChecked != "") {
  191. // 显示右侧的权限列表数据
  192. this.tableData = [];
  193. this.systemListData.forEach((v) => {
  194. if (v.label === value.systemChecked) {
  195. v.modelList.forEach((ele) => {
  196. this.tableData.push({
  197. key: ele.id,
  198. deviceType: ele.deviceType || "--",
  199. modelName: ele.modelName || "--",
  200. functionAuth: ele.functionAuth || "--",
  201. });
  202. });
  203. }
  204. });
  205. if (
  206. this.addedRoleMap.has(
  207. `${value.groupChecked}-${value.systemChecked}`
  208. )
  209. ) {
  210. this.checkedUsers = this.addedRoleMap.get(
  211. `${value.groupChecked}-${value.systemChecked}`
  212. );
  213. } else {
  214. this.checkedUsers = [];
  215. }
  216. }
  217. },
  218. deep: true,
  219. // immediate: true,
  220. },
  221. checkedUsers(data) {
  222. if (
  223. this.checkedObj.groupChecked != "" &&
  224. this.checkedObj.systemChecked != ""
  225. ) {
  226. // group-system,作为key单独存
  227. this.addedRoleMap.set(
  228. `${this.checkedObj.groupChecked}-${this.checkedObj.systemChecked}`,
  229. data
  230. );
  231. this.addedRoleArr = [];
  232. if (data.length > 0) {
  233. this.addedRoleMap.forEach((v, i) => {
  234. v.forEach((ele, index) => {
  235. this.addedRoleArr.push({
  236. id: publicFunc.buildGuid("checked"),
  237. group: i.split("-")[0],
  238. system: i.split("-")[1],
  239. role: ele,
  240. });
  241. });
  242. });
  243. }
  244. }
  245. },
  246. },
  247. methods: {
  248. requireImg,
  249. groupClick(data) {
  250. this.checkedObj.groupChecked = data;
  251. },
  252. systemClick(data) {
  253. this.checkedObj.systemChecked = data;
  254. },
  255. // 删除添加的角色权限组列
  256. deleteEvent(data) {
  257. let targetArr = this.addedRoleMap
  258. .get(`${data.group}-${data.system}`)
  259. .filter((v) => {
  260. return v !== data.role;
  261. });
  262. // 删除后该系统还有别的角色
  263. if (targetArr.length > 0) {
  264. this.addedRoleMap.set(`${data.group}-${data.system}`, targetArr);
  265. // 同步配置权限列表
  266. this.checkedUsers = this.addedRoleMap.get(
  267. `${this.checkedObj.groupChecked}-${this.checkedObj.systemChecked}`
  268. );
  269. } else {
  270. // 删除全部角色
  271. this.addedRoleMap.delete(`${data.group}-${data.system}`);
  272. this.checkedObj.groupChecked = "";
  273. this.checkedObj.systemChecked = "";
  274. this.checkedUsers = [];
  275. }
  276. this.addedRoleArr = this.addedRoleArr.filter((v) => {
  277. return v.id !== data.id;
  278. });
  279. },
  280. initData() {
  281. // 获取key及其对应的数据
  282. this.userListGroup = this.userListData.map((v) => {
  283. this.keyDictObj[v.label] = v.id;
  284. return {
  285. content: v.label,
  286. value: v.label,
  287. };
  288. });
  289. this.roleListData.forEach((v, i) => {
  290. this.keyDictObj[v.label] = v.id;
  291. });
  292. this.systemListData.forEach((v, i) => {
  293. this.keyDictObj[v.label] = v.id;
  294. });
  295. },
  296. onChange(checkedValues) {
  297. console.log(checkedValues);
  298. },
  299. // 打开新建角色权限组对话框
  300. createRoleDialog() {
  301. this.visible.roleGroup = true;
  302. console.log("添加角色权限组");
  303. },
  304. // 打开添加用户对话框
  305. createUserDialog() {
  306. this.visible.user = true;
  307. console.log("添加用户事件");
  308. },
  309. addRoleGroupEvent() {
  310. console.log("保存新建的角色权限组");
  311. },
  312. onTreeSelectChange() {},
  313. onTreeSearch() {},
  314. cancelEvent() {},
  315. confirmEvent() {},
  316. },
  317. };
  318. </script>
  319. <template>
  320. <div class="auth-role">
  321. <div class="auth-role-title">配置权限</div>
  322. <div class="auth-role-content">
  323. <div class="left-box">
  324. <div class="left-box-inner">
  325. <div class="left-box-inner-list">
  326. <div class="add-role-group-box">
  327. <div class="add-role-group-btn" @click="createRoleDialog">
  328. 新建角色权限组
  329. </div>
  330. <a-modal
  331. v-model="visible.roleGroup"
  332. title="新建角色权限组"
  333. @ok="addRoleGroupEvent"
  334. >
  335. 组名:<a-input placeholder="请输入名称" v-model="inputName"></a-input>
  336. </a-modal>
  337. </div>
  338. <div
  339. class="left-box-inner-list-item"
  340. v-for="item in roleListData"
  341. :key="item.id"
  342. :class="{ active: checkedObj.groupChecked === item.label }"
  343. @click="groupClick(item.label)"
  344. >
  345. <img
  346. v-if="checkedObj.groupChecked === item.label"
  347. :src="requireImg('auth/group_blue.png')"
  348. class="icon-img"
  349. />
  350. <img
  351. v-else
  352. :src="requireImg('auth/group_gray.png')"
  353. class="icon-img"
  354. />
  355. <div class="text">{{ item.label }}</div>
  356. </div>
  357. </div>
  358. <div class="left-box-inner-list">
  359. <div
  360. class="left-box-inner-list-item"
  361. v-for="item in systemListData"
  362. :key="item.id"
  363. :class="{ active: checkedObj.systemChecked === item.label }"
  364. @click="systemClick(item.label)"
  365. >
  366. <img
  367. class="icon-img"
  368. v-if="checkedObj.systemChecked === item.label"
  369. :src="requireImg('auth/system_blue.png')"
  370. />
  371. <img
  372. class="icon-img"
  373. v-else
  374. :src="requireImg('auth/system_gray.png')"
  375. />
  376. <div class="text">{{ item.label }}</div>
  377. </div>
  378. </div>
  379. <div class="left-box-inner-list">
  380. <a-checkbox-group
  381. :options="userListGroup"
  382. v-model="checkedUsers"
  383. @change="onChange"
  384. >
  385. <template #label="value">
  386. <img
  387. v-if="checkedUsers.includes(value.content)"
  388. :src="requireImg('auth/role_blue.png')"
  389. class="icon-img"
  390. />
  391. <img
  392. v-else
  393. :src="requireImg('auth/role_gray.png')"
  394. class="icon-img"
  395. />
  396. <span
  397. :style="{
  398. color: checkedUsers.includes(value.content)
  399. ? '#66beff'
  400. : '#7f7f7f',
  401. }"
  402. >{{ value.content }}</span
  403. >
  404. </template>
  405. </a-checkbox-group>
  406. </div>
  407. </div>
  408. </div>
  409. <div class="right-box">
  410. <div class="title">权限列表</div>
  411. <a-table
  412. :data-source="tableData"
  413. :columns="columns"
  414. :scroll="{ y: 230 }"
  415. bordered
  416. ></a-table>
  417. </div>
  418. </div>
  419. <div class="auth-role-infolist">
  420. <div class="auth-role-infolist-inner">
  421. <div
  422. class="auth-role-infolist-inner-item"
  423. v-for="item in addedRoleArr"
  424. :key="item.id"
  425. >
  426. <div class="left-content">
  427. <a-breadcrumb separator=">">
  428. <a-breadcrumb-item>
  429. <img
  430. :src="requireImg('auth/group_blue.png')"
  431. class="icon-img"
  432. />
  433. <span class="selected-item">{{ item.group }}</span>
  434. </a-breadcrumb-item>
  435. <a-breadcrumb-item>
  436. <img
  437. :src="requireImg('auth/system_blue.png')"
  438. class="icon-img"
  439. />
  440. <span class="selected-item">{{ item.system }}</span>
  441. </a-breadcrumb-item>
  442. <a-breadcrumb-item>
  443. <img :src="requireImg('auth/role_blue.png')" class="icon-img" />
  444. <span class="selected-item">{{ item.role }}</span>
  445. </a-breadcrumb-item>
  446. </a-breadcrumb>
  447. </div>
  448. <div class="close-btn" @click="deleteEvent(item)"></div>
  449. </div>
  450. </div>
  451. </div>
  452. <div class="auth-role-select">
  453. <div class="auth-role-select-inner">
  454. <div class="top-section">
  455. <div class="top-section-inner">
  456. <div class="top-section-inner-title">选择人员</div>
  457. <div class="top-section-inner-select">
  458. <a-tree-select
  459. show-search
  460. v-model="value"
  461. multiple
  462. :dropdown-style="{ maxHeight: '200px', overflow: 'auto' }"
  463. placeholder="请选择查询内容"
  464. style="width: 100%"
  465. tree-checkable
  466. allow-clear
  467. :tree-data="treeData"
  468. tree-default-expand-all
  469. ></a-tree-select>
  470. </div>
  471. <div class="top-section-inner-button">
  472. <div class="add-user-btn" @click="createUserDialog">
  473. <div class="add-user-btn-icon"><div class="img"></div></div>
  474. <div class="add-user-btn-text">添加用户</div>
  475. </div>
  476. <a-modal v-model="visible.user" title="添加用户"></a-modal>
  477. </div>
  478. </div>
  479. </div>
  480. <div class="bottom-section">
  481. <div class="bottom-section-extra-box"></div>
  482. </div>
  483. </div>
  484. </div>
  485. <div class="auth-role-footer">
  486. <div class="auth-role-footer-inner">
  487. <div class="cancel-btn" @click="cancelEvent">取消</div>
  488. <div class="confirm-btn" @click="confirmEvent">确认</div>
  489. </div>
  490. </div>
  491. </div>
  492. </template>
  493. <style lang="less" scoped>
  494. @fontDefaultColor: #7f7f7f;
  495. @fontColor: #66beff;
  496. .auth-role {
  497. width: 100%;
  498. height: 100%;
  499. background: #fff;
  500. border-radius: 4px;
  501. &-title {
  502. width: 100%;
  503. height: 5%;
  504. // background: rgba(200, 200, 255, 0.5);
  505. display: flex;
  506. align-items: center;
  507. justify-content: flex-start;
  508. font-size: 14px;
  509. font-weight: bold;
  510. text-indent: 30px;
  511. }
  512. &-content {
  513. width: 100%;
  514. height: 50%;
  515. // background: peachpuff;
  516. display: flex;
  517. align-items: center;
  518. justify-content: space-around;
  519. .left-box {
  520. height: 100%;
  521. width: 48%;
  522. background: #fafafa;
  523. display: flex;
  524. align-items: center;
  525. justify-content: center;
  526. &-inner {
  527. width: calc(100% - 10px);
  528. height: calc(100% - 10px);
  529. display: flex;
  530. align-items: center;
  531. justify-content: space-around;
  532. &-list {
  533. height: 100%;
  534. width: 32%;
  535. border: 1px solid rgb(240, 241, 242);
  536. overflow: auto;
  537. position: relative;
  538. .ant-checkbox-group {
  539. display: flex;
  540. flex-direction: column;
  541. /deep/ .ant-checkbox-group-item {
  542. width: 100%;
  543. height: 40px;
  544. display: flex;
  545. align-items: center;
  546. margin-bottom: 10px;
  547. // background: rgba(100, 100, 150, 0.2);
  548. color: @fontDefaultColor;
  549. padding-left: 30px;
  550. .icon-img {
  551. width: 19.5px;
  552. height: 19.5px;
  553. margin-left: 10px;
  554. margin-right: 10px;
  555. }
  556. }
  557. }
  558. .add-role-group-box {
  559. position: absolute;
  560. bottom: 10px;
  561. width: 100%;
  562. height: 40px;
  563. display: flex;
  564. align-items: center;
  565. justify-content: center;
  566. .add-role-group-btn {
  567. position: absolute;
  568. bottom: 5px;
  569. width: 150px;
  570. height: 25px;
  571. background: #2ea8e6;
  572. color: #fff;
  573. border-radius: 5px;
  574. display: flex;
  575. align-items: center;
  576. justify-content: center;
  577. cursor: pointer;
  578. }
  579. }
  580. &-item {
  581. width: 100%;
  582. height: 40px;
  583. padding-left: 10px;
  584. color: @fontDefaultColor;
  585. display: flex;
  586. align-items: center;
  587. margin-bottom: 10px;
  588. cursor: pointer;
  589. .icon-img {
  590. width: 22px;
  591. height: 22px;
  592. margin-left: 10px;
  593. margin-right: 10px;
  594. }
  595. &.active {
  596. background: rgb(224, 239, 250, 0.8);
  597. color: @fontColor;
  598. }
  599. .text {
  600. width: calc(100% - 35px);
  601. height: 40px;
  602. display: flex;
  603. align-items: center;
  604. justify-content: flex-start;
  605. }
  606. }
  607. }
  608. }
  609. }
  610. .right-box {
  611. height: 100%;
  612. width: 45%;
  613. // background: rgb(255, 165, 0, 0.1);
  614. .title {
  615. width: 100%;
  616. height: 12%;
  617. display: flex;
  618. align-items: center;
  619. justify-content: flex-start;
  620. font-weight: 400;
  621. font-size: 16px;
  622. }
  623. .table {
  624. width: 100%;
  625. height: 88%;
  626. display: flex;
  627. align-items: center;
  628. justify-content: center;
  629. }
  630. }
  631. }
  632. &-infolist {
  633. width: 100%;
  634. height: 15%;
  635. display: flex;
  636. align-items: center;
  637. justify-content: center;
  638. margin-top: 10px;
  639. &-inner {
  640. background: #fafafa;
  641. width: calc(96% - 5px);
  642. height: calc(100% - 5px);
  643. border: 1px solid rgba(240, 241, 242, 0.3);
  644. overflow: auto;
  645. &-item {
  646. width: 100%;
  647. height: 40px;
  648. font-size: 16px;
  649. position: relative;
  650. .left-content {
  651. width: 60%;
  652. height: 40px;
  653. display: flex;
  654. align-items: center;
  655. position: absolute;
  656. left: 0;
  657. .selected-item {
  658. color: @fontColor;
  659. }
  660. .icon-img {
  661. width: 19.5px;
  662. height: 19.5px;
  663. margin-left: 10px;
  664. margin-right: 10px;
  665. }
  666. }
  667. .close-btn {
  668. position: absolute;
  669. top: 9px;
  670. right: 30px;
  671. width: 25px;
  672. height: 25px;
  673. display: flex;
  674. align-items: center;
  675. justify-content: center;
  676. cursor: pointer;
  677. background: url("@/assets/images/auth/close.png") no-repeat center;
  678. }
  679. }
  680. }
  681. }
  682. &-select {
  683. width: 100%;
  684. height: 19%;
  685. display: flex;
  686. align-items: center;
  687. justify-content: center;
  688. margin-top: 10px;
  689. &-inner {
  690. width: calc(96% - 5px);
  691. height: calc(100% - 10px);
  692. background: #fafafa;
  693. border: 1px solid rgba(240, 241, 242, 0.3);
  694. overflow: auto;
  695. .top-section {
  696. width: 100%;
  697. height: 30%;
  698. display: flex;
  699. align-items: center;
  700. justify-content: center;
  701. &-inner {
  702. height: 100%;
  703. width: 98%;
  704. display: flex;
  705. align-items: center;
  706. justify-content: center;
  707. &-title {
  708. width: 8%;
  709. height: 100%;
  710. display: flex;
  711. align-items: center;
  712. justify-content: center;
  713. }
  714. &-select {
  715. width: 82%;
  716. height: 100%;
  717. display: flex;
  718. align-items: center;
  719. }
  720. &-button {
  721. width: 10%;
  722. height: 100%;
  723. display: flex;
  724. align-items: center;
  725. justify-content: center;
  726. .add-user-btn {
  727. width: 70%;
  728. height: 100%;
  729. display: flex;
  730. align-items: center;
  731. justify-content: center;
  732. cursor: pointer;
  733. &-icon {
  734. width: 30%;
  735. height: 100%;
  736. display: flex;
  737. align-items: center;
  738. justify-content: center;
  739. .img {
  740. width: 22px;
  741. height: 22px;
  742. background: url("@/assets/images/auth/plus-square.png")
  743. no-repeat center;
  744. }
  745. }
  746. &-text {
  747. width: 70%;
  748. height: 100%;
  749. display: flex;
  750. align-items: center;
  751. justify-content: center;
  752. color: #2ea8e6;
  753. }
  754. }
  755. }
  756. }
  757. }
  758. .bottom-section {
  759. width: 100%;
  760. height: 70%;
  761. display: flex;
  762. align-items: center;
  763. justify-content: center;
  764. &-extra-box {
  765. background: #fff;
  766. width: calc(90% - 10px);
  767. height: calc(90% - 10px);
  768. border: 1px solid rgba(240, 241, 242, 0.3);
  769. }
  770. }
  771. }
  772. }
  773. &-footer {
  774. margin-top: 10px;
  775. width: 100%;
  776. height: 5%;
  777. display: flex;
  778. align-items: center;
  779. justify-content: center;
  780. &-inner {
  781. width: 20%;
  782. height: 100%;
  783. display: flex;
  784. align-items: center;
  785. justify-content: space-around;
  786. .cancel-btn,
  787. .confirm-btn {
  788. width: 80px;
  789. height: 25px;
  790. border-radius: 5px;
  791. display: flex;
  792. align-items: center;
  793. justify-content: center;
  794. cursor: pointer;
  795. color: #fff;
  796. }
  797. .cancel-btn {
  798. background: #b3b3b3;
  799. }
  800. .confirm-btn {
  801. background: #2ea8e6;
  802. }
  803. }
  804. }
  805. }
  806. </style>