setings.vue 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765
  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. store.dispatch('themeConfig/setThemeConfig', getThemeConfig.value);
  455. };
  456. // 4、界面显示 --> 开启水印
  457. const onWartermarkChange = () => {
  458. getThemeConfig.value.isWartermark ? Watermark.set(getThemeConfig.value.wartermarkText) : Watermark.del();
  459. setLocalThemeConfig();
  460. };
  461. // 4、界面显示 --> 水印文案
  462. const onWartermarkTextInput = (val: any) => {
  463. getThemeConfig.value.wartermarkText = verifyAndSpace(val);
  464. if (getThemeConfig.value.wartermarkText === '') return false;
  465. if (getThemeConfig.value.isWartermark) Watermark.set(getThemeConfig.value.wartermarkText);
  466. setLocalThemeConfig();
  467. };
  468. // 5、布局切换
  469. const onSetLayout = (layout: string) => {
  470. Local.set('oldLayout', layout);
  471. if (getThemeConfig.value.layout === layout) return false;
  472. getThemeConfig.value.layout = layout;
  473. getThemeConfig.value.isDrawer = false;
  474. initLayoutChangeFun();
  475. };
  476. // 设置布局切换函数
  477. const initLayoutChangeFun = () => {
  478. onBgColorPickerChange('menuBar');
  479. onBgColorPickerChange('menuBarColor');
  480. onBgColorPickerChange('topBar');
  481. onBgColorPickerChange('topBarColor');
  482. onBgColorPickerChange('columnsMenuBar');
  483. onBgColorPickerChange('columnsMenuBarColor');
  484. };
  485. // 关闭弹窗时,初始化变量。变量用于处理 proxy.$refs.layoutScrollbarRef.update()
  486. const onDrawerClose = () => {
  487. getThemeConfig.value.isFixedHeaderChange = false;
  488. getThemeConfig.value.isShowLogoChange = false;
  489. getThemeConfig.value.isDrawer = false;
  490. setLocalThemeConfig();
  491. };
  492. // 布局配置弹窗打开
  493. const openDrawer = () => {
  494. getThemeConfig.value.isDrawer = true;
  495. };
  496. // 触发 store 布局配置更新
  497. const setDispatchThemeConfig = () => {
  498. setLocalThemeConfig();
  499. setLocalThemeConfigStyle();
  500. };
  501. // 存储布局配置
  502. const setLocalThemeConfig = () => {
  503. Local.remove('themeConfig');
  504. Local.set('themeConfig', getThemeConfig.value);
  505. };
  506. // 存储布局配置全局主题样式(html根标签)
  507. const setLocalThemeConfigStyle = () => {
  508. Local.set('themeConfigStyle', document.documentElement.style.cssText);
  509. };
  510. // 一键复制配置
  511. const onCopyConfigClick = () => {
  512. let copyThemeConfig = Local.get('themeConfig');
  513. copyThemeConfig.isDrawer = false;
  514. copyText(JSON.stringify(copyThemeConfig)).then(() => {
  515. getThemeConfig.value.isDrawer = false;
  516. });
  517. };
  518. // 一键恢复默认
  519. const onResetConfigClick = () => {
  520. Local.clear();
  521. window.location.reload();
  522. };
  523. // 初始化菜单样式等
  524. const initSetStyle = () => {
  525. // 2、菜单 / 顶栏 --> 顶栏背景渐变
  526. onTopBarGradualChange();
  527. // 2、菜单 / 顶栏 --> 菜单背景渐变
  528. onMenuBarGradualChange();
  529. // 2、菜单 / 顶栏 --> 分栏菜单背景渐变
  530. onColumnsMenuBarGradualChange();
  531. };
  532. onMounted(() => {
  533. nextTick(() => {
  534. // 判断当前布局是否不相同,不相同则初始化当前布局的样式,防止监听窗口大小改变时,布局配置logo、菜单背景等部分布局失效问题
  535. if (!Local.get('frequency')) initLayoutChangeFun();
  536. Local.set('frequency', 1);
  537. // 监听窗口大小改变,非默认布局,设置成默认布局(适配移动端)
  538. proxy.mittBus.on('layoutMobileResize', (res: any) => {
  539. getThemeConfig.value.layout = res.layout;
  540. getThemeConfig.value.isDrawer = false;
  541. initLayoutChangeFun();
  542. state.isMobile = other.isMobile();
  543. });
  544. setTimeout(() => {
  545. // 灰色模式
  546. if (getThemeConfig.value.isGrayscale) onAddFilterChange('grayscale');
  547. // 色弱模式
  548. if (getThemeConfig.value.isInvert) onAddFilterChange('invert');
  549. // 深色模式
  550. if (getThemeConfig.value.isIsDark) onAddDarkChange();
  551. // 开启水印
  552. onWartermarkChange();
  553. // 语言国际化
  554. console.log("globalI18n:", Local.get('themeConfig').globalI18n)
  555. if (Local.get('themeConfig')) proxy.$i18n.locale = Local.get('themeConfig').globalI18n;
  556. // 初始化菜单样式等
  557. initSetStyle();
  558. }, 100);
  559. });
  560. });
  561. onUnmounted(() => {
  562. proxy.mittBus.off('layoutMobileResize');
  563. });
  564. return {
  565. openDrawer,
  566. onColorPickerChange,
  567. onBgColorPickerChange,
  568. onTopBarGradualChange,
  569. onMenuBarGradualChange,
  570. onColumnsMenuBarGradualChange,
  571. onThemeConfigChange,
  572. onIsFixedHeaderChange,
  573. onIsShowLogoChange,
  574. getThemeConfig,
  575. onDrawerClose,
  576. onAddFilterChange,
  577. onAddDarkChange,
  578. onWartermarkChange,
  579. onWartermarkTextInput,
  580. onSetLayout,
  581. setLocalThemeConfig,
  582. onClassicSplitMenuChange,
  583. onIsBreadcrumbChange,
  584. onSortableTagsViewChange,
  585. onShareTagsViewChange,
  586. onCopyConfigClick,
  587. onResetConfigClick,
  588. ...toRefs(state),
  589. };
  590. },
  591. });
  592. </script>
  593. <style scoped lang="scss">
  594. .layout-breadcrumb-seting-bar {
  595. height: calc(100vh - 50px);
  596. padding: 0 15px;
  597. :deep(.el-scrollbar__view) {
  598. overflow-x: hidden !important;
  599. }
  600. .layout-breadcrumb-seting-bar-flex {
  601. display: flex;
  602. align-items: center;
  603. margin-bottom: 5px;
  604. &-label {
  605. flex: 1;
  606. color: var(--el-text-color-primary);
  607. }
  608. }
  609. .layout-drawer-content-flex {
  610. overflow: hidden;
  611. display: flex;
  612. flex-wrap: wrap;
  613. align-content: flex-start;
  614. margin: 0 -5px;
  615. .layout-drawer-content-item {
  616. width: 50%;
  617. height: 70px;
  618. cursor: pointer;
  619. border: 1px solid transparent;
  620. position: relative;
  621. padding: 5px;
  622. .el-container {
  623. height: 100%;
  624. .el-aside-dark {
  625. background-color: var(--next-color-seting-header);
  626. }
  627. .el-aside {
  628. background-color: var(--next-color-seting-aside);
  629. }
  630. .el-header {
  631. background-color: var(--next-color-seting-header);
  632. }
  633. .el-main {
  634. background-color: var(--next-color-seting-main);
  635. }
  636. }
  637. .el-circular {
  638. border-radius: 2px;
  639. overflow: hidden;
  640. border: 1px solid transparent;
  641. transition: all 0.3s ease-in-out;
  642. }
  643. .drawer-layout-active {
  644. border: 1px solid;
  645. border-color: var(--el-color-primary);
  646. }
  647. .layout-tips-warp,
  648. .layout-tips-warp-active {
  649. transition: all 0.3s ease-in-out;
  650. position: absolute;
  651. left: 50%;
  652. top: 50%;
  653. transform: translate(-50%, -50%);
  654. border: 1px solid;
  655. border-color: var(--el-color-primary-light-4);
  656. border-radius: 100%;
  657. padding: 4px;
  658. .layout-tips-box {
  659. transition: inherit;
  660. width: 30px;
  661. height: 30px;
  662. z-index: 9;
  663. border: 1px solid;
  664. border-color: var(--el-color-primary-light-4);
  665. border-radius: 100%;
  666. .layout-tips-txt {
  667. transition: inherit;
  668. position: relative;
  669. top: 5px;
  670. font-size: 12px;
  671. line-height: 1;
  672. letter-spacing: 2px;
  673. white-space: nowrap;
  674. color: var(--el-color-primary-light-4);
  675. text-align: center;
  676. transform: rotate(30deg);
  677. left: -1px;
  678. background-color: var(--next-color-seting-main);
  679. width: 32px;
  680. height: 17px;
  681. line-height: 17px;
  682. }
  683. }
  684. }
  685. .layout-tips-warp-active {
  686. border: 1px solid;
  687. border-color: var(--el-color-primary);
  688. .layout-tips-box {
  689. border: 1px solid;
  690. border-color: var(--el-color-primary);
  691. .layout-tips-txt {
  692. color: var(--el-color-primary) !important;
  693. background-color: var(--next-color-seting-main) !important;
  694. }
  695. }
  696. }
  697. &:hover {
  698. .el-circular {
  699. transition: all 0.3s ease-in-out;
  700. border: 1px solid;
  701. border-color: var(--el-color-primary);
  702. }
  703. .layout-tips-warp {
  704. transition: all 0.3s ease-in-out;
  705. border-color: var(--el-color-primary);
  706. .layout-tips-box {
  707. transition: inherit;
  708. border-color: var(--el-color-primary);
  709. .layout-tips-txt {
  710. transition: inherit;
  711. color: var(--el-color-primary) !important;
  712. background-color: var(--next-color-seting-main) !important;
  713. }
  714. }
  715. }
  716. }
  717. }
  718. }
  719. .copy-config {
  720. margin: 10px 0;
  721. .copy-config-btn {
  722. width: 100%;
  723. margin-top: 15px;
  724. }
  725. .copy-config-btn-reset {
  726. width: 100%;
  727. margin: 10px 0 0;
  728. }
  729. }
  730. }
  731. </style>