setting.vue 12 KB

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