setings.vue 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763
  1. <template>
  2. <div class="layout-breadcrumb-seting">
  3. <el-drawer :title="$t('message.layout.configTitle')" v-model="getThemeConfig.isDrawer" direction="rtl" destroy-on-close size="260px" @close="onDrawerClose">
  4. <el-scrollbar class="layout-breadcrumb-seting-bar">
  5. <!-- 全局主题 -->
  6. <el-divider content-position="left">{{ $t('message.layout.oneTitle') }}</el-divider>
  7. <div class="layout-breadcrumb-seting-bar-flex">
  8. <div class="layout-breadcrumb-seting-bar-flex-label">primary</div>
  9. <div class="layout-breadcrumb-seting-bar-flex-value">
  10. <el-color-picker v-model="getThemeConfig.primary" @change="onColorPickerChange"> </el-color-picker>
  11. </div>
  12. </div>
  13. <div class="layout-breadcrumb-seting-bar-flex mt15">
  14. <div class="layout-breadcrumb-seting-bar-flex-label">{{ $t('message.layout.fourIsDark') }}</div>
  15. <div class="layout-breadcrumb-seting-bar-flex-value">
  16. <el-switch v-model="getThemeConfig.isIsDark" size="small" @change="onAddDarkChange"></el-switch>
  17. </div>
  18. </div>
  19. <!-- 顶栏设置 -->
  20. <el-divider content-position="left">{{ $t('message.layout.twoTopTitle') }}</el-divider>
  21. <div class="layout-breadcrumb-seting-bar-flex">
  22. <div class="layout-breadcrumb-seting-bar-flex-label">{{ $t('message.layout.twoTopBar') }}</div>
  23. <div class="layout-breadcrumb-seting-bar-flex-value">
  24. <el-color-picker v-model="getThemeConfig.topBar" @change="onBgColorPickerChange('topBar')"> </el-color-picker>
  25. </div>
  26. </div>
  27. <div class="layout-breadcrumb-seting-bar-flex">
  28. <div class="layout-breadcrumb-seting-bar-flex-label">{{ $t('message.layout.twoTopBarColor') }}</div>
  29. <div class="layout-breadcrumb-seting-bar-flex-value">
  30. <el-color-picker v-model="getThemeConfig.topBarColor" @change="onBgColorPickerChange('topBarColor')"> </el-color-picker>
  31. </div>
  32. </div>
  33. <div class="layout-breadcrumb-seting-bar-flex mt10">
  34. <div class="layout-breadcrumb-seting-bar-flex-label">{{ $t('message.layout.twoIsTopBarColorGradual') }}</div>
  35. <div class="layout-breadcrumb-seting-bar-flex-value">
  36. <el-switch v-model="getThemeConfig.isTopBarColorGradual" size="small" @change="onTopBarGradualChange"></el-switch>
  37. </div>
  38. </div>
  39. <!-- 菜单设置 -->
  40. <el-divider content-position="left">{{ $t('message.layout.twoMenuTitle') }}</el-divider>
  41. <div class="layout-breadcrumb-seting-bar-flex">
  42. <div class="layout-breadcrumb-seting-bar-flex-label">{{ $t('message.layout.twoMenuBar') }}</div>
  43. <div class="layout-breadcrumb-seting-bar-flex-value">
  44. <el-color-picker v-model="getThemeConfig.menuBar" @change="onBgColorPickerChange('menuBar')"> </el-color-picker>
  45. </div>
  46. </div>
  47. <div class="layout-breadcrumb-seting-bar-flex">
  48. <div class="layout-breadcrumb-seting-bar-flex-label">{{ $t('message.layout.twoMenuBarColor') }}</div>
  49. <div class="layout-breadcrumb-seting-bar-flex-value">
  50. <el-color-picker v-model="getThemeConfig.menuBarColor" @change="onBgColorPickerChange('menuBarColor')"> </el-color-picker>
  51. </div>
  52. </div>
  53. <div class="layout-breadcrumb-seting-bar-flex mt14">
  54. <div class="layout-breadcrumb-seting-bar-flex-label">{{ $t('message.layout.twoIsMenuBarColorGradual') }}</div>
  55. <div class="layout-breadcrumb-seting-bar-flex-value">
  56. <el-switch v-model="getThemeConfig.isMenuBarColorGradual" size="small" @change="onMenuBarGradualChange"></el-switch>
  57. </div>
  58. </div>
  59. <!-- 分栏设置 -->
  60. <el-divider content-position="left" :style="{ opacity: getThemeConfig.layout !== 'columns' ? 0.5 : 1 }">{{
  61. $t('message.layout.twoColumnsTitle')
  62. }}</el-divider>
  63. <div class="layout-breadcrumb-seting-bar-flex" :style="{ opacity: getThemeConfig.layout !== 'columns' ? 0.5 : 1 }">
  64. <div class="layout-breadcrumb-seting-bar-flex-label">{{ $t('message.layout.twoColumnsMenuBar') }}</div>
  65. <div class="layout-breadcrumb-seting-bar-flex-value">
  66. <el-color-picker v-model="getThemeConfig.columnsMenuBar" @change="onBgColorPickerChange('columnsMenuBar')" :disabled="getThemeConfig.layout !== 'columns'">
  67. </el-color-picker>
  68. </div>
  69. </div>
  70. <div class="layout-breadcrumb-seting-bar-flex" :style="{ opacity: getThemeConfig.layout !== 'columns' ? 0.5 : 1 }">
  71. <div class="layout-breadcrumb-seting-bar-flex-label">{{ $t('message.layout.twoColumnsMenuBarColor') }}</div>
  72. <div class="layout-breadcrumb-seting-bar-flex-value">
  73. <el-color-picker v-model="getThemeConfig.columnsMenuBarColor" @change="onBgColorPickerChange('columnsMenuBarColor')" :disabled="getThemeConfig.layout !== 'columns'">
  74. </el-color-picker>
  75. </div>
  76. </div>
  77. <div class="layout-breadcrumb-seting-bar-flex mt14" :style="{ opacity: getThemeConfig.layout !== 'columns' ? 0.5 : 1 }">
  78. <div class="layout-breadcrumb-seting-bar-flex-label">{{ $t('message.layout.twoIsColumnsMenuBarColorGradual') }}</div>
  79. <div class="layout-breadcrumb-seting-bar-flex-value">
  80. <el-switch v-model="getThemeConfig.isColumnsMenuBarColorGradual" size="small" @change="onColumnsMenuBarGradualChange" :disabled="getThemeConfig.layout !== 'columns'"></el-switch>
  81. </div>
  82. </div>
  83. <!-- 界面设置 -->
  84. <el-divider content-position="left">{{ $t('message.layout.threeTitle') }}</el-divider>
  85. <div class="layout-breadcrumb-seting-bar-flex">
  86. <div class="layout-breadcrumb-seting-bar-flex-label">{{ $t('message.layout.threeIsCollapse') }}</div>
  87. <div class="layout-breadcrumb-seting-bar-flex-value">
  88. <el-switch v-model="getThemeConfig.isCollapse" size="small" @change="onThemeConfigChange"></el-switch>
  89. </div>
  90. </div>
  91. <div class="layout-breadcrumb-seting-bar-flex mt15">
  92. <div class="layout-breadcrumb-seting-bar-flex-label">{{ $t('message.layout.threeIsUniqueOpened') }}</div>
  93. <div class="layout-breadcrumb-seting-bar-flex-value">
  94. <el-switch v-model="getThemeConfig.isUniqueOpened" size="small" @change="setLocalThemeConfig"></el-switch>
  95. </div>
  96. </div>
  97. <div class="layout-breadcrumb-seting-bar-flex mt15">
  98. <div class="layout-breadcrumb-seting-bar-flex-label">{{ $t('message.layout.threeIsFixedHeader') }}</div>
  99. <div class="layout-breadcrumb-seting-bar-flex-value">
  100. <el-switch v-model="getThemeConfig.isFixedHeader" size="small" @change="onIsFixedHeaderChange"></el-switch>
  101. </div>
  102. </div>
  103. <div class="layout-breadcrumb-seting-bar-flex mt15" :style="{ opacity: getThemeConfig.layout !== 'classic' ? 0.5 : 1 }">
  104. <div class="layout-breadcrumb-seting-bar-flex-label">{{ $t('message.layout.threeIsClassicSplitMenu') }}</div>
  105. <div class="layout-breadcrumb-seting-bar-flex-value">
  106. <el-switch v-model="getThemeConfig.isClassicSplitMenu" :disabled="getThemeConfig.layout !== 'classic'" size="small" @change="onClassicSplitMenuChange">
  107. </el-switch>
  108. </div>
  109. </div>
  110. <div class="layout-breadcrumb-seting-bar-flex mt15">
  111. <div class="layout-breadcrumb-seting-bar-flex-label">{{ $t('message.layout.threeIsLockScreen') }}</div>
  112. <div class="layout-breadcrumb-seting-bar-flex-value">
  113. <el-switch v-model="getThemeConfig.isLockScreen" size="small" @change="setLocalThemeConfig"></el-switch>
  114. </div>
  115. </div>
  116. <div class="layout-breadcrumb-seting-bar-flex mt11">
  117. <div class="layout-breadcrumb-seting-bar-flex-label">{{ $t('message.layout.threeLockScreenTime') }}</div>
  118. <div class="layout-breadcrumb-seting-bar-flex-value">
  119. <el-input-number v-model="getThemeConfig.lockScreenTime" controls-position="right" :min="1" :max="9999" @change="setLocalThemeConfig" style="width: 90px">
  120. </el-input-number>
  121. </div>
  122. </div>
  123. <!-- 界面显示 -->
  124. <el-divider content-position="left">{{ $t('message.layout.fourTitle') }}</el-divider>
  125. <div class="layout-breadcrumb-seting-bar-flex mt15">
  126. <div class="layout-breadcrumb-seting-bar-flex-label">{{ $t('message.layout.fourIsShowLogo') }}</div>
  127. <div class="layout-breadcrumb-seting-bar-flex-value">
  128. <el-switch v-model="getThemeConfig.isShowLogo" size="small" @change="onIsShowLogoChange"></el-switch>
  129. </div>
  130. </div>
  131. <div class="layout-breadcrumb-seting-bar-flex mt15" :style="{ opacity: getThemeConfig.layout === 'classic' || getThemeConfig.layout === 'transverse' ? 0.5 : 1 }">
  132. <div class="layout-breadcrumb-seting-bar-flex-label">{{ $t('message.layout.fourIsBreadcrumb') }}</div>
  133. <div class="layout-breadcrumb-seting-bar-flex-value">
  134. <el-switch v-model="getThemeConfig.isBreadcrumb" :disabled="getThemeConfig.layout === 'classic' || getThemeConfig.layout === 'transverse'" size="small" @change="onIsBreadcrumbChange"></el-switch>
  135. </div>
  136. </div>
  137. <div class="layout-breadcrumb-seting-bar-flex mt15">
  138. <div class="layout-breadcrumb-seting-bar-flex-label">{{ $t('message.layout.fourIsBreadcrumbIcon') }}</div>
  139. <div class="layout-breadcrumb-seting-bar-flex-value">
  140. <el-switch v-model="getThemeConfig.isBreadcrumbIcon" size="small" @change="setLocalThemeConfig"></el-switch>
  141. </div>
  142. </div>
  143. <div class="layout-breadcrumb-seting-bar-flex mt15">
  144. <div class="layout-breadcrumb-seting-bar-flex-label">{{ $t('message.layout.fourIsTagsview') }}</div>
  145. <div class="layout-breadcrumb-seting-bar-flex-value">
  146. <el-switch v-model="getThemeConfig.isTagsview" size="small" @change="setLocalThemeConfig"></el-switch>
  147. </div>
  148. </div>
  149. <div class="layout-breadcrumb-seting-bar-flex mt15">
  150. <div class="layout-breadcrumb-seting-bar-flex-label">{{ $t('message.layout.fourIsTagsviewIcon') }}</div>
  151. <div class="layout-breadcrumb-seting-bar-flex-value">
  152. <el-switch v-model="getThemeConfig.isTagsviewIcon" size="small" @change="setLocalThemeConfig"></el-switch>
  153. </div>
  154. </div>
  155. <div class="layout-breadcrumb-seting-bar-flex mt15">
  156. <div class="layout-breadcrumb-seting-bar-flex-label">{{ $t('message.layout.fourIsCacheTagsView') }}</div>
  157. <div class="layout-breadcrumb-seting-bar-flex-value">
  158. <el-switch v-model="getThemeConfig.isCacheTagsView" size="small" @change="setLocalThemeConfig"></el-switch>
  159. </div>
  160. </div>
  161. <div class="layout-breadcrumb-seting-bar-flex mt15" :style="{ opacity: isMobile ? 0.5 : 1 }">
  162. <div class="layout-breadcrumb-seting-bar-flex-label">{{ $t('message.layout.fourIsSortableTagsView') }}</div>
  163. <div class="layout-breadcrumb-seting-bar-flex-value">
  164. <el-switch v-model="getThemeConfig.isSortableTagsView" :disabled="isMobile ? true : false" size="small" @change="onSortableTagsViewChange"></el-switch>
  165. </div>
  166. </div>
  167. <div class="layout-breadcrumb-seting-bar-flex mt15">
  168. <div class="layout-breadcrumb-seting-bar-flex-label">{{ $t('message.layout.fourIsShareTagsView') }}</div>
  169. <div class="layout-breadcrumb-seting-bar-flex-value">
  170. <el-switch v-model="getThemeConfig.isShareTagsView" size="small" @change="onShareTagsViewChange"></el-switch>
  171. </div>
  172. </div>
  173. <div class="layout-breadcrumb-seting-bar-flex mt15">
  174. <div class="layout-breadcrumb-seting-bar-flex-label">{{ $t('message.layout.fourIsFooter') }}</div>
  175. <div class="layout-breadcrumb-seting-bar-flex-value">
  176. <el-switch v-model="getThemeConfig.isFooter" size="small" @change="setLocalThemeConfig"></el-switch>
  177. </div>
  178. </div>
  179. <div class="layout-breadcrumb-seting-bar-flex mt15">
  180. <div class="layout-breadcrumb-seting-bar-flex-label">{{ $t('message.layout.fourIsGrayscale') }}</div>
  181. <div class="layout-breadcrumb-seting-bar-flex-value">
  182. <el-switch v-model="getThemeConfig.isGrayscale" size="small" @change="onAddFilterChange('grayscale')"></el-switch>
  183. </div>
  184. </div>
  185. <div class="layout-breadcrumb-seting-bar-flex mt15">
  186. <div class="layout-breadcrumb-seting-bar-flex-label">{{ $t('message.layout.fourIsInvert') }}</div>
  187. <div class="layout-breadcrumb-seting-bar-flex-value">
  188. <el-switch v-model="getThemeConfig.isInvert" size="small" @change="onAddFilterChange('invert')"></el-switch>
  189. </div>
  190. </div>
  191. <div class="layout-breadcrumb-seting-bar-flex mt15">
  192. <div class="layout-breadcrumb-seting-bar-flex-label">{{ $t('message.layout.fourIsWartermark') }}</div>
  193. <div class="layout-breadcrumb-seting-bar-flex-value">
  194. <el-switch v-model="getThemeConfig.isWartermark" size="small" @change="onWartermarkChange"></el-switch>
  195. </div>
  196. </div>
  197. <div class="layout-breadcrumb-seting-bar-flex mt14">
  198. <div class="layout-breadcrumb-seting-bar-flex-label">{{ $t('message.layout.fourWartermarkText') }}</div>
  199. <div class="layout-breadcrumb-seting-bar-flex-value">
  200. <el-input v-model="getThemeConfig.wartermarkText" style="width: 90px" @input="onWartermarkTextInput($event)"></el-input>
  201. </div>
  202. </div>
  203. <!-- 其它设置 -->
  204. <el-divider content-position="left">{{ $t('message.layout.fiveTitle') }}</el-divider>
  205. <div class="layout-breadcrumb-seting-bar-flex mt15">
  206. <div class="layout-breadcrumb-seting-bar-flex-label">{{ $t('message.layout.fiveTagsStyle') }}</div>
  207. <div class="layout-breadcrumb-seting-bar-flex-value">
  208. <el-select v-model="getThemeConfig.tagsStyle" placeholder="请选择" style="width: 90px" @change="setLocalThemeConfig">
  209. <el-option label="风格1" value="tags-style-one"></el-option>
  210. <el-option label="风格4" value="tags-style-four"></el-option>
  211. <el-option label="风格5" value="tags-style-five"></el-option>
  212. </el-select>
  213. </div>
  214. </div>
  215. <div class="layout-breadcrumb-seting-bar-flex mt15">
  216. <div class="layout-breadcrumb-seting-bar-flex-label">{{ $t('message.layout.fiveAnimation') }}</div>
  217. <div class="layout-breadcrumb-seting-bar-flex-value">
  218. <el-select v-model="getThemeConfig.animation" placeholder="请选择" style="width: 90px" @change="setLocalThemeConfig">
  219. <el-option label="slide-right" value="slide-right"></el-option>
  220. <el-option label="slide-left" value="slide-left"></el-option>
  221. <el-option label="opacitys" value="opacitys"></el-option>
  222. </el-select>
  223. </div>
  224. </div>
  225. <div class="layout-breadcrumb-seting-bar-flex mt15" :style="{ opacity: getThemeConfig.layout !== 'columns' ? 0.5 : 1 }">
  226. <div class="layout-breadcrumb-seting-bar-flex-label">{{ $t('message.layout.fiveColumnsAsideStyle') }}</div>
  227. <div class="layout-breadcrumb-seting-bar-flex-value">
  228. <el-select v-model="getThemeConfig.columnsAsideStyle" placeholder="请选择" style="width: 90px" :disabled="getThemeConfig.layout !== 'columns' ? true : false" @change="setLocalThemeConfig">
  229. <el-option label="圆角" value="columns-round"></el-option>
  230. <el-option label="卡片" value="columns-card"></el-option>
  231. </el-select>
  232. </div>
  233. </div>
  234. <div class="layout-breadcrumb-seting-bar-flex mt15 mb27" :style="{ opacity: getThemeConfig.layout !== 'columns' ? 0.5 : 1 }">
  235. <div class="layout-breadcrumb-seting-bar-flex-label">{{ $t('message.layout.fiveColumnsAsideLayout') }}</div>
  236. <div class="layout-breadcrumb-seting-bar-flex-value">
  237. <el-select v-model="getThemeConfig.columnsAsideLayout" placeholder="请选择" style="width: 90px" :disabled="getThemeConfig.layout !== 'columns' ? true : false" @change="setLocalThemeConfig">
  238. <el-option label="水平" value="columns-horizontal"></el-option>
  239. <el-option label="垂直" value="columns-vertical"></el-option>
  240. </el-select>
  241. </div>
  242. </div>
  243. <!-- 布局切换 -->
  244. <el-divider content-position="left">{{ $t('message.layout.sixTitle') }}</el-divider>
  245. <div class="layout-drawer-content-flex">
  246. <!-- defaults 布局 -->
  247. <div class="layout-drawer-content-item" @click="onSetLayout('defaults')">
  248. <section class="el-container el-circular" :class="{ 'drawer-layout-active': getThemeConfig.layout === 'defaults' }">
  249. <aside class="el-aside" style="width: 20px"></aside>
  250. <section class="el-container is-vertical">
  251. <header class="el-header" style="height: 10px"></header>
  252. <main class="el-main"></main>
  253. </section>
  254. </section>
  255. <div class="layout-tips-warp" :class="{ 'layout-tips-warp-active': getThemeConfig.layout === 'defaults' }">
  256. <div class="layout-tips-box">
  257. <p class="layout-tips-txt">{{ $t('message.layout.sixDefaults') }}</p>
  258. </div>
  259. </div>
  260. </div>
  261. <!-- classic 布局 -->
  262. <div class="layout-drawer-content-item" @click="onSetLayout('classic')">
  263. <section class="el-container is-vertical el-circular" :class="{ 'drawer-layout-active': getThemeConfig.layout === 'classic' }">
  264. <header class="el-header" style="height: 10px"></header>
  265. <section class="el-container">
  266. <aside class="el-aside" style="width: 20px"></aside>
  267. <section class="el-container is-vertical">
  268. <main class="el-main"></main>
  269. </section>
  270. </section>
  271. </section>
  272. <div class="layout-tips-warp" :class="{ 'layout-tips-warp-active': getThemeConfig.layout === 'classic' }">
  273. <div class="layout-tips-box">
  274. <p class="layout-tips-txt">{{ $t('message.layout.sixClassic') }}</p>
  275. </div>
  276. </div>
  277. </div>
  278. <!-- transverse 布局 -->
  279. <div class="layout-drawer-content-item" @click="onSetLayout('transverse')">
  280. <section class="el-container is-vertical el-circular" :class="{ 'drawer-layout-active': getThemeConfig.layout === 'transverse' }">
  281. <header class="el-header" style="height: 10px"></header>
  282. <section class="el-container">
  283. <section class="el-container is-vertical">
  284. <main class="el-main"></main>
  285. </section>
  286. </section>
  287. </section>
  288. <div class="layout-tips-warp" :class="{ 'layout-tips-warp-active': getThemeConfig.layout === 'transverse' }">
  289. <div class="layout-tips-box">
  290. <p class="layout-tips-txt">{{ $t('message.layout.sixTransverse') }}</p>
  291. </div>
  292. </div>
  293. </div>
  294. <!-- columns 布局 -->
  295. <div class="layout-drawer-content-item" @click="onSetLayout('columns')">
  296. <section class="el-container el-circular" :class="{ 'drawer-layout-active': getThemeConfig.layout === 'columns' }">
  297. <aside class="el-aside-dark" style="width: 10px"></aside>
  298. <aside class="el-aside" style="width: 20px"></aside>
  299. <section class="el-container is-vertical">
  300. <header class="el-header" style="height: 10px"></header>
  301. <main class="el-main"></main>
  302. </section>
  303. </section>
  304. <div class="layout-tips-warp" :class="{ 'layout-tips-warp-active': getThemeConfig.layout === 'columns' }">
  305. <div class="layout-tips-box">
  306. <p class="layout-tips-txt">{{ $t('message.layout.sixColumns') }}</p>
  307. </div>
  308. </div>
  309. </div>
  310. </div>
  311. <div class="copy-config">
  312. <el-alert :title="$t('message.layout.tipText')" type="warning" :closable="false"> </el-alert>
  313. <el-button class="copy-config-btn" type="primary" ref="copyConfigBtnRef" @click="onCopyConfigClick">
  314. <el-icon class="mr5">
  315. <ele-CopyDocument />
  316. </el-icon>
  317. {{ $t('message.layout.copyText') }}
  318. </el-button>
  319. <el-button class="copy-config-btn-reset" type="info" @click="onResetConfigClick">
  320. <el-icon class="mr5">
  321. <ele-RefreshRight />
  322. </el-icon>
  323. {{ $t('message.layout.resetText') }}
  324. </el-button>
  325. </div>
  326. </el-scrollbar>
  327. </el-drawer>
  328. </div>
  329. </template>
  330. <script lang="ts">
  331. import { nextTick, onUnmounted, onMounted, getCurrentInstance, defineComponent, computed, reactive, toRefs } from 'vue';
  332. import { useStore } from '/@/store/index';
  333. import { getLightColor, getDarkColor } from '/@/utils/theme';
  334. import { verifyAndSpace } from '/@/utils/toolsValidate';
  335. import { Local } from '/@/utils/storage';
  336. import Watermark from '/@/utils/wartermark';
  337. import commonFunction from '/@/utils/commonFunction';
  338. import other from '/@/utils/other';
  339. export default defineComponent({
  340. name: 'layoutBreadcrumbSeting',
  341. setup() {
  342. const { proxy } = <any>getCurrentInstance();
  343. const store = useStore();
  344. const { copyText } = commonFunction();
  345. const state = reactive({
  346. isMobile: false,
  347. });
  348. // 获取布局配置信息
  349. const getThemeConfig = computed(() => {
  350. return store.state.themeConfig.themeConfig;
  351. });
  352. // 1、全局主题
  353. const onColorPickerChange = () => {
  354. // 颜色加深
  355. document.documentElement.style.setProperty('--el-color-primary-dark-2', `${getDarkColor(getThemeConfig.value.primary, 0.1)}`);
  356. document.documentElement.style.setProperty('--el-color-primary', getThemeConfig.value.primary);
  357. // 颜色变浅
  358. for (let i = 1; i <= 9; i++) {
  359. document.documentElement.style.setProperty(`--el-color-primary-light-${i}`, `${getLightColor(getThemeConfig.value.primary, i / 10)}`);
  360. }
  361. setDispatchThemeConfig();
  362. };
  363. // 2、菜单 / 顶栏
  364. const onBgColorPickerChange = (bg: string) => {
  365. document.documentElement.style.setProperty(`--next-bg-${bg}`, (<any>getThemeConfig.value)[bg]);
  366. onTopBarGradualChange();
  367. onMenuBarGradualChange();
  368. onColumnsMenuBarGradualChange();
  369. setDispatchThemeConfig();
  370. };
  371. // 2、菜单 / 顶栏 --> 顶栏背景渐变
  372. const onTopBarGradualChange = () => {
  373. setGraduaFun('.layout-navbars-breadcrumb-index', getThemeConfig.value.isTopBarColorGradual, getThemeConfig.value.topBar);
  374. };
  375. // 2、菜单 / 顶栏 --> 菜单背景渐变
  376. const onMenuBarGradualChange = () => {
  377. setGraduaFun('.layout-container .el-aside', getThemeConfig.value.isMenuBarColorGradual, getThemeConfig.value.menuBar);
  378. };
  379. // 2、菜单 / 顶栏 --> 分栏菜单背景渐变
  380. const onColumnsMenuBarGradualChange = () => {
  381. setGraduaFun('.layout-container .layout-columns-aside', getThemeConfig.value.isColumnsMenuBarColorGradual, getThemeConfig.value.columnsMenuBar);
  382. };
  383. // 2、菜单 / 顶栏 --> 背景渐变函数
  384. const setGraduaFun = (el: string, bool: boolean, color: string) => {
  385. setTimeout(() => {
  386. let els = document.querySelector(el);
  387. if (!els) return false;
  388. document.documentElement.style.setProperty('--el-menu-bg-color', document.documentElement.style.getPropertyValue('--next-bg-menuBar'));
  389. if (bool) els.setAttribute('style', `background:linear-gradient(to bottom left , ${color}, ${getLightColor(color, 0.6)}) !important;`);
  390. else els.setAttribute('style', ``);
  391. setLocalThemeConfig();
  392. }, 200);
  393. };
  394. // 3、界面设置 --> 菜单水平折叠
  395. const onThemeConfigChange = () => {
  396. setDispatchThemeConfig();
  397. };
  398. // 3、界面设置 --> 固定 Header
  399. const onIsFixedHeaderChange = () => {
  400. getThemeConfig.value.isFixedHeaderChange = getThemeConfig.value.isFixedHeader ? false : true;
  401. setLocalThemeConfig();
  402. };
  403. // 3、界面设置 --> 经典布局分割菜单
  404. const onClassicSplitMenuChange = () => {
  405. getThemeConfig.value.isBreadcrumb = false;
  406. setLocalThemeConfig();
  407. proxy.mittBus.emit('getBreadcrumbIndexSetFilterRoutes');
  408. };
  409. // 4、界面显示 --> 侧边栏 Logo
  410. const onIsShowLogoChange = () => {
  411. getThemeConfig.value.isShowLogoChange = getThemeConfig.value.isShowLogo ? false : true;
  412. setLocalThemeConfig();
  413. };
  414. // 4、界面显示 --> 面包屑 Breadcrumb
  415. const onIsBreadcrumbChange = () => {
  416. if (getThemeConfig.value.layout === 'classic') {
  417. getThemeConfig.value.isClassicSplitMenu = false;
  418. }
  419. setLocalThemeConfig();
  420. };
  421. // 4、界面显示 --> 开启 TagsView 拖拽
  422. const onSortableTagsViewChange = () => {
  423. proxy.mittBus.emit('openOrCloseSortable');
  424. setLocalThemeConfig();
  425. };
  426. // 4、界面显示 --> 开启 TagsView 共用
  427. const onShareTagsViewChange = () => {
  428. proxy.mittBus.emit('openShareTagsView');
  429. setLocalThemeConfig();
  430. };
  431. // 4、界面显示 --> 灰色模式/色弱模式
  432. const onAddFilterChange = (attr: string) => {
  433. if (attr === 'grayscale') {
  434. if (getThemeConfig.value.isGrayscale) getThemeConfig.value.isInvert = false;
  435. } else {
  436. if (getThemeConfig.value.isInvert) getThemeConfig.value.isGrayscale = false;
  437. }
  438. const cssAttr =
  439. attr === 'grayscale' ? `grayscale(${getThemeConfig.value.isGrayscale ? 1 : 0})` : `invert(${getThemeConfig.value.isInvert ? '80%' : '0%'})`;
  440. const appEle: any = document.body;
  441. appEle.setAttribute('style', `filter: ${cssAttr}`);
  442. setLocalThemeConfig();
  443. };
  444. // 4、界面显示 --> 深色模式
  445. const onAddDarkChange = () => {
  446. const body = document.documentElement as HTMLElement;
  447. if (getThemeConfig.value.isIsDark) {
  448. body.setAttribute('data-theme', 'dark');
  449. document.querySelector('html')!.className = 'dark'
  450. } else {
  451. body.setAttribute('data-theme', '');
  452. document.querySelector('html')!.className = ''
  453. }
  454. };
  455. // 4、界面显示 --> 开启水印
  456. const onWartermarkChange = () => {
  457. getThemeConfig.value.isWartermark ? Watermark.set(getThemeConfig.value.wartermarkText) : Watermark.del();
  458. setLocalThemeConfig();
  459. };
  460. // 4、界面显示 --> 水印文案
  461. const onWartermarkTextInput = (val: any) => {
  462. getThemeConfig.value.wartermarkText = verifyAndSpace(val);
  463. if (getThemeConfig.value.wartermarkText === '') return false;
  464. if (getThemeConfig.value.isWartermark) Watermark.set(getThemeConfig.value.wartermarkText);
  465. setLocalThemeConfig();
  466. };
  467. // 5、布局切换
  468. const onSetLayout = (layout: string) => {
  469. Local.set('oldLayout', layout);
  470. if (getThemeConfig.value.layout === layout) return false;
  471. getThemeConfig.value.layout = layout;
  472. getThemeConfig.value.isDrawer = false;
  473. initLayoutChangeFun();
  474. };
  475. // 设置布局切换函数
  476. const initLayoutChangeFun = () => {
  477. onBgColorPickerChange('menuBar');
  478. onBgColorPickerChange('menuBarColor');
  479. onBgColorPickerChange('topBar');
  480. onBgColorPickerChange('topBarColor');
  481. onBgColorPickerChange('columnsMenuBar');
  482. onBgColorPickerChange('columnsMenuBarColor');
  483. };
  484. // 关闭弹窗时,初始化变量。变量用于处理 proxy.$refs.layoutScrollbarRef.update()
  485. const onDrawerClose = () => {
  486. getThemeConfig.value.isFixedHeaderChange = false;
  487. getThemeConfig.value.isShowLogoChange = false;
  488. getThemeConfig.value.isDrawer = false;
  489. setLocalThemeConfig();
  490. };
  491. // 布局配置弹窗打开
  492. const openDrawer = () => {
  493. getThemeConfig.value.isDrawer = true;
  494. };
  495. // 触发 store 布局配置更新
  496. const setDispatchThemeConfig = () => {
  497. setLocalThemeConfig();
  498. setLocalThemeConfigStyle();
  499. };
  500. // 存储布局配置
  501. const setLocalThemeConfig = () => {
  502. Local.remove('themeConfig');
  503. Local.set('themeConfig', getThemeConfig.value);
  504. };
  505. // 存储布局配置全局主题样式(html根标签)
  506. const setLocalThemeConfigStyle = () => {
  507. Local.set('themeConfigStyle', document.documentElement.style.cssText);
  508. };
  509. // 一键复制配置
  510. const onCopyConfigClick = () => {
  511. let copyThemeConfig = Local.get('themeConfig');
  512. copyThemeConfig.isDrawer = false;
  513. copyText(JSON.stringify(copyThemeConfig)).then(() => {
  514. getThemeConfig.value.isDrawer = false;
  515. });
  516. };
  517. // 一键恢复默认
  518. const onResetConfigClick = () => {
  519. Local.clear();
  520. window.location.reload();
  521. };
  522. // 初始化菜单样式等
  523. const initSetStyle = () => {
  524. // 2、菜单 / 顶栏 --> 顶栏背景渐变
  525. onTopBarGradualChange();
  526. // 2、菜单 / 顶栏 --> 菜单背景渐变
  527. onMenuBarGradualChange();
  528. // 2、菜单 / 顶栏 --> 分栏菜单背景渐变
  529. onColumnsMenuBarGradualChange();
  530. };
  531. onMounted(() => {
  532. nextTick(() => {
  533. // 判断当前布局是否不相同,不相同则初始化当前布局的样式,防止监听窗口大小改变时,布局配置logo、菜单背景等部分布局失效问题
  534. if (!Local.get('frequency')) initLayoutChangeFun();
  535. Local.set('frequency', 1);
  536. // 监听窗口大小改变,非默认布局,设置成默认布局(适配移动端)
  537. proxy.mittBus.on('layoutMobileResize', (res: any) => {
  538. getThemeConfig.value.layout = res.layout;
  539. getThemeConfig.value.isDrawer = false;
  540. initLayoutChangeFun();
  541. state.isMobile = other.isMobile();
  542. });
  543. setTimeout(() => {
  544. // 灰色模式
  545. if (getThemeConfig.value.isGrayscale) onAddFilterChange('grayscale');
  546. // 色弱模式
  547. if (getThemeConfig.value.isInvert) onAddFilterChange('invert');
  548. // 深色模式
  549. if (getThemeConfig.value.isIsDark) onAddDarkChange();
  550. // 开启水印
  551. onWartermarkChange();
  552. // 语言国际化
  553. if (Local.get('themeConfig')) proxy.$i18n.locale = Local.get('themeConfig').globalI18n;
  554. // 初始化菜单样式等
  555. initSetStyle();
  556. }, 100);
  557. });
  558. });
  559. onUnmounted(() => {
  560. proxy.mittBus.off('layoutMobileResize');
  561. });
  562. return {
  563. openDrawer,
  564. onColorPickerChange,
  565. onBgColorPickerChange,
  566. onTopBarGradualChange,
  567. onMenuBarGradualChange,
  568. onColumnsMenuBarGradualChange,
  569. onThemeConfigChange,
  570. onIsFixedHeaderChange,
  571. onIsShowLogoChange,
  572. getThemeConfig,
  573. onDrawerClose,
  574. onAddFilterChange,
  575. onAddDarkChange,
  576. onWartermarkChange,
  577. onWartermarkTextInput,
  578. onSetLayout,
  579. setLocalThemeConfig,
  580. onClassicSplitMenuChange,
  581. onIsBreadcrumbChange,
  582. onSortableTagsViewChange,
  583. onShareTagsViewChange,
  584. onCopyConfigClick,
  585. onResetConfigClick,
  586. ...toRefs(state),
  587. };
  588. },
  589. });
  590. </script>
  591. <style scoped lang="scss">
  592. .layout-breadcrumb-seting-bar {
  593. height: calc(100vh - 50px);
  594. padding: 0 15px;
  595. ::v-deep(.el-scrollbar__view) {
  596. overflow-x: hidden !important;
  597. }
  598. .layout-breadcrumb-seting-bar-flex {
  599. display: flex;
  600. align-items: center;
  601. margin-bottom: 5px;
  602. &-label {
  603. flex: 1;
  604. color: var(--el-text-color-primary);
  605. }
  606. }
  607. .layout-drawer-content-flex {
  608. overflow: hidden;
  609. display: flex;
  610. flex-wrap: wrap;
  611. align-content: flex-start;
  612. margin: 0 -5px;
  613. .layout-drawer-content-item {
  614. width: 50%;
  615. height: 70px;
  616. cursor: pointer;
  617. border: 1px solid transparent;
  618. position: relative;
  619. padding: 5px;
  620. .el-container {
  621. height: 100%;
  622. .el-aside-dark {
  623. background-color: var(--next-color-seting-header);
  624. }
  625. .el-aside {
  626. background-color: var(--next-color-seting-aside);
  627. }
  628. .el-header {
  629. background-color: var(--next-color-seting-header);
  630. }
  631. .el-main {
  632. background-color: var(--next-color-seting-main);
  633. }
  634. }
  635. .el-circular {
  636. border-radius: 2px;
  637. overflow: hidden;
  638. border: 1px solid transparent;
  639. transition: all 0.3s ease-in-out;
  640. }
  641. .drawer-layout-active {
  642. border: 1px solid;
  643. border-color: var(--el-color-primary);
  644. }
  645. .layout-tips-warp,
  646. .layout-tips-warp-active {
  647. transition: all 0.3s ease-in-out;
  648. position: absolute;
  649. left: 50%;
  650. top: 50%;
  651. transform: translate(-50%, -50%);
  652. border: 1px solid;
  653. border-color: var(--el-color-primary-light-4);
  654. border-radius: 100%;
  655. padding: 4px;
  656. .layout-tips-box {
  657. transition: inherit;
  658. width: 30px;
  659. height: 30px;
  660. z-index: 9;
  661. border: 1px solid;
  662. border-color: var(--el-color-primary-light-4);
  663. border-radius: 100%;
  664. .layout-tips-txt {
  665. transition: inherit;
  666. position: relative;
  667. top: 5px;
  668. font-size: 12px;
  669. line-height: 1;
  670. letter-spacing: 2px;
  671. white-space: nowrap;
  672. color: var(--el-color-primary-light-4);
  673. text-align: center;
  674. transform: rotate(30deg);
  675. left: -1px;
  676. background-color: var(--next-color-seting-main);
  677. width: 32px;
  678. height: 17px;
  679. line-height: 17px;
  680. }
  681. }
  682. }
  683. .layout-tips-warp-active {
  684. border: 1px solid;
  685. border-color: var(--el-color-primary);
  686. .layout-tips-box {
  687. border: 1px solid;
  688. border-color: var(--el-color-primary);
  689. .layout-tips-txt {
  690. color: var(--el-color-primary) !important;
  691. background-color: var(--next-color-seting-main) !important;
  692. }
  693. }
  694. }
  695. &:hover {
  696. .el-circular {
  697. transition: all 0.3s ease-in-out;
  698. border: 1px solid;
  699. border-color: var(--el-color-primary);
  700. }
  701. .layout-tips-warp {
  702. transition: all 0.3s ease-in-out;
  703. border-color: var(--el-color-primary);
  704. .layout-tips-box {
  705. transition: inherit;
  706. border-color: var(--el-color-primary);
  707. .layout-tips-txt {
  708. transition: inherit;
  709. color: var(--el-color-primary) !important;
  710. background-color: var(--next-color-seting-main) !important;
  711. }
  712. }
  713. }
  714. }
  715. }
  716. }
  717. .copy-config {
  718. margin: 10px 0;
  719. .copy-config-btn {
  720. width: 100%;
  721. margin-top: 15px;
  722. }
  723. .copy-config-btn-reset {
  724. width: 100%;
  725. margin: 10px 0 0;
  726. }
  727. }
  728. }
  729. </style>