78c1ce8b942990ddf2a717040a03935651e62a26.svn-base 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303
  1. <template>
  2. <div class="user-wrapper" :class="theme">
  3. <!-- update_begin author:zhaoxin date:20191129 for: 做头部菜单栏导航 -->
  4. <!-- update-begin author:sunjianlei date:20191@20 for: 解决全局样式冲突的问题 -->
  5. <span class="action" @click="showClick">
  6. <a-icon type="search"></a-icon>
  7. </span>
  8. <!-- update-begin author:sunjianlei date:20200219 for: 菜单搜索改为动态组件,在手机端呈现出弹出框 -->
  9. <component :is="searchMenuComp" v-show="searchMenuVisible || isMobile()" class="borders" :visible="searchMenuVisible" title="搜索菜单" :footer="null" @cancel="searchMenuVisible=false">
  10. <a-select
  11. class="search-input"
  12. showSearch
  13. :showArrow="false"
  14. placeholder="搜索菜单"
  15. optionFilterProp="children"
  16. :filterOption="filterOption"
  17. :open="isMobile()?true:null"
  18. :getPopupContainer="(node) => node.parentNode"
  19. :style="isMobile()?{width: '100%',marginBottom:'50px'}:{}"
  20. @change="searchMethods"
  21. @blur="hiddenClick"
  22. >
  23. <a-select-option v-for="(site,index) in searchMenuOptions" :key="index" :value="site.id">{{site.meta.title}}</a-select-option>
  24. </a-select>
  25. </component>
  26. <!-- update-end author:sunjianlei date:20200219 for: 菜单搜索改为动态组件,在手机端呈现出弹出框 -->
  27. <!-- update-end author:sunjianlei date:20191220 for: 解决全局样式冲突的问题 -->
  28. <!-- update_end author:zhaoxin date:20191129 for: 做头部菜单栏导航 -->
  29. <span class="action">
  30. <a class="logout_title" target="_blank" :href="getManualUrl()">
  31. <a-icon type="question-circle-o"></a-icon>
  32. </a>
  33. </span>
  34. <header-notice class="action"/>
  35. <a-popover class="action" trigger="click" placement="bottomRight">
  36. <template slot="content">
  37. <img src="../../assets/app.png" height="240" width="240"/>
  38. </template>
  39. <a-icon style="font-size: 16px;" type="android" />
  40. </a-popover>
  41. <a-dropdown>
  42. <span class="action action-full ant-dropdown-link user-dropdown-menu">
  43. <a-avatar class="avatar" size="small" :src="getAvatar()"/>
  44. <span v-if="isDesktop()">欢迎您,{{ nickname() }}</span>
  45. </span>
  46. <a-menu slot="overlay" class="user-dropdown-menu-wrapper">
  47. <a-menu-item key="0">
  48. <router-link :to="{ name: 'account-center' }">
  49. <a-icon type="user"/>
  50. <span>个人中心</span>
  51. </router-link>
  52. </a-menu-item>
  53. <a-menu-item key="1">
  54. <router-link :to="{ name: 'account-settings-base' }">
  55. <a-icon type="setting"/>
  56. <span>账户设置</span>
  57. </router-link>
  58. </a-menu-item>
  59. <a-menu-item key="3" @click="systemSetting">
  60. <a-icon type="tool"/>
  61. <span>系统设置</span>
  62. </a-menu-item>
  63. <a-menu-item key="4" @click="updatePassword">
  64. <a-icon type="setting"/>
  65. <span>密码修改</span>
  66. </a-menu-item>
  67. <a-menu-item key="5" @click="updateCurrentDepart">
  68. <a-icon type="cluster"/>
  69. <span>切换部门</span>
  70. </a-menu-item>
  71. <a-menu-item key="6" @click="clearCache">
  72. <a-icon type="sync"/>
  73. <span>清理缓存</span>
  74. </a-menu-item>
  75. <!-- <a-menu-item key="2" disabled>
  76. <a-icon type="setting"/>
  77. <span>测试</span>
  78. </a-menu-item>
  79. <a-menu-divider/>
  80. <a-menu-item key="3">
  81. <a href="javascript:;" @click="handleLogout">
  82. <a-icon type="logout"/>
  83. <span>退出登录</span>
  84. </a>
  85. </a-menu-item>-->
  86. </a-menu>
  87. </a-dropdown>
  88. <span class="action">
  89. <a class="logout_title" href="javascript:;" @click="handleLogout">
  90. <a-icon type="logout"/>
  91. <span v-if="isDesktop()">&nbsp;退出登录</span>
  92. </a>
  93. </span>
  94. <user-password ref="userPassword"></user-password>
  95. <depart-select ref="departSelect" :closable="true" title="部门切换"></depart-select>
  96. <setting-drawer ref="settingDrawer" :closable="true" title="系统设置"></setting-drawer>
  97. </div>
  98. </template>
  99. <script>
  100. import HeaderNotice from './HeaderNotice'
  101. import UserPassword from './UserPassword'
  102. import SettingDrawer from "@/components/setting/SettingDrawer";
  103. import DepartSelect from './DepartSelect'
  104. import { mapActions, mapGetters,mapState } from 'vuex'
  105. import { mixinDevice } from '@/utils/mixin.js'
  106. import { getFileAccessHttpUrl,getAction } from "@/api/manage"
  107. import Vue from 'vue'
  108. import { UI_CACHE_DB_DICT_DATA } from "@/store/mutation-types"
  109. export default {
  110. name: "UserMenu",
  111. mixins: [mixinDevice],
  112. data(){
  113. return{
  114. // update-begin author:sunjianlei date:20200219 for: 头部菜单搜索规范命名 --------------
  115. searchMenuOptions:[],
  116. searchMenuComp: 'span',
  117. searchMenuVisible: false,
  118. // update-begin author:sunjianlei date:20200219 for: 头部菜单搜索规范命名 --------------
  119. }
  120. },
  121. components: {
  122. HeaderNotice,
  123. UserPassword,
  124. DepartSelect,
  125. SettingDrawer
  126. },
  127. props: {
  128. theme: {
  129. type: String,
  130. required: false,
  131. default: 'dark'
  132. }
  133. },
  134. /* update_begin author:zhaoxin date:20191129 for: 做头部菜单栏导航*/
  135. created() {
  136. let lists = []
  137. this.searchMenus(lists,this.permissionMenuList)
  138. this.searchMenuOptions=[...lists]
  139. },
  140. mounted() {
  141. //如果是单点登录模式
  142. if (process.env.VUE_APP_SSO == 'true') {
  143. let depart = this.userInfo().orgCode
  144. if (!depart) {
  145. this.updateCurrentDepart()
  146. }
  147. }
  148. },
  149. computed: {
  150. ...mapState({
  151. // 后台菜单
  152. permissionMenuList: state => state.user.permissionList
  153. })
  154. },
  155. /* update_end author:zhaoxin date:20191129 for: 做头部菜单栏导航*/
  156. watch: {
  157. // update-begin author:sunjianlei date:20200219 for: 菜单搜索改为动态组件,在手机端呈现出弹出框
  158. device: {
  159. immediate: true,
  160. handler() {
  161. this.searchMenuVisible = false
  162. this.searchMenuComp = this.isMobile() ? 'a-modal' : 'span'
  163. },
  164. },
  165. // update-end author:sunjianlei date:20200219 for: 菜单搜索改为动态组件,在手机端呈现出弹出框
  166. },
  167. methods: {
  168. getManualUrl(){
  169. let fileUrl = window._CONFIG['domianURL']+"/manual/用户手册.pdf"
  170. let manualUrl = window._CONFIG['domianURL'] + "/generic/web/viewer.html?file=" + encodeURIComponent(fileUrl);
  171. return manualUrl;
  172. },
  173. /* update_begin author:zhaoxin date:20191129 for: 做头部菜单栏导航*/
  174. showClick() {
  175. this.searchMenuVisible = true
  176. },
  177. hiddenClick(){
  178. this.shows = false
  179. },
  180. /* update_end author:zhaoxin date:20191129 for: 做头部菜单栏导航*/
  181. ...mapActions(["Logout"]),
  182. ...mapGetters(["nickname", "avatar","userInfo"]),
  183. getAvatar(){
  184. return getFileAccessHttpUrl(this.avatar())
  185. },
  186. handleLogout() {
  187. const that = this
  188. this.$confirm({
  189. title: '提示',
  190. content: '真的要注销登录吗 ?',
  191. onOk() {
  192. return that.Logout({}).then(() => {
  193. // update-begin author:wangshuai date:20200601 for: 退出登录跳转登录页面
  194. that.$router.push({ path: '/user/login' });
  195. window.location.reload()
  196. // update-end author:wangshuai date:20200601 for: 退出登录跳转登录页面
  197. }).catch(err => {
  198. that.$message.error({
  199. title: '错误',
  200. description: err.message
  201. })
  202. })
  203. },
  204. onCancel() {
  205. },
  206. });
  207. },
  208. updatePassword(){
  209. let username = this.userInfo().username
  210. this.$refs.userPassword.show(username)
  211. },
  212. updateCurrentDepart(){
  213. this.$refs.departSelect.show()
  214. },
  215. systemSetting(){
  216. this.$refs.settingDrawer.showDrawer()
  217. },
  218. /* update_begin author:zhaoxin date:20191129 for: 做头部菜单栏导航*/
  219. searchMenus(arr,menus){
  220. for(let i of menus){
  221. if(!i.hidden && "layouts/RouteView"!==i.component){
  222. arr.push(i)
  223. }
  224. if(i.children&& i.children.length>0){
  225. this.searchMenus(arr,i.children)
  226. }
  227. }
  228. },
  229. filterOption(input, option) {
  230. return option.componentOptions.children[0].text.toLowerCase().indexOf(input.toLowerCase()) >= 0
  231. },
  232. // update_begin author:sunjianlei date:20191230 for: 解决外部链接打开失败的问题
  233. searchMethods(value) {
  234. let route = this.searchMenuOptions.filter(item => item.id === value)[0]
  235. //update-begin-author:taoyan date:20210528 for: 【菜单问题】配置一个iframe地址的菜单,内部打开,在搜索菜单上打开却新开了一个窗口
  236. if (route.meta.internalOrExternal === true) {
  237. window.open(route.meta.url, '_blank')
  238. } else {
  239. if(route.component.includes('layouts/IframePageView')){
  240. this.$router.push(route)
  241. }else{
  242. this.$router.push({ path: route.path })
  243. }
  244. }
  245. //update-end-author:taoyan date:20210528 for: 【菜单问题】配置一个iframe地址的菜单,内部打开,在搜索菜单上打开却新开了一个窗口
  246. this.searchMenuVisible = false
  247. },
  248. // update_end author:sunjianlei date:20191230 for: 解决外部链接打开失败的问题
  249. /*update_end author:zhaoxin date:20191129 for: 做头部菜单栏导航*/
  250. /*update_begin author:liushaoqian date:20200507 for: 刷新缓存*/
  251. clearCache(){
  252. getAction("sys/dict/refleshCache").then((res) => {
  253. if (res.success) {
  254. //重新加载缓存
  255. getAction("sys/dict/queryAllDictItems").then((res) => {
  256. if (res.success) {
  257. Vue.ls.remove(UI_CACHE_DB_DICT_DATA)
  258. Vue.ls.set(UI_CACHE_DB_DICT_DATA, res.result, 7 * 24 * 60 * 60 * 1000)
  259. }
  260. })
  261. this.$message.success("刷新缓存完成!");
  262. }
  263. }).catch(e=>{
  264. this.$message.warn("刷新缓存失败!");
  265. console.log("刷新失败",e)
  266. })
  267. }
  268. /*update_end author:liushaoqian date:20200507 for: 刷新缓存*/
  269. }
  270. }
  271. </script>
  272. <style lang="less" scoped>
  273. /* update_begin author:zhaoxin date:20191129 for: 让搜索框颜色能随主题颜色变换*/
  274. /* update-begin author:sunjianlei date:20191220 for: 解决全局样式冲突问题 */
  275. .user-wrapper .search-input {
  276. width: 180px;
  277. color: inherit;
  278. /deep/ .ant-select-selection {
  279. background-color: inherit;
  280. border: 0;
  281. border-bottom: 1px solid white;
  282. &__placeholder, &__field__placeholder {
  283. color: inherit;
  284. }
  285. }
  286. }
  287. /* update-end author:sunjianlei date:20191220 for: 解决全局样式冲突问题 */
  288. /* update_end author:zhaoxin date:20191129 for: 让搜索框颜色能随主题颜色变换*/
  289. </style>
  290. <style scoped>
  291. .logout_title {
  292. color: inherit;
  293. text-decoration: none;
  294. }
  295. </style>