Navbar.vue 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832
  1. <template>
  2. <div class="navbar">
  3. <!-- <hamburger :is-active="sidebar.opened" class="hamburger-container" @toggleClick="toggleSideBar" /> -->
  4. <router-link
  5. key="collapse"
  6. style="display: flex; align-items: center; padding-left: 30px"
  7. to="/"
  8. >
  9. <img
  10. v-if="tenantLogo"
  11. :src="tenantLogo"
  12. class="sidebar-logo"
  13. style="width: 36px; height: 36px"
  14. />
  15. <img
  16. v-else
  17. src="@/assets/images/base/logo.png"
  18. class="sidebar-logo"
  19. style="width: 36px; height: 36px"
  20. />
  21. <span class="tenantName" :title="tenantName">{{ tenantName }}</span>
  22. </router-link>
  23. <!-- <breadcrumb class="breadcrumb-container" /> -->
  24. <div class="indexlayout-top-menu">
  25. <!-- :class="{'active': getTopMenuActive === route.path}" -->
  26. <!-- el-scrollbar -->
  27. <el-scrollbar
  28. class="horizontal-scrollbar"
  29. style="overflow: hidden; height: 100%"
  30. >
  31. <template v-for="route in permission_routes">
  32. <app-link
  33. v-if="!route.hidden"
  34. :to="route.path"
  35. :key="route.id"
  36. class="indexlayout-top-menu-li"
  37. :class="{ active: getTopMenuActive === route.path }"
  38. >
  39. <div style="display: flex; align-items: center; justify-content: center; flex-direction: column; height: 76px;">
  40. <i :class="[route.meta.icon, 'menuSize']"></i>
  41. <span style="line-height: 1.2">{{ route.meta.title }}</span>
  42. </div>
  43. </app-link>
  44. </template>
  45. </el-scrollbar>
  46. </div>
  47. <div class="right-menu">
  48. <el-popover
  49. placement="bottom"
  50. trigger="hover"
  51. style="display: flex;"
  52. v-if="tenantForm.tenantId == 1"
  53. >
  54. <div class="popover-container" style="text-align: center">OA审批</div>
  55. <div
  56. class="msginfo right-position"
  57. @click="gotoOa"
  58. slot="reference"
  59. >
  60. <i class="icon_admin_oa operationSize"></i>
  61. </div>
  62. </el-popover>
  63. <!-- <el-popover
  64. v-if="isShowIns"
  65. placement="bottom"
  66. trigger="hover"
  67. style="display: flex;"
  68. >
  69. <div class="popover-container" style="text-align: center">操作手册</div>
  70. <div
  71. class="msginfo right-position"
  72. @click="openIns"
  73. slot="reference"
  74. >
  75. <i class="icon_admin_book operationSize"></i>
  76. </div>
  77. </el-popover> -->
  78. <el-popover
  79. placement="bottom"
  80. trigger="hover"
  81. style="display: flex;"
  82. >
  83. <div class="popover-container" style="text-align: center">系统日志</div>
  84. <div
  85. class="msginfo right-position"
  86. v-permission="'/journal'"
  87. @click="gotoRecode"
  88. slot="reference"
  89. >
  90. <i class="icon_admin_message operationSize"></i>
  91. </div>
  92. </el-popover>
  93. <div class="left-menu" style="margin-right: 12px">
  94. <el-popover
  95. placement="top-start"
  96. width="300"
  97. trigger="hover"
  98. style="display: flex;"
  99. >
  100. <div class="popover-container">
  101. <el-tag
  102. class="navbar_tag"
  103. type="info"
  104. v-for="item in organNameList"
  105. :key="item"
  106. >{{ item }}</el-tag
  107. >
  108. </div>
  109. <span
  110. slot="reference"
  111. class="msginfo right-position"
  112. >
  113. <i class="icon_admin_orgin operationSize"></i>
  114. </span>
  115. </el-popover>
  116. </div>
  117. <el-dropdown class="avatar-container" trigger="hover">
  118. <div class="avatar-wrapper">
  119. <img
  120. v-if="$store.getters.avatar"
  121. :src="$store.getters.avatar"
  122. class="user-avatar"
  123. />
  124. <img
  125. v-else
  126. class="user-avatar"
  127. src="@/assets/images/base/placehorder-icon.png"
  128. />
  129. <span>{{ username }}</span>
  130. </div>
  131. <el-dropdown-menu slot="dropdown" class="user-dropdown">
  132. <div class="drop_userInfo">
  133. <div class="avatar-wrapper">
  134. <img
  135. v-if="$store.getters.avatar"
  136. :src="$store.getters.avatar"
  137. class="user-avatar"
  138. />
  139. <img
  140. v-else
  141. class="user-avatar"
  142. src="@/assets/images/base/placehorder-icon.png"
  143. />
  144. <div>
  145. <span>{{ username }}</span>
  146. <p class="positionName" :title="positionName">{{ positionName }}</p>
  147. </div>
  148. </div>
  149. </div>
  150. <div class="tenantService" v-if="!tenantStatus">
  151. <div class="serviceName">
  152. <p class="name">{{ tenantInfo.serverName }}</p>
  153. <div class="serviceRenew" @click="onRenew" v-if="$helpers.permission('/ productService') && $helpers.permission('/serviceRenew')">立即续费</div>
  154. </div>
  155. <div class="serviceTime" v-if="tenantInfo.validRemaining > 0">
  156. 剩余{{ tenantInfo.validRemaining }}天({{ tenantInfo.expiryDateEnd }})到期
  157. </div>
  158. <div class="serviceTime" v-else>
  159. 已过期
  160. </div>
  161. </div>
  162. <!-- divided -->
  163. <el-dropdown-item v-if="tenantStatus" @click.native="onTenantChange">
  164. <i class="icon_admin_tenant userSize"></i>
  165. <span class="dropdown-text">{{ tenantName }}</span>
  166. <i style="margin-left: 3px" class="icon_admin_change userSize"></i>
  167. </el-dropdown-item>
  168. <el-dropdown-item @click.native="resetPassWord">
  169. <i class="icon_admin_edit userSize"></i>
  170. <span class="dropdown-text">修改密码</span>
  171. </el-dropdown-item>
  172. <el-dropdown-item @click.native="accountStatus = true" v-if="$helpers.permission('/tenantInfoSetting')">
  173. <i class="icon_admin_account userSize"></i>
  174. <span class="dropdown-text">账号设置</span>
  175. </el-dropdown-item>
  176. <el-dropdown-item style="border-top: 1px solid #E5E5E5;" @click.native="logout">
  177. <i class="icon_admin_exit userSize"></i>
  178. <span class="dropdown-text">安全退出</span>
  179. </el-dropdown-item>
  180. </el-dropdown-menu>
  181. </el-dropdown>
  182. </div>
  183. <el-dialog
  184. title="修改密码"
  185. width="500px"
  186. append-to-body
  187. :visible.sync="resetVisible"
  188. >
  189. <el-form
  190. :model="resetForm"
  191. label-position="right"
  192. label-width="100px"
  193. ref="pwdForm"
  194. >
  195. <el-form-item label="手机号" prop="phone">
  196. <div>{{ this.$store.getters.phone }}</div>
  197. </el-form-item>
  198. <el-form-item
  199. label="新密码"
  200. :rules="[
  201. { required: true, message: '密码不能为空', trigger: 'blur' },
  202. {
  203. pattern: /^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z]{6,20}$/,
  204. message: '密码为6-20位数字和字母组合',
  205. trigger: 'blur',
  206. },
  207. ]"
  208. prop="password"
  209. >
  210. <el-input
  211. v-model.trim="resetForm.password"
  212. type="password"
  213. style="width: 180px"
  214. autocomplete="off"
  215. ></el-input>
  216. </el-form-item>
  217. <el-form-item
  218. label="再次输入"
  219. :rules="[
  220. { required: true, message: '密码不能为空', trigger: 'blur' },
  221. {
  222. pattern: /^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z]{6,20}$/,
  223. message: '密码为6-20位数字和字母组合',
  224. trigger: 'blur',
  225. },
  226. ]"
  227. prop="password2"
  228. >
  229. <el-input
  230. v-model.trim="resetForm.password2"
  231. type="password"
  232. style="width: 180px"
  233. autocomplete="off"
  234. ></el-input>
  235. </el-form-item>
  236. <el-form-item
  237. label="验证码"
  238. :rules="[
  239. { required: true, message: '验证码不能为空', trigger: 'blur' },
  240. ]"
  241. prop="authCode"
  242. style=""
  243. >
  244. <el-input
  245. v-model.trim="resetForm.authCode"
  246. style="width: 180px"
  247. autocomplete="off"
  248. ></el-input>
  249. <el-button :disabled="isDisable" @click="getCode">{{
  250. btnName
  251. }}</el-button>
  252. </el-form-item>
  253. </el-form>
  254. <div slot="footer" class="dialog-footer">
  255. <el-button @click="resetVisible = false">取 消</el-button>
  256. <el-button type="primary" @click="submitResetPassWord">确 定</el-button>
  257. </div>
  258. </el-dialog>
  259. <el-dialog
  260. title="切换机构"
  261. width="500px"
  262. append-to-body
  263. v-if="tenantVisible"
  264. :visible.sync="tenantVisible"
  265. >
  266. <el-form
  267. :model="tenantForm"
  268. label-position="right"
  269. label-width="100px"
  270. ref="tenantForm"
  271. >
  272. <el-form-item
  273. label="选择机构"
  274. :rules="[
  275. { required: true, message: '请选择机构', trigger: 'change' }
  276. ]"
  277. prop="tenantId"
  278. >
  279. <el-select
  280. v-model.trim="tenantForm.tenantId"
  281. filterable
  282. placeholder="请选择机构"
  283. clearable
  284. style="width: 100% !important"
  285. >
  286. <el-option v-for="(item, index) in tenantList" :key="index" :label="item.name" :value="item.id"></el-option>
  287. </el-select>
  288. </el-form-item>
  289. </el-form>
  290. <div slot="footer" class="dialog-footer">
  291. <el-button @click="tenantVisible = false">取 消</el-button>
  292. <el-button type="primary" @click="submitTenant">确 定</el-button>
  293. </div>
  294. </el-dialog>
  295. <el-dialog
  296. title="账号设置"
  297. append-to-body
  298. :visible.sync="accountStatus"
  299. v-if="accountStatus"
  300. width="650px"
  301. >
  302. <user-model @close="accountStatus = false"></user-model>
  303. </el-dialog>
  304. <!-- <portal-target name="AppMain" ref="target">
  305. <instructions ref="instructions" @checkShow="checkShow" />
  306. </portal-target> -->
  307. </div>
  308. </template>
  309. <script>
  310. import qs from "qs";
  311. import Logo from "./Sidebar/Logo";
  312. import { mapGetters } from "vuex";
  313. // import Breadcrumb from '@/components/Breadcrumb'
  314. // import Hamburger from '@/components/Hamburger'
  315. import { resetPassword } from "@/api/buildTeam";
  316. import AppLink from "./Sidebar/Link";
  317. import { getBelongTopMenuPath } from "@/utils/permission";
  318. // import instructions from "./instructions";
  319. import { validOaUrl } from '@/utils/validate'
  320. import { tenantInfoQueryPage } from '@/views/organManager/api'
  321. import Cookies from 'js-cookie'
  322. import axios from 'axios'
  323. import userModel from './modal/userModal'
  324. export default {
  325. data() {
  326. let tenantConfig = sessionStorage.getItem('tenantConfig')
  327. tenantConfig = tenantConfig ? JSON.parse(tenantConfig) : {}
  328. return {
  329. accountStatus: false,
  330. username: "",
  331. organName: this.$store.getters.organName,
  332. organNameList: [],
  333. resetVisible: false,
  334. resetForm: {
  335. phone: "",
  336. authCode: "",
  337. password: "",
  338. password2: "",
  339. },
  340. isDisable: false, // 是否允许发送验证码
  341. timerCount: 60,
  342. btnName: "获取验证码",
  343. isShowIns: false,
  344. tenantVisible: false,
  345. tenantName: tenantConfig.tenantName || null,
  346. tenantForm: {
  347. tenantId: Number(tenantConfig.tenantId) || null,
  348. },
  349. tenantList: [],
  350. tenantLogo: tenantConfig.tenantLogo || null,
  351. };
  352. },
  353. components: {
  354. AppLink,
  355. userModel
  356. // instructions,
  357. // Breadcrumb,
  358. // Hamburger
  359. },
  360. computed: {
  361. ...mapGetters(["sidebar", "avatar", "positionName", "permission_routes", "tenantInfo"]),
  362. getTopMenuActive() {
  363. let route = this.$route;
  364. // (route, getBelongTopMenuPath(route))
  365. return getBelongTopMenuPath(route);
  366. },
  367. tenantStatus() { // 判断是否是平台账号 true 是
  368. const baseTenantId = sessionStorage.getItem('baseTenantId')
  369. return baseTenantId < 0 ? true : false
  370. },
  371. },
  372. mounted() {
  373. // 手动加入
  374. this.toggleSideBar();
  375. this.username = this.$store.getters.name;
  376. this.organNameList = this.organName.split(",") || [];
  377. },
  378. methods: {
  379. toggleSideBar() {
  380. this.$store.dispatch("app/toggleSideBar");
  381. },
  382. async logout() {
  383. await this.$store.dispatch("user/logout");
  384. localStorage.removeItem("firstMenuUrl");
  385. // await this.$store.dispatch("permission/removePermission")
  386. this.$router.push(`/login`);
  387. window.location.reload();
  388. },
  389. async onTenantChange() {
  390. try {
  391. const res = await tenantInfoQueryPage({ page: 1, rows: 999, payState: 1 }, )
  392. this.tenantList = res.data?.rows || []
  393. this.tenantVisible = true
  394. } catch(e) {}
  395. },
  396. onRenew() {
  397. this.$router.push('/productService')
  398. },
  399. submitTenant() {
  400. this.$refs['tenantForm'].validate((res) => {
  401. if(res) {
  402. const tenantForm = this.tenantForm
  403. let tenantName = null
  404. let tenantLogo = null
  405. this.tenantList.forEach(item => {
  406. if(item.id == tenantForm.tenantId) {
  407. tenantName = item.name
  408. tenantLogo = item.logo
  409. this.tenantName = item.name
  410. this.tenantLogo = item.logo
  411. }
  412. });
  413. let tenantConfig = sessionStorage.getItem('tenantConfig')
  414. tenantConfig = tenantConfig ? JSON.parse(tenantConfig) : {}
  415. if(tenantConfig.tenantId != tenantForm.tenantId) {
  416. //判断是否是当前路由
  417. // if(url == this.$route.path) {
  418. tenantConfig.tenantId = tenantForm.tenantId
  419. tenantConfig.tenantName = tenantName
  420. tenantConfig.tenantLogo = tenantLogo
  421. sessionStorage.setItem('tenantConfig', JSON.stringify(tenantConfig))
  422. this.$router.push({
  423. path: '/redirect',
  424. query: this.$route.fullPath
  425. })
  426. // } else {
  427. // this.$router.push({
  428. // path: url
  429. // })
  430. // }
  431. }
  432. }
  433. })
  434. },
  435. gotoRecode() {
  436. this.$router.push("/journal/journal");
  437. },
  438. resetPassWord() {
  439. this.resetVisible = true;
  440. },
  441. submitResetPassWord() {
  442. if (this.resetForm.password !== this.resetForm.password2) {
  443. this.$message.error("两次密码必须相同");
  444. return;
  445. }
  446. this.$refs["pwdForm"].validate((res) => {
  447. if (res) {
  448. // 发请求
  449. resetPassword({
  450. authCode: this.resetForm.authCode,
  451. mobile: this.$store.getters.phone,
  452. newPassword: this.resetForm.password,
  453. }).then((res) => {
  454. if (res.code == 200) {
  455. // 修改成功
  456. this.$message.success("修改成功");
  457. this.logout();
  458. }
  459. });
  460. }
  461. });
  462. },
  463. getCode() {
  464. // 获取验证码
  465. if (!this.$store.getters.phone) {
  466. this.$message.error("请输入正确的手机号");
  467. return;
  468. }
  469. if (!this.isDisable) {
  470. this.isDisable = true;
  471. // 发请求成功后开启定时器
  472. // 发送验证码
  473. axios
  474. .post(
  475. "/api-web/code/sendSms",
  476. qs.stringify({ mobile: this.$store.getters.phone })
  477. )
  478. .then((res) => {
  479. if (res.data.code == 200) {
  480. let timer = setInterval((res) => {
  481. if (this.timerCount <= 0) {
  482. clearInterval(timer);
  483. this.isDisable = false;
  484. this.btnName = "获取验证码";
  485. this.timerCount = 60;
  486. } else {
  487. this.timerCount--;
  488. this.btnName = `${this.timerCount}s后重试`;
  489. }
  490. }, 1000);
  491. }
  492. });
  493. }
  494. },
  495. openIns() {
  496. // this.$refs.instructions.showInstructions();
  497. },
  498. checkShow(val) {
  499. this.isShowIns = val;
  500. },
  501. gotoOa(){
  502. // console.log(validOaUrl())
  503. // const Token = Cookies.get('cross-Token')
  504. // console.log(Token, validOaUrl().split('//')[1])
  505. // Cookies.set('Admin-Token', Token, { domain: `.${validOaUrl().split('//')[1]}`, path: '/' })
  506. // document.cookie = `Adminoken=${Token};domain=oadev.dayaedu.com;`
  507. window.open(validOaUrl())
  508. }
  509. },
  510. watch: {
  511. resetVisible(val) {
  512. if (!val) {
  513. this.resetForm = {
  514. phone: "",
  515. authCode: "",
  516. password: "",
  517. password2: "",
  518. };
  519. }
  520. },
  521. },
  522. };
  523. </script>
  524. <style lang="scss" scoped>
  525. .navbar_tag {
  526. margin: 0 5px 8px;
  527. }
  528. .indexlayout-top-menu {
  529. padding-left: 57px;
  530. height: 76px;
  531. line-height: 76px;
  532. flex: 1;
  533. display: flex;
  534. overflow: hidden;
  535. /* overflow-x: auto; */
  536. .indexlayout-top-menu-li {
  537. display: table-cell;
  538. padding: 0 5px;
  539. height: 76px;
  540. text-decoration: none;
  541. color: #f2f2f2;
  542. font-size: 16px;
  543. transition: all 0.3s ease;
  544. span {
  545. // display: block;
  546. transition: all 0.3s ease;
  547. // padding: 10px 20px;
  548. padding: 8px 20px 3px;
  549. }
  550. &:hover,
  551. &.active {
  552. span {
  553. font-weight: 500;
  554. // border-radius: 6px;
  555. }
  556. }
  557. // &.active span {
  558. // font-weight: bold;
  559. // }
  560. }
  561. .breadcrumb {
  562. line-height: 76px;
  563. margin-left: 10px;
  564. .el-breadcrumb__item {
  565. display: inline-block;
  566. float: none;
  567. }
  568. }
  569. }
  570. .popover-container {
  571. max-height: 350px;
  572. overflow-y: scroll;
  573. }
  574. .navbar {
  575. display: flex;
  576. flex-direction: row;
  577. justify-content: space-between;
  578. height: 76px;
  579. overflow: hidden;
  580. position: relative;
  581. z-index: 2000;
  582. box-shadow: 0px 8px 20px 0px rgba(0, 0, 0, 0.1);
  583. h2 {
  584. font-size: 18px;
  585. line-height: 76px;
  586. margin: 0 0 0 30px;
  587. display: inline-block;
  588. }
  589. .hamburger-container {
  590. line-height: 76px;
  591. height: 100%;
  592. float: left;
  593. cursor: pointer;
  594. transition: background 0.3s;
  595. -webkit-tap-highlight-color: transparent;
  596. &:hover {
  597. background: rgba(0, 0, 0, 0.025);
  598. }
  599. }
  600. .breadcrumb-container {
  601. float: left;
  602. }
  603. .left-menu {
  604. line-height: 76px;
  605. // padding-right: 22px;
  606. font-size: 16px;
  607. .topIcon {
  608. width: 20px;
  609. height: 25px;
  610. }
  611. }
  612. .right-menu {
  613. min-width: 154px;
  614. float: right;
  615. height: 100%;
  616. line-height: 76px;
  617. display: flex;
  618. flex-direction: row;
  619. justify-content: flex-start;
  620. &:focus {
  621. outline: none;
  622. }
  623. .msginfo.ins {
  624. img {
  625. width: 18px;
  626. height: 23px;
  627. }
  628. }
  629. .msginfo {
  630. display: flex;
  631. flex-direction: row;
  632. justify-content: flex-start;
  633. align-items: center;
  634. padding: 0 12px;
  635. position: relative;
  636. cursor: pointer;
  637. img {
  638. width: 24px;
  639. height: 24px;
  640. }
  641. .active {
  642. position: absolute;
  643. width: 7px;
  644. height: 7px;
  645. background-color: #f97215;
  646. border-radius: 50%;
  647. top: 20px;
  648. right: -4px;
  649. }
  650. }
  651. .right-menu-item {
  652. display: inline-block;
  653. padding: 0 8px;
  654. height: 100%;
  655. font-size: 14px;
  656. color: #5a5e66;
  657. vertical-align: text-bottom;
  658. &.hover-effect {
  659. cursor: pointer;
  660. transition: background 0.3s;
  661. &:hover {
  662. background: rgba(0, 0, 0, 0.025);
  663. }
  664. }
  665. }
  666. .avatar-container {
  667. height: 76px;
  668. margin-right: 42px;
  669. cursor: pointer;
  670. .avatar-wrapper {
  671. position: relative;
  672. display: flex;
  673. flex-direction: row;
  674. justify-content: flex-start;
  675. align-items: center;
  676. span {
  677. margin-left: 8px;
  678. font-size: 14px;
  679. font-weight: 500;
  680. // color: rgba(68, 68, 68, 1);
  681. color: #fff;
  682. }
  683. .user-avatar {
  684. cursor: pointer;
  685. width: 32px;
  686. height: 32px;
  687. border: 2px solid #f0f2f5;
  688. border-radius: 50%;
  689. }
  690. .el-icon-caret-bottom {
  691. cursor: pointer;
  692. position: absolute;
  693. right: -20px;
  694. top: 25px;
  695. font-size: 14px;
  696. }
  697. }
  698. }
  699. }
  700. }
  701. .user-dropdown {
  702. width: 258px;
  703. padding-top: 0 !important;
  704. box-shadow: 0px 2px 13px 0px rgba(0, 0, 0, 0.05);
  705. /deep/.popper__arrow {
  706. border-bottom-color: var(--color-primary) !important;
  707. &::after {
  708. border-bottom-color: var(--color-primary) !important;
  709. }
  710. }
  711. .drop_userInfo {
  712. background-color: var(--color-primary);
  713. height: 64px;
  714. color: #fff;
  715. padding: 0 12px;
  716. border-radius: 4px 4px 0 0;
  717. display: flex;
  718. align-items: center;
  719. .avatar-wrapper {
  720. display: flex;
  721. align-items: center;
  722. background: url("../../assets/images/user_tips.png") no-repeat right center;
  723. background-size: 45%;
  724. width: 100%;
  725. .user-avatar {
  726. width: 38px;
  727. height: 38px;
  728. border-radius: 50%;
  729. margin-right: 10px;
  730. }
  731. }
  732. }
  733. .tenantService {
  734. border-bottom: 1px solid #E5E5E5;
  735. padding: 18px 17px 12px;
  736. .serviceName {
  737. display: flex;
  738. align-items: center;
  739. justify-content: space-between;
  740. .name {
  741. font-size: 18px;
  742. font-weight: 600;
  743. color: var(--color-primary);
  744. line-height: 25px;
  745. width: 160px;
  746. overflow: hidden;
  747. text-overflow: ellipsis;
  748. white-space: nowrap;
  749. }
  750. .serviceRenew {
  751. width: 63px;
  752. height: 22px;
  753. background: linear-gradient(270deg, #FFC65E 0%, #FFE8A6 100%);
  754. border-radius: 11px;
  755. line-height: 22px;
  756. font-size: 11px;
  757. font-weight: 400;
  758. color: #981E13;
  759. text-align: center;
  760. cursor: pointer;
  761. }
  762. }
  763. .serviceTime {
  764. margin-top: 15px;
  765. font-size: 13px;
  766. font-weight: 400;
  767. color: #333333;
  768. line-height: 18px;
  769. }
  770. }
  771. .el-dropdown-menu__item {
  772. display: flex;
  773. align-items: center;
  774. // margin: 3px 17px;
  775. padding: 7px 17px;
  776. }
  777. .dropdown-text {
  778. display: block;
  779. width: 180px;
  780. overflow: hidden;
  781. text-overflow: ellipsis;
  782. white-space: nowrap;
  783. }
  784. }
  785. .right-position {
  786. display: flex;
  787. align-items: center;
  788. justify-content: center;
  789. height: 75px;
  790. }
  791. .sidebar-logo {
  792. margin-right: 8px;
  793. }
  794. .tenantName {
  795. font-size: 20px;
  796. font-family: PingFangSC-Semibold, PingFang SC;
  797. font-weight: 600;
  798. color: #FFFFFF;
  799. line-height: 28px;
  800. max-width: 150px;
  801. white-space: nowrap;
  802. text-overflow: ellipsis;
  803. overflow: hidden;
  804. }
  805. .positionName {
  806. font-size: 12px;
  807. width: 145px;
  808. white-space: nowrap;
  809. overflow: hidden;
  810. text-overflow: ellipsis;
  811. }
  812. </style>