index.vue 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  1. <template>
  2. <HcCard actionSize="lg" scrollbar>
  3. <div class="text-lg font-medium mb-4">主题模式<span class="text-sm text-slate-400 font-light ml-4">深色模式还未适配,暂不推荐使用深色模式</span></div>
  4. <div class="hc-theme-box mb-8">
  5. <el-radio-group v-model="UserTheme" @change="ThemeTabsUpdate">
  6. <template v-for="item in ThemeDatas">
  7. <div class="item" :class="UserTheme === item?.key ? 'active' : ''">
  8. <div class="demo" :class="item?.key">
  9. <img :src="ImgTheme" alt="">
  10. </div>
  11. <div class="action" @click="ThemeConfigClick(item)">
  12. <el-radio :label="item?.key" size="large" class="size-xl">{{item?.name}}</el-radio>
  13. </div>
  14. </div>
  15. </template>
  16. </el-radio-group>
  17. </div>
  18. <div class="text-lg font-medium mb-4">主题色</div>
  19. <div class="hc-theme-box color-box mb-4">
  20. <template v-for="(item,index) in ColorConfigData">
  21. <div class="item" :class="UserColorNmae === item.name ? 'active' : ''" v-if="index < 5">
  22. <div class="demo" :class="`bg-${item.name}`">
  23. <img :src="ImgColor" alt="">
  24. </div>
  25. <div class="action" @click="ColorConfigClick(item)">
  26. <el-radio v-model="UserColorNmae" :label="item?.name" size="large" class="size-xl">{{item?.label}}</el-radio>
  27. </div>
  28. </div>
  29. </template>
  30. </div>
  31. <div class="hc-theme-box color-box mb-8">
  32. <template v-for="(item,index) in ColorConfigData">
  33. <div class="item" :class="UserColorNmae === item.name ? 'active' : ''" v-if="index >= 5">
  34. <div class="demo" :class="`bg-${item.name}`">
  35. <img :src="ImgColor" alt="">
  36. </div>
  37. <div class="action" @click="ColorConfigClick(item)">
  38. <el-radio v-model="UserColorNmae" :label="item?.name" size="large" class="size-xl">{{item?.label}}</el-radio>
  39. </div>
  40. </div>
  41. </template>
  42. </div>
  43. <div class="text-lg font-medium mb-2">首页背景</div>
  44. <div class="hc-theme-box home-bg-box mb-8">
  45. <template v-for="item in homeConfigData">
  46. <div class="item mt-2" :class="HomeTheme.name === item?.name ? 'active' : ''" @click="homeConfigClick(item)">
  47. <img :src="item.bg" alt="" crossOrigin="anonymous">
  48. </div>
  49. </template>
  50. </div>
  51. <div class="text-lg font-medium mb-4">截图设置</div>
  52. <div class="hc-screenshot-box mb-4">
  53. <div class="item">
  54. <div class="label">WebRtc:</div>
  55. <el-popover placement="top-start" trigger="hover" :width="400">
  56. <template #reference>
  57. <el-switch v-model="webRtcVal" size="large" active-value="1" inactive-value="0" @change="webRtcUpdate"/>
  58. </template>
  59. <div>
  60. <div>是否启用WebRtc方式截图,WebRtc方式不会错版,但需要同意授权,调用的是浏览器的共享屏幕API (可能在某些浏览器上,不支持)。</div>
  61. <div class="mt-2 mb-2">不启用WebRtc时,采用 html2canvas 实现截图,但支持的并不好,容易出现错版。</div>
  62. <div>但目前市面上,网页截图的仅有这两种方案,推荐使用第三方截图来手动上传图片。</div>
  63. </div>
  64. </el-popover>
  65. </div>
  66. <div class="item">
  67. <div class="label">全屏截图:</div>
  68. <el-popover placement="top-start" trigger="hover" :width="180">
  69. <template #reference>
  70. <el-switch v-model="fullScreenVal" size="large" active-value="1" inactive-value="0" @change="fullScreenUpdate"/>
  71. </template>
  72. <div>单击截全屏的启用状态</div>
  73. </el-popover>
  74. </div>
  75. </div>
  76. <template #action>
  77. <el-popover placement="top" trigger="hover" :width="180">
  78. <template #reference>
  79. <el-button type="primary" hc-btn :loading="saveLoading" @click="SaveConfigClick">
  80. <HcIcon name="save"/>
  81. <span>保存配置</span>
  82. </el-button>
  83. </template>
  84. <div>下次登录后,会自动同步,并启用当前配置</div>
  85. </el-popover>
  86. <el-popover placement="top-start" trigger="hover" :width="180">
  87. <template #reference>
  88. <el-button hc-btn @click="CancelClick">
  89. <HcIcon name="arrow-go-back"/>
  90. <span>取消</span>
  91. </el-button>
  92. </template>
  93. <div>如果没有保存配置,下次登录后,将恢复到上次保存的配置</div>
  94. </el-popover>
  95. </template>
  96. </HcCard>
  97. </template>
  98. <script setup>
  99. import {ref,nextTick} from "vue";
  100. import {useRouter, useRoute} from 'vue-router'
  101. import {useAppStore} from "~src/store";
  102. import themeData from '~src/config/theme';
  103. import {userConfigSave} from "~api/other";
  104. import ImgTheme from "~src/assets/images/theme.png";
  105. import ImgColor from "~src/assets/images/color.png";
  106. import {useOsTheme} from '~src/plugins/useOsTheme';
  107. import {setElementMainColor} from "js-fast-way"
  108. //初始变量
  109. const router = useRouter()
  110. const useRoutes = useRoute()
  111. const useAppState = useAppStore()
  112. //配置变量
  113. const UserTheme = ref(useAppState.getTheme)
  114. const UserColor = ref(useAppState.getColor)
  115. const HomeTheme = ref(useAppState.getHomeTheme)
  116. const webRtcVal = ref(useAppState.getShotWebRtc)
  117. const fullScreenVal = ref(useAppState.getFullScreen)
  118. const UserColorNmae = ref(UserColor.value?.name || 'green')
  119. //颜色
  120. const ColorConfigData = ref(themeData.color)
  121. //更改主色调
  122. const ColorConfigClick = (item) => {
  123. useAppState.setColor(item)
  124. UserColorNmae.value = item?.name
  125. //设置主色调
  126. setElementMainColor(item?.color)
  127. nextTick(() => {
  128. UserColor.value = item
  129. })
  130. }
  131. //更改主题设置
  132. const ThemeDatas = ref([
  133. {key: 'auto', name: '跟随系统'},
  134. {key: 'light', name: '浅色模式'},
  135. {key: 'dark', name: '深色模式'}
  136. ])
  137. const ThemeConfigClick = (item) => {
  138. ThemeTabsUpdate(item?.key)
  139. }
  140. const ThemeTabsUpdate = (val) => {
  141. UserTheme.value = val
  142. useAppState.setTheme(val)
  143. if (val === 'auto') {
  144. useAppState.setThemeVal(useOsTheme().value)
  145. } else {
  146. useAppState.setThemeVal(val)
  147. }
  148. let colorName = UserColorNmae.value || 'green'
  149. document.documentElement.setAttribute('class',`${val} color-${colorName}`)
  150. }
  151. //更改首页主题
  152. const homeConfigData = ref(themeData.home)
  153. const homeConfigClick = (item) => {
  154. HomeTheme.value = item
  155. useAppState.setHomeTheme(item)
  156. }
  157. //更改截图方式
  158. const webRtcUpdate = (val) => {
  159. useAppState.setShotWebRtc(val)
  160. }
  161. //更改全屏截图方式
  162. const fullScreenUpdate = (val) => {
  163. useAppState.setFullScreen(val)
  164. }
  165. //取消配置
  166. const CancelClick = () => {
  167. router.back()
  168. }
  169. //保存配置
  170. const saveLoading = ref(false)
  171. const SaveConfigClick = async () => {
  172. //发起请求
  173. saveLoading.value = true
  174. const { error, code } = await userConfigSave({
  175. theme: UserTheme.value,
  176. color: UserColorNmae.value,
  177. homeTheme: HomeTheme.value?.name,
  178. shotWebRtc: webRtcVal.value,
  179. fullScreen: fullScreenVal.value
  180. })
  181. //判断状态
  182. saveLoading.value = false
  183. if (!error && code === 200) {
  184. window?.$message?.success('保存成功')
  185. router.back()
  186. } else {
  187. window?.$message?.error('保存失败,请稍后再试')
  188. }
  189. }
  190. </script>
  191. <style lang="scss" scoped>
  192. @import "../../styles/view/config.scss";
  193. </style>
  194. <style lang="scss">
  195. .hc-theme-box .item .action .el-radio.el-radio--large {
  196. height: 40px;
  197. }
  198. </style>