setting.vue 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383
  1. <template>
  2. <view class="app-page" :class="{ 'is-balck grey-darken-6': isBlackTheme }">
  3. <tm-form v-if="!loading" ref="formData">
  4. <!-- <tm-sheet :shadow="24" :padding="[12, 24]" :margin="[24, 24]">
  5. <view class="py-12 px-24 mx-12 round-3 border-b-1 grey text">
  6. <text class="text-size-n text-weight-b ">标题</text>
  7. <text class="text-grey text-size-xs px-10">副标题/描述</text>
  8. </view>
  9. <view class="sheet-content">内容区域</view>
  10. </tm-sheet> -->
  11. <tm-sheet :shadow="6" :padding="[12, 24]" :margin="[24, 24]">
  12. <view class="py-12 px-24 mx-12 round-3 grey text">
  13. <text class="text-size-n text-weight-b text-grey-darken-3">布局</text>
  14. <text class="text-grey text-size-xs px-10 ml-12">应用以及文章列表布局设置</text>
  15. </view>
  16. <view class="sheet-content">
  17. <tm-pickers title="请选择首页布局" btn-color="light-blue" :default-value.sync="homeLayout.selectDefault"
  18. rang-key="name" :list="homeLayout.list" @confirm="fnOnHomeLayoutConfirm">
  19. <tm-input name="status" required title="首页文章布局" placeholder="请选择首页文章布局" disabled align="right"
  20. :value="homeLayout.selectLabel" right-icon="icon-angle-right"></tm-input>
  21. </tm-pickers>
  22. <tm-pickers title="请选择文章卡片样式" btn-color="light-blue"
  23. :default-value.sync="articleCardStyle.selectDefault" rang-key="name"
  24. :list="articleCardStyle.list" @confirm="fnOnArticleCardStyleConfirm">
  25. <tm-input name="status" required title="文章卡片样式" placeholder="请选择文章卡片样式" disabled align="right"
  26. :value="articleCardStyle.selectLabel" right-icon="icon-angle-right"></tm-input>
  27. </tm-pickers>
  28. </view>
  29. </tm-sheet>
  30. <tm-sheet v-if="false" :shadow="24" :padding="[12, 24]" :margin="[24, 24]">
  31. <view class="py-12 px-24 mx-12 round-3 grey text">
  32. <text class="text-size-n text-weight-b ">外观</text>
  33. <text class="text-grey text-size-xs px-10">设置应用主题色/暗黑模式等</text>
  34. </view>
  35. <view class="sheet-content">
  36. <!-- 内容区域 -->
  37. <text class="ma-24">todo</text>
  38. </view>
  39. </tm-sheet>
  40. <tm-sheet :shadow="6" :padding="[12, 24]" :margin="[24, 24]">
  41. <view class="py-12 px-24 mx-12 round-3 grey text">
  42. <text class="text-size-n text-weight-b text-grey-darken-3">功能</text>
  43. <text class="text-grey text-size-xs px-10 ml-12">一些常用的功能性设置</text>
  44. </view>
  45. <view class="sheet-content">
  46. <view class="mx-32 my-24 border-b-1 pb-24 flex-between">
  47. <text class="text-size-m">图库瀑布流模式</text>
  48. <tm-switch v-model="appSettings.gallery.useWaterfull" color="light-blue"
  49. :text="['是', '否']"></tm-switch>
  50. </view>
  51. <view class="mx-32 my-24 border-b-1 pb-24 flex-between">
  52. <text class="text-size-m">友链简洁模式</text>
  53. <tm-switch v-model="appSettings.links.useSimple" color="light-blue"
  54. :text="['是', '否']"></tm-switch>
  55. </view>
  56. <!-- <view class="mx-32 mt-24 mb-0 border-b-1 pb-24 flex-between">
  57. <text class="text-size-m">启用评论弹幕</text>
  58. <tm-switch v-model="appSettings.barrage.use" color="light-blue" :text="['是', '否']"></tm-switch>
  59. </view>
  60. <tm-pickers
  61. v-if="appSettings.barrage.use"
  62. title="评论弹幕位置"
  63. btn-color="light-blue"
  64. :default-value.sync="barrage.selectDefault"
  65. rang-key="name"
  66. :list="barrage.list"
  67. @confirm="fnOnBarrageConfirm"
  68. >
  69. <tm-input
  70. name="status"
  71. title="评论弹幕位置"
  72. placeholder="请选择评论弹幕位置"
  73. disabled
  74. align="right"
  75. :value="barrage.selectLabel"
  76. right-icon="icon-angle-right"
  77. ></tm-input>
  78. </tm-pickers> -->
  79. <view class="mx-32 my-24 border-b-1 pb-24 flex-between">
  80. <text class="text-size-m">是否圆形头像</text>
  81. <tm-switch v-model="appSettings.isAvatarRadius" color="light-blue"
  82. :text="['是', '否']"></tm-switch>
  83. </view>
  84. <view class="mx-32 my-24 border-b-1 pb-24 flex-between">
  85. <text class="text-size-m ">轮播图指示器</text>
  86. <tm-switch v-model="appSettings.banner.useDot" color="light-blue"
  87. :text="['是', '否']"></tm-switch>
  88. </view>
  89. <view v-if="appSettings.banner.useDot" class="mx-32 my-24 border-b-1 pb-24 flex-between">
  90. <text class="text-size-m ">轮播图指示器位置</text>
  91. <tm-groupradio name="dotPosition" @change="fnOnBannerDotChange">
  92. <tm-radio :name="item.name" :size="28" color="light-blue"
  93. v-for="(item, index) in dotPositionList" :key="index" v-model="item.checked"
  94. :label="item.name"></tm-radio>
  95. </tm-groupradio>
  96. </view>
  97. <!-- <view class="mx-32 my-24 border-b-1 pb-24 flex-between">
  98. <text class="text-size-m">显示完整统计</text>
  99. <tm-switch v-model="appSettings.about.showAllCount" color="light-blue" :text="['是', '否']"></tm-switch>
  100. </view>
  101. <view class="mx-32 my-24 border-b-1 pb-24 flex-between">
  102. <text class="text-size-m ">链接直接打开</text>
  103. <tm-switch v-model="appSettings.contact.isLinkCopy" color="light-blue" :text="['是', '否']"></tm-switch>
  104. </view>
  105. <view v-if="false" class="mx-32 my-24 border-b-1 pb-24 flex-between">
  106. <text class="text-size-m ">显示后台入口</text>
  107. <tm-switch v-model="appSettings.about.showAdmin" color="light-blue" :text="['是', '否']"></tm-switch>
  108. </view> -->
  109. </view>
  110. </tm-sheet>
  111. </tm-form>
  112. <!-- 操作区域 -->
  113. <view v-if="!loading" class="btn-bar flex flex-center bg-white">
  114. <tm-button theme="light-blue" :shadow="0" block :height="70" @click="fnOnSave()">保存设置</tm-button>
  115. <tm-button theme="red" :shadow="0" block :height="70" @click="fnOnSaveDefault()">恢复默认设置</tm-button>
  116. <tm-button theme="blue-grey" :shadow="0" block :height="70" @click="fnOnBack()">返回</tm-button>
  117. </view>
  118. </view>
  119. </template>
  120. <script>
  121. import {
  122. _DefaultAppSettings
  123. } from '@/utils/app.js';
  124. import tmButton from '@/tm-vuetify/components/tm-button/tm-button.vue';
  125. import tmForm from '@/tm-vuetify/components/tm-form/tm-form.vue';
  126. import tmPickers from '@/tm-vuetify/components/tm-pickers/tm-pickers.vue';
  127. import tmInput from '@/tm-vuetify/components/tm-input/tm-input.vue';
  128. import tmSwitch from '@/tm-vuetify/components/tm-switch/tm-switch.vue';
  129. import tmSheet from '@/tm-vuetify/components/tm-sheet/tm-sheet.vue';
  130. import tmGroupradio from '@/tm-vuetify/components/tm-groupradio/tm-groupradio.vue';
  131. import tmRadio from '@/tm-vuetify/components/tm-radio/tm-radio.vue';
  132. export default {
  133. components: {
  134. tmButton,
  135. tmForm,
  136. tmPickers,
  137. tmInput,
  138. tmSwitch,
  139. tmSheet,
  140. tmGroupradio,
  141. tmRadio
  142. },
  143. data() {
  144. return {
  145. isBlackTheme: false,
  146. loading: true,
  147. appSettings: {},
  148. isSaved: true,
  149. firstLoad: true,
  150. homeLayout: {
  151. list: [{
  152. name: '一行一列',
  153. value: 'h_row_col1'
  154. }, {
  155. name: '一行两列',
  156. value: 'h_row_col2'
  157. }],
  158. selectDefault: ['一行一列'],
  159. selectLabel: '一行一列',
  160. selectValue: 'h_row_col1'
  161. },
  162. articleCardStyle: {
  163. list: [{
  164. name: '左图右文',
  165. value: 'lr_image_text'
  166. },
  167. {
  168. name: '左文右图',
  169. value: 'lr_text_image'
  170. },
  171. {
  172. name: '上图下文',
  173. value: 'tb_image_text'
  174. },
  175. {
  176. name: '上文下图',
  177. value: 'tb_text_image'
  178. },
  179. {
  180. name: '只有文字',
  181. value: 'only_text'
  182. }
  183. ],
  184. selectDefault: ['左图右文'],
  185. selectLabel: '左图右文',
  186. selectValue: 'lr_image_text'
  187. },
  188. dotPositionList: [{
  189. name: '右边',
  190. value: 'right',
  191. checked: true
  192. }, {
  193. name: '下边',
  194. value: 'bottom',
  195. checked: false
  196. }],
  197. barrage: {
  198. list: [{
  199. name: '顶部',
  200. value: 'rightToLeft'
  201. }, {
  202. name: '左下',
  203. value: 'leftBottom'
  204. }],
  205. selectDefault: ['顶部'],
  206. selectLabel: '顶部',
  207. selectValue: 'rightToLeft'
  208. }
  209. };
  210. },
  211. watch: {
  212. appSettings: {
  213. deep: true,
  214. handler() {
  215. if (this.firstLoad) {
  216. this.firstLoad = false;
  217. } else {
  218. this.isSaved = false;
  219. }
  220. }
  221. }
  222. },
  223. onLoad(e) {
  224. this.fnSetPageTitle('应用设置');
  225. },
  226. created() {
  227. this.appSettings = Object.assign({}, _DefaultAppSettings, uni.$tm.vx.getters().getSettings);
  228. this.fnHandleFormatSelect();
  229. uni.showLoading({
  230. title: '加载中...',
  231. mask: true
  232. });
  233. setTimeout(() => {
  234. this.loading = false;
  235. uni.hideLoading();
  236. }, 500);
  237. },
  238. methods: {
  239. // 统一处理选择框的内容
  240. fnHandleFormatSelect() {
  241. // 首页布局
  242. const _homeLayout = this.fnFindObjInList(this.homeLayout.list, 'value', this.appSettings.layout.home);
  243. this.homeLayout.selectDefault = [_homeLayout.name];
  244. this.homeLayout.selectLabel = _homeLayout.name;
  245. this.homeLayout.selectValue = _homeLayout.value;
  246. const _articleCardStyle = this.fnFindObjInList(this.articleCardStyle.list, 'value', this.appSettings.layout
  247. .cardType);
  248. this.articleCardStyle.selectDefault = [_articleCardStyle.name];
  249. this.articleCardStyle.selectLabel = _articleCardStyle.name;
  250. this.articleCardStyle.selectValue = _articleCardStyle.value;
  251. const _barrage = this.fnFindObjInList(this.barrage.list, 'value', this.appSettings.barrage.type);
  252. this.barrage.selectDefault = [_barrage.name];
  253. this.barrage.selectLabel = _barrage.name;
  254. this.barrage.selectValue = _barrage.value;
  255. },
  256. // 在集合中找匹配的对象
  257. fnFindObjInList(list, key, value) {
  258. return list.find(x => x[key] == value);
  259. },
  260. fnOnBannerDotChange(e) {
  261. const _select = e[0];
  262. if (_select.index == 0 && _select.checked) {
  263. this.appSettings.banner.dotPosition = 'right';
  264. }
  265. if (_select.index == 1 && _select.checked) {
  266. this.appSettings.banner.dotPosition = 'bottom';
  267. }
  268. },
  269. // 首页布局
  270. fnOnHomeLayoutConfirm(e) {
  271. const _select = e[0].data;
  272. this.homeLayout.selectDefault = [_select.name];
  273. this.homeLayout.selectLabel = _select.name;
  274. this.homeLayout.selectValue = _select.value;
  275. this.appSettings.layout.home = _select.value;
  276. },
  277. // 文章卡片样式
  278. fnOnArticleCardStyleConfirm(e) {
  279. const _select = e[0].data;
  280. this.articleCardStyle.selectDefault = [_select.name];
  281. this.articleCardStyle.selectLabel = _select.name;
  282. this.articleCardStyle.selectValue = _select.value;
  283. this.appSettings.layout.cardType = _select.value;
  284. },
  285. // 弹幕设置
  286. fnOnBarrageConfirm(e) {
  287. const _select = e[0].data;
  288. this.barrage.selectDefault = [_select.name];
  289. this.barrage.selectLabel = _select.name;
  290. this.barrage.selectValue = _select.value;
  291. this.appSettings.barrage.type = _select.value;
  292. },
  293. // 保存
  294. fnOnSave() {
  295. this.isSaved = true;
  296. this.$tm.vx.commit('setting/setSettings', this.appSettings);
  297. uni.$tm.toast('保存成功,部分设置在重启后生效!');
  298. },
  299. // 使用默认配置
  300. fnOnSaveDefault() {
  301. uni.$eShowModal({
  302. title: '提示',
  303. content: '您确定要恢复为默认的设置吗?',
  304. showCancel: true,
  305. cancelText: '否',
  306. cancelColor: '#999999',
  307. confirmText: '是',
  308. confirmColor: '#03a9f4'
  309. })
  310. .then(res => {
  311. this.isSaved = true;
  312. uni.$tm.vx.actions('setting/updateDefaultAppSettings');
  313. uni.$tm.toast('系统设置已恢复为默认配置,部分设置在重启后生效!');
  314. })
  315. .catch(err => {});
  316. },
  317. fnOnBack() {
  318. if (this.isSaved) {
  319. uni.navigateBack();
  320. return;
  321. }
  322. uni.$eShowModal({
  323. title: '提示',
  324. content: '您当前可能有未保存的数据,确定返回吗?',
  325. showCancel: true,
  326. cancelText: '否',
  327. cancelColor: '#999999',
  328. confirmText: '是',
  329. confirmColor: '#03a9f4'
  330. })
  331. .then(res => {
  332. uni.navigateBack();
  333. this.isSaved = true;
  334. })
  335. .catch(err => {});
  336. }
  337. }
  338. };
  339. </script>
  340. <style scoped lang="scss">
  341. .app-page {
  342. box-sizing: border-box;
  343. padding-bottom: 120rpx;
  344. .btn-bar {
  345. width: 100vw;
  346. position: fixed;
  347. left: 0;
  348. bottom: 0;
  349. box-sizing: border-box;
  350. padding: 24rpx;
  351. gap: 0 24rpx;
  352. box-shadow: 0rpx -6rpx 24rpx rgba(0, 0, 0, 0.03);
  353. }
  354. }
  355. .required {
  356. position: relative;
  357. padding-left: 18rpx;
  358. &:before {
  359. content: '*';
  360. position: absolute;
  361. left: -4rpx;
  362. top: 50%;
  363. transform: translateY(-50%);
  364. font-size: 34rpx;
  365. color: rgba(244, 67, 54, 1);
  366. }
  367. }
  368. </style>