├── App.vue ├── LICENSE.md ├── README.md ├── androidPrivacy.json ├── app ├── components │ ├── app-footer │ │ └── app-footer.vue │ ├── app-nav-li │ │ └── app-nav-li.vue │ └── app-navbar │ │ └── app-navbar.vue ├── index.js ├── js │ ├── filters.js │ └── mixin.js ├── scss │ ├── _app.scss │ ├── _var.scss │ ├── icon │ │ ├── _coloricon.scss │ │ └── _style.scss │ ├── style │ │ └── _prism.scss │ └── theme │ │ ├── _darkblue.scss │ │ ├── _lightblue.scss │ │ └── _style.scss └── store │ └── index.js ├── main.js ├── manifest.json ├── package.json ├── pages.json ├── pages ├── about │ └── about.vue ├── comments │ └── comments.vue ├── detail │ └── detail.vue ├── hot │ └── hot.vue ├── index │ └── index.vue ├── list │ └── list.vue ├── live │ └── live.vue ├── logs │ └── logs.vue ├── my │ └── my.vue ├── page │ └── page.vue ├── pay │ └── pay.vue ├── poster │ └── poster.vue ├── readlog │ └── readlog.vue ├── search │ └── search.vue ├── system │ └── system.vue ├── tags │ └── tags.vue ├── theme │ └── theme.vue ├── topic │ └── topic.vue └── webpage │ └── webpage.vue ├── polyfill ├── README.md ├── base64Binary.js ├── mixins.js └── polyfill.js ├── project.config.json ├── project.private.config.json ├── sitemap.json ├── static └── images │ ├── gravatar.png │ ├── logo.png │ ├── logo700.png │ ├── website-search.png │ └── website.png ├── ui ├── components │ ├── ui-avatar-stack │ │ └── ui-avatar-stack.vue │ ├── ui-avatar │ │ └── ui-avatar.vue │ ├── ui-card │ │ └── ui-card.vue │ ├── ui-change-theme │ │ └── ui-change-theme.vue │ ├── ui-checkbox-group │ │ └── ui-checkbox-group.vue │ ├── ui-checkbox │ │ └── ui-checkbox.vue │ ├── ui-code │ │ ├── prism.js │ │ └── ui-code.vue │ ├── ui-color-picker │ │ └── ui-color-picker.vue │ ├── ui-fixed │ │ └── ui-fixed.vue │ ├── ui-form-group │ │ └── ui-form-group.vue │ ├── ui-form │ │ └── ui-form.vue │ ├── ui-img │ │ └── ui-img.vue │ ├── ui-input │ │ └── ui-input.vue │ ├── ui-loading │ │ └── ui-loading.vue │ ├── ui-menu-item │ │ └── ui-menu-item.vue │ ├── ui-menu │ │ └── ui-menu.vue │ ├── ui-modal │ │ └── ui-modal.vue │ ├── ui-navbar │ │ └── ui-navbar.vue │ ├── ui-popover │ │ └── ui-popover.vue │ ├── ui-progress │ │ └── ui-progress.vue │ ├── ui-radio-group │ │ └── ui-radio-group.vue │ ├── ui-radio │ │ └── ui-radio.vue │ ├── ui-stepper │ │ └── ui-stepper.vue │ ├── ui-steps │ │ └── ui-steps.vue │ ├── ui-swiper │ │ └── ui-swiper.vue │ ├── ui-switch │ │ └── ui-switch.vue │ ├── ui-sys │ │ └── ui-sys.vue │ ├── ui-tab-item │ │ └── ui-tab-item.vue │ ├── ui-tab │ │ └── ui-tab.vue │ ├── ui-tabbar │ │ └── ui-tabbar.vue │ ├── ui-table │ │ ├── csv.js │ │ ├── export-csv.js │ │ └── ui-table.vue │ ├── ui-tag │ │ └── ui-tag.vue │ ├── ui-text-size │ │ └── ui-text-size.vue │ ├── ui-title │ │ └── ui-title.vue │ └── ui-toast │ │ └── ui-toast.vue ├── index.js ├── js │ ├── mixin.js │ ├── modal.js │ ├── request.js │ ├── toast.js │ └── util.js ├── scss │ ├── _main.scss │ ├── _mixins.scss │ ├── _var.scss │ ├── icon │ │ ├── _icon.scss │ │ └── _style.scss │ ├── style │ │ ├── _avatar.scss │ │ ├── _background.scss │ │ ├── _border.scss │ │ ├── _button.scss │ │ ├── _card.scss │ │ ├── _code.scss │ │ ├── _flex.scss │ │ ├── _form.scss │ │ ├── _grid.scss │ │ ├── _markdown.scss │ │ ├── _menu.scss │ │ ├── _shadow.scss │ │ ├── _table.scss │ │ ├── _tag.scss │ │ └── _text.scss │ ├── theme │ │ ├── _dark.scss │ │ ├── _light.scss │ │ └── _style.scss │ └── ui.scss └── store │ ├── index.js │ └── modal.js ├── uni.scss ├── uni_modules └── mp-html │ ├── README.md │ ├── changelog.md │ ├── components │ └── mp-html │ │ ├── mp-html.vue │ │ ├── node │ │ └── node.vue │ │ └── parser.js │ ├── package.json │ └── static │ └── app-plus │ └── mp-html │ ├── js │ ├── handler.js │ └── uni.webview.min.js │ └── local.html └── utils ├── adapter.js ├── api.js ├── auth.js ├── config.js ├── uiconfig.js ├── util.js ├── wxApi.js └── wxRequest.js /LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Jianbo 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## WordPress多端应用 2 | 后端使用开源博客建站系统wordpress和微慕小程序开源版插件,前端使用uniapp+colorui。 3 | 4 | 本项目可以直接同步wordpress的内容并生成H5、微信小程序、QQ小程序、支付宝小程序、百度小程序、头条抖音小程序、安卓APP、苹果APP及快应用。 5 | 6 | 7 | 8 | 目前的模板是资讯模板,后期会看下载和使用情况增加企业官网等模板 9 | 10 | ## 注意事项 11 | 因为没有用到互动功能,所以wordpress后台的微慕小程序插件只起到同步内容的作用,appid和密钥及赞赏相关的设置不需要设置。 12 | 13 | 如果需要互动和激励广告等功能,可以使用微慕开源版原生微信小程序。 14 | 15 | 不要因为没有百度等小程序的设置就给差评,也不要因为自己不会使用就给差评,**有问题留言**。 16 | 17 | ## 问答交流 18 | **请不要以差评的方式提问,非常感谢** 19 | 20 | 1. 直接在dcloud插件市场评论提问,有问题直接留言即可 21 | 2. 在ask论坛提问:[点此提问](https://ask.dcloud.net.cn "点此提问") 22 | 3. 付费咨询及远程服务加微信:poisonkid 23 | 24 | 【微信仅提供付费服务,有问题尽量使用1、2方式提问,也方便后边的人】 25 | 26 | ## 案例演示 27 | 演示的不一定是最新版,以dcloud插件市场发布为准 28 | 29 | 多端H5:https://www.watch-life.net/h5/index.html 30 | 31 | 安卓APP:https://wwi.lanzoul.com/iRUlq00d5m4f 32 | 33 | 苹果APP: 暂未上线 34 | 35 | 小程序:守望轩LIVE(原生小程序,有互动支付相关功能) 36 | 37 | 快应用: 暂未上线 38 | 39 | 如果你有多端小程序账号,且为企业主体,可以联系我搭建作为案例演示 40 | 41 | ## 使用方法 42 | ### 网站后端 43 | **建议先看看[微慕小程序开源版安装文档](https://docs.minapper.com/minfree/2304123 "微慕小程序开源版安装文档")** 44 | 1. 搭建wordpress网站,推荐使用nginx+php7.4+mysql5.7 45 | 2. 在wordpress插件市场搜索“REST API TO MiniProgram”安装并启用微慕小程序开源版插件 46 | 3. 设置wordpress固定连接及伪静态规则,推荐使用/%post_id%.html 47 | - 在浏览器输入https://xxx.com/wp-json/wp/v2/posts 48 | - 如果有数据输出则说明设置没有问题,如果出现404或者其他问题则说明伪静态没有设置好 49 | 4. 发布一些文章,发布一个关于我们的页面 50 | - 在微慕小程序—扩展设置—设置轮播图及精选栏目 51 | - 在微慕小程序—基础设置—设置显示的文章分类id 和"关于我们"页面 52 | 5. 小程序后台还需要设置授权域名,必须支持https 53 | 54 | ### 前端 55 | 1. 将本项目导入HbuilerX 56 | 2. 安装[SaaS插件](https://ext.dcloud.net.cn/plugin?name=compile-node-sass "SaaS插件") 57 | 3. 设置/utils/config.js下的域名及其他信息 58 | ```html 59 | var DOMAIN = "www.watch-life.net"; //网站域名 60 | var WEBSITENAME = "守望轩"; //网站名称 61 | var PAGECOUNT = '10'; //每页文章数目 62 | var WECHAT = '微信号:poisonkid'; //联系方式如:微信号:iamxjb 邮箱:468909765@qq.com 63 | ``` 64 | 4. 运行到各端体验即可 65 | 66 | ## 常见问题 67 | 摘录一些留言及付费解决的问题到这里,如果你遇到同样问题可以尝试一下 68 | 69 | Q: **打包了app安装好了,但是打开白屏** 70 | 71 | A: 之前的版本没有设置轮播图就会导致所有内容不显示,新版已经解决此问题 72 | 73 | 另外如果伪静态没有做好,api没有内容输出也会白屏 74 | 还有一种情况就是模拟器打开白屏,但是真机没有问题,是因为manifest.json设置里没有勾选x86 75 | 76 | 77 | 78 | Q: **怎么设置默认主题色** 79 | 80 | A: 在app/store/index.js中设置 81 | ``` 82 | themeAuto: false, // 深色模式跟随系统 83 | theme: 'light', // 设置默认模式,dark深色 light浅色 84 | main: 'blue', // 设置默认主题色 85 | ``` 86 | 87 | ## 感谢 88 | 专业的WordPress生成小程序解决方案 —— [微慕](https://blog.minapper.com/) 89 | 90 | 界面精美专注视觉的小程序css组件库 ——[color-ui](https://github.com/Color-UI/MP-CU) 91 | 92 | color-ui的UNIAPP版本 ——[ColorUI-UniApp](https://ext.dcloud.net.cn/plugin?id=239) 93 | 94 | -------------------------------------------------------------------------------- /androidPrivacy.json: -------------------------------------------------------------------------------- 1 | { 2 | "prompt": "template" 3 | } 4 | -------------------------------------------------------------------------------- /app/components/app-footer/app-footer.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 15 | 16 | 23 | -------------------------------------------------------------------------------- /app/components/app-nav-li/app-nav-li.vue: -------------------------------------------------------------------------------- 1 | 16 | 17 | 40 | 41 | // 42 | 73 | 188 | -------------------------------------------------------------------------------- /app/components/app-navbar/app-navbar.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /app/index.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | 3 | // 挂载app混入 4 | import appMixin from '@/app/js/mixin.js' 5 | Vue.mixin(appMixin) 6 | 7 | // 挂载app过滤 8 | // import apFilters from "@/app/js/filters.js" 9 | // Object.keys(filters).forEach(key => { 10 | // Vue.filter(key, filters[key]) 11 | // }) 12 | -------------------------------------------------------------------------------- /app/js/filters.js: -------------------------------------------------------------------------------- 1 | 2 | export default { } -------------------------------------------------------------------------------- /app/js/mixin.js: -------------------------------------------------------------------------------- 1 | import { 2 | mapState 3 | } from 'vuex'; 4 | export default { 5 | data() { 6 | return { 7 | }; 8 | }, 9 | computed: { 10 | ...mapState({ 11 | }), 12 | }, 13 | 14 | props: { 15 | 16 | }, 17 | onLoad() { 18 | 19 | }, 20 | onShareTimeline() { 21 | return { 22 | title: 'ui组件库', 23 | query: {} 24 | }; 25 | }, 26 | onShareAppMessage() { 27 | wx.showShareMenu({ 28 | withShareTicket: true, 29 | menus: ['shareAppMessage', 'shareTimeline'] 30 | }); 31 | }, 32 | created() { 33 | 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /app/scss/_app.scss: -------------------------------------------------------------------------------- 1 | // 你项目单独的样式↓ -------------------------------------------------------------------------------- /app/scss/_var.scss: -------------------------------------------------------------------------------- 1 | //颜色 2 | $yellow: #fbbd08; 3 | $orange: #f37b1d; 4 | $red: #e54d42; 5 | $pink: #e03997; 6 | $mauve: #b745cb; 7 | $purple: #8044de; 8 | $blue: #0081ff; 9 | $cyan: #37c0fe; 10 | $green: #3eb93b; 11 | $olive: #8dc63f; 12 | $grey: #8799a3; 13 | $brown: #a5673f; 14 | 15 | $colors: (); 16 | $colors: map-merge( 17 | ( 18 | 'yellow': $yellow, 19 | 'orange': $orange, 20 | 'red': $red, 21 | 'pink': $pink, 22 | 'mauve': $mauve, 23 | 'purple': $purple, 24 | 'violet': $purple, 25 | 'blue': $blue, 26 | 'cyan': $cyan, 27 | 'green': $green, 28 | 'olive': $olive, 29 | 'grey': $grey, 30 | 'brown': $brown, 31 | ), 32 | $colors 33 | ); 34 | 35 | //灰度 36 | $white: #ffffff; 37 | $gray-f: #f8f9fa; 38 | $gray-e: #eeeeee; 39 | $gray-d: #dddddd; 40 | $gray-c: #cccccc; 41 | $gray-b: #bbbbbb; 42 | $gray-a: #aaaaaa; 43 | $dark-9: #999999; 44 | $dark-8: #888888; 45 | $dark-7: #777777; 46 | $dark-6: #666666; 47 | $dark-5: #555555; 48 | $dark-4: #444444; 49 | $dark-3: #333333; 50 | $dark-2: #222222; 51 | $dark-1: #111111; 52 | $black: #000000; 53 | 54 | $grays: (); 55 | $grays: map-merge( 56 | ( 57 | 'white': $white, 58 | 'gray-f': $gray-f, 59 | 'gray-e': $gray-e, 60 | 'gray-d': $gray-d, 61 | 'gray-c': $gray-c, 62 | 'gray-b': $gray-b, 63 | 'gray-a': $gray-a, 64 | 'gray': $gray-a, 65 | ), 66 | $grays 67 | ); 68 | 69 | $darks: (); 70 | $darks: map-merge( 71 | ( 72 | 'dark-9': $dark-9, 73 | 'dark-8': $dark-8, 74 | 'dark-7': $dark-7, 75 | 'dark-6': $dark-6, 76 | 'dark-5': $dark-5, 77 | 'dark-4': $dark-4, 78 | 'dark-3': $dark-3, 79 | 'dark-2': $dark-2, 80 | 'dark-1': $dark-1, 81 | 'black': $black, 82 | ), 83 | $darks 84 | ); 85 | 86 | 87 | // 边框 88 | $border-width: 1rpx !default; // 边框大小 89 | // $border-color: $gray-d !default; // 边框颜色 90 | 91 | // 圆角 92 | $radius: 10rpx !default; // 默认圆角大小 93 | $radius-lg: 40rpx !default; // 大圆角 94 | $radius-sm: 6rpx !default; // 小圆角 95 | $round-pill: 1000rpx !default; // 半圆 96 | 97 | // 动画过渡 98 | $transition-base: all .2s ease-in-out !default; // 默认过渡 99 | $transition-base-out: all .04s ease-in-out !default; // 进场过渡 100 | $transition-fade: opacity .15s linear !default; // 透明过渡 101 | $transition-collapse: height .35s ease !default; // 收缩过渡 102 | 103 | // 间距 104 | $spacer: 20rpx !default; 105 | $spacers: () !default; 106 | $spacers: map-merge( 107 | ( 108 | 0: 0, 109 | 1: $spacer * 0.25, 110 | 2: $spacer * .5, 111 | 3: $spacer, 112 | 4: $spacer * 1.5, 113 | 5: $spacer * 3, 114 | 6: $spacer * 5, 115 | ), 116 | $spacers 117 | ); 118 | 119 | // 字形 120 | $font-weight-lighter: lighter !default; 121 | $font-weight-light: 300 !default; 122 | $font-weight-normal: 400 !default; 123 | $font-weight-bold: 700 !default; 124 | $font-weight-bolder: 900 !default; 125 | $fontsize: () !default; 126 | $fontsize: map-merge( 127 | ( 128 | xs: 20, 129 | sm: 24, 130 | df: 28, 131 | lg: 32, 132 | xl: 36, 133 | xxl: 44, 134 | sl: 80, 135 | xsl: 120 136 | ), 137 | $fontsize 138 | ); 139 | 140 | // 段落 141 | $line-height-base: 1.5 !default; 142 | $line-height-lg: 2 !default; 143 | $line-height-sm: 1.25 !default; 144 | 145 | // 图标 146 | $iconsize: () !default; 147 | $iconsize: map-merge( 148 | ( 149 | xs: 0.5, 150 | sm: 0.75, 151 | df: 1, 152 | lg: 1.25, 153 | xl: 1.5, 154 | xxl: 2, 155 | sl: 6, 156 | xsl: 10 157 | ), 158 | $iconsize 159 | ); 160 | -------------------------------------------------------------------------------- /app/scss/icon/_style.scss: -------------------------------------------------------------------------------- 1 | @import './coloricon'; -------------------------------------------------------------------------------- /app/scss/style/_prism.scss: -------------------------------------------------------------------------------- 1 | /* PrismJS 1.19.0 2 | https://prismjs.com/download.html#themes=prism&languages=markup+css+clike+javascript */ 3 | /** 4 | * prism.js default theme for JavaScript, CSS and HTML 5 | * Based on dabblet (http://dabblet.com) 6 | * @author Lea Verou 7 | */ 8 | 9 | code[class*="language-"], 10 | pre[class*="language-"] { 11 | color: black; 12 | background: none; 13 | text-shadow: 0 1px white; 14 | font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace; 15 | font-size: 1em; 16 | text-align: left; 17 | white-space: pre; 18 | word-spacing: normal; 19 | word-break: normal; 20 | word-wrap: normal; 21 | line-height: 1.5; 22 | 23 | -moz-tab-size: 4; 24 | -o-tab-size: 4; 25 | tab-size: 4; 26 | 27 | -webkit-hyphens: none; 28 | -moz-hyphens: none; 29 | -ms-hyphens: none; 30 | hyphens: none; 31 | } 32 | 33 | pre[class*="language-"]::-moz-selection, pre[class*="language-"] ::-moz-selection, 34 | code[class*="language-"]::-moz-selection, code[class*="language-"] ::-moz-selection { 35 | text-shadow: none; 36 | background: #b3d4fc; 37 | } 38 | 39 | pre[class*="language-"]::selection, pre[class*="language-"] ::selection, 40 | code[class*="language-"]::selection, code[class*="language-"] ::selection { 41 | text-shadow: none; 42 | background: #b3d4fc; 43 | } 44 | 45 | @media print { 46 | code[class*="language-"], 47 | pre[class*="language-"] { 48 | text-shadow: none; 49 | } 50 | } 51 | 52 | /* Code blocks */ 53 | pre[class*="language-"] { 54 | padding: 1em; 55 | margin: .5em 0; 56 | overflow: auto; 57 | } 58 | 59 | :not(pre) > code[class*="language-"], 60 | pre[class*="language-"] { 61 | background: #f5f2f0; 62 | } 63 | 64 | /* Inline code */ 65 | :not(pre) > code[class*="language-"] { 66 | padding: .1em; 67 | border-radius: .3em; 68 | white-space: normal; 69 | } 70 | 71 | .comment, 72 | .prolog, 73 | .doctype, 74 | .cdata { 75 | color: slategray; 76 | } 77 | 78 | .punctuation { 79 | color: $grey; 80 | } 81 | 82 | .namespace { 83 | opacity: .7; 84 | } 85 | 86 | .property, 87 | .tag, 88 | .boolean, 89 | .number, 90 | .constant, 91 | .symbol, 92 | .deleted { 93 | color: $green; 94 | } 95 | 96 | .selector, 97 | .attr-name, 98 | .string, 99 | .char, 100 | .builtin, 101 | .inserted { 102 | color: $blue; 103 | } 104 | 105 | .operator, 106 | .entity, 107 | .url, 108 | .language-css .string, 109 | .style .string { 110 | color: $brown; 111 | } 112 | 113 | .atrule, 114 | .attr-value, 115 | .keyword { 116 | color: $cyan; 117 | } 118 | 119 | .function, 120 | .class-name { 121 | color: $red; 122 | } 123 | 124 | .regex, 125 | .important, 126 | .variable { 127 | color: $orange; 128 | } 129 | 130 | .important, 131 | .bold { 132 | font-weight: bold; 133 | } 134 | .italic { 135 | font-style: italic; 136 | } 137 | 138 | .entity { 139 | cursor: help; 140 | } 141 | 142 | -------------------------------------------------------------------------------- /app/scss/theme/_darkblue.scss: -------------------------------------------------------------------------------- 1 | @mixin theme-darkblue { 2 | 3 | // 背景色 4 | --ui-BG: #111111; 5 | --ui-BG-1: #181818; 6 | --ui-BG-2: #1b1b1b; 7 | --ui-BG-3: #222222; 8 | --ui-BG-4: #282828; 9 | 10 | // 文本色 11 | --ui-TC: #ffffff; 12 | --ui-TC-1: #d4d4d4; 13 | --ui-TC-2: #919191; 14 | --ui-TC-3: #6a6a6a; 15 | --ui-TC-4: #474747; 16 | 17 | // 模糊 18 | --ui-Blur: rgba(17, 17, 17, 0.85); 19 | --ui-Blur-1: rgba(24, 24, 24, 0.85); 20 | --ui-Blur-2: rgba(27, 27, 27, 0.85); 21 | --ui-Blur-3: rgba(34, 34, 34, 0.85); 22 | 23 | // 边框 24 | --ui-Border: #303030; 25 | --ui-Outline: rgba(255,255,255,0.1); 26 | --ui-Line: rgba(119,119,119,0.25); 27 | } 28 | -------------------------------------------------------------------------------- /app/scss/theme/_lightblue.scss: -------------------------------------------------------------------------------- 1 | @mixin theme-lightblue { 2 | 3 | // 背景色 4 | --ui-BG: #ffffff; 5 | --ui-BG-1: #f6f6f6; 6 | --ui-BG-2: #f1f1f1; 7 | --ui-BG-3: #e8e8e8; 8 | --ui-BG-4: #e0e0e0; 9 | 10 | // 文本色 11 | --ui-TC: #303030; 12 | --ui-TC-1: #525252; 13 | --ui-TC-2: #777777; 14 | --ui-TC-3: #9e9e9e; 15 | --ui-TC-4: #c6c6c6; 16 | 17 | // 模糊 18 | --ui-Blur: rgba(255, 255, 255, 0.85); 19 | --ui-Blur-1: rgba(246, 246, 246, 0.85); 20 | --ui-Blur-2: rgba(241,241,241,0.85); 21 | --ui-Blur-3: rgba(232,232,232,0.85); 22 | 23 | // 边框 24 | --ui-Border: #d4d4d4; 25 | --ui-Outline: rgba(0,0,0,0.1); 26 | --ui-Line: rgba(119,119,119,0.25); 27 | } 28 | -------------------------------------------------------------------------------- /app/scss/theme/_style.scss: -------------------------------------------------------------------------------- 1 | // 导入自定义主题 2 | @import './lightblue'; //浅蓝主题 3 | @import './darkblue'; //深蓝主题 4 | 5 | .theme-darkblue { 6 | @include theme-darkblue; 7 | } 8 | .theme-lightblue { 9 | @include theme-lightblue; 10 | } 11 | -------------------------------------------------------------------------------- /app/store/index.js: -------------------------------------------------------------------------------- 1 | export default { 2 | state: { 3 | isTheme: true, // 是否开启多主题(true:会读缓存,能设置对应的主题) 4 | themeAuto: false, // 跟随系统 5 | theme: 'light', // 设置默认主题 6 | main: 'blue', // 设置默认强调色 7 | text: 1, // 设置默认字号等级(0-4) 8 | domain: ' ', 9 | apiPath: '/api/', 10 | homePath: '/pages/index/index', // 设置首页路径(一些组件会用到跳回主页,请每个项目设置好!) 11 | tabbar: [{ 12 | title: '首页', 13 | icon: 'cicon-home-sm-o', 14 | curIcon: 'cicon-home-line', 15 | url: '/pages/index/index', 16 | type: 'tab' 17 | }, 18 | { 19 | title: '分类', 20 | icon: 'cicon-discover-o', 21 | curIcon: 'cicon-discover', 22 | url: '/pages/topic/topic', 23 | type: 'tab' 24 | }, 25 | { 26 | title: '排行', 27 | icon: 'cicon-upstage-o', 28 | curIcon: 'cicon-upstage', 29 | url: '/pages/hot/hot', 30 | type: 'tab' 31 | }, 32 | { 33 | title: '我的', 34 | icon: 'cicon-my-o', 35 | curIcon: 'cicon-my', 36 | url: '/pages/my/my', 37 | type: 'tab' 38 | }], 39 | nav: [] 40 | 41 | }, 42 | getters: { 43 | getCustomTheme: state => { 44 | return state.theme 45 | }, 46 | getCustomMain: state => { 47 | return state.main 48 | }, 49 | getCustomText: state => { 50 | return state.text 51 | }, 52 | getTabbar: state => { 53 | return state.tabbar 54 | }, 55 | getNav: state => { 56 | return state.nav 57 | }, 58 | getDomain: state => { 59 | return state.domain 60 | }, 61 | getApiPath: state => { 62 | return state.apiPath 63 | }, 64 | }, 65 | mutations: { 66 | 67 | }, 68 | actions: {} 69 | } 70 | -------------------------------------------------------------------------------- /main.js: -------------------------------------------------------------------------------- 1 | import App from './App' 2 | import ui from './ui' 3 | 4 | // Api函数polyfill(目前为实验版本,如不需要,可删除!)'; 5 | import Polyfill from './polyfill/polyfill'; 6 | Polyfill.init(); 7 | 8 | // 全局mixins,用于实现setData等功能,请勿删除!'; 9 | import Mixin from './polyfill/mixins'; 10 | 11 | // #ifndef VUE3 12 | import Vue from 'vue'; 13 | 14 | Vue.mixin(Mixin); 15 | Vue.config.productionTip = false; 16 | App.mpType = 'app'; 17 | const app = new Vue({ 18 | ...App 19 | }); 20 | app.$mount(); 21 | // #endif 22 | 23 | // #ifdef VUE3 24 | import { createSSRApp } from 'vue'; 25 | export function createApp() { 26 | const app = createSSRApp(App); 27 | app.mixin(Mixin); 28 | return { 29 | app 30 | }; 31 | } 32 | // #endif 33 | -------------------------------------------------------------------------------- /manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name" : "微慕开源版", 3 | "appid" : "__UNI__308C881", 4 | "description" : "www.minapper.com", 5 | "versionName" : "1.0.0", 6 | "versionCode" : "100", 7 | "transformPx" : false, 8 | "app-plus" : { 9 | "usingComponents" : true, 10 | "nvueStyleCompiler" : "uni-app", 11 | "compilerVersion" : 3, 12 | "splashscreen" : { 13 | "alwaysShowBeforeRender" : true, 14 | "waiting" : true, 15 | "autoclose" : true, 16 | "delay" : 0 17 | }, 18 | "modules" : { 19 | "VideoPlayer" : {} 20 | }, 21 | "distribute" : { 22 | "android" : { 23 | "permissions" : [ 24 | "", 25 | "", 26 | "", 27 | "", 28 | "", 29 | "", 30 | "", 31 | "", 32 | "", 33 | "", 34 | "", 35 | "", 36 | "", 37 | "", 38 | "" 39 | ], 40 | "abiFilters" : [ "armeabi-v7a", "arm64-v8a", "x86" ] 41 | }, 42 | "ios" : {}, 43 | "sdkConfigs" : { 44 | "ad" : {} 45 | }, 46 | "icons" : { 47 | "android" : { 48 | "hdpi" : "unpackage/res/icons/72x72.png", 49 | "xhdpi" : "unpackage/res/icons/96x96.png", 50 | "xxhdpi" : "unpackage/res/icons/144x144.png", 51 | "xxxhdpi" : "unpackage/res/icons/192x192.png" 52 | }, 53 | "ios" : { 54 | "appstore" : "unpackage/res/icons/1024x1024.png", 55 | "ipad" : { 56 | "app" : "unpackage/res/icons/76x76.png", 57 | "app@2x" : "unpackage/res/icons/152x152.png", 58 | "notification" : "unpackage/res/icons/20x20.png", 59 | "notification@2x" : "unpackage/res/icons/40x40.png", 60 | "proapp@2x" : "unpackage/res/icons/167x167.png", 61 | "settings" : "unpackage/res/icons/29x29.png", 62 | "settings@2x" : "unpackage/res/icons/58x58.png", 63 | "spotlight" : "unpackage/res/icons/40x40.png", 64 | "spotlight@2x" : "unpackage/res/icons/80x80.png" 65 | }, 66 | "iphone" : { 67 | "app@2x" : "unpackage/res/icons/120x120.png", 68 | "app@3x" : "unpackage/res/icons/180x180.png", 69 | "notification@2x" : "unpackage/res/icons/40x40.png", 70 | "notification@3x" : "unpackage/res/icons/60x60.png", 71 | "settings@2x" : "unpackage/res/icons/58x58.png", 72 | "settings@3x" : "unpackage/res/icons/87x87.png", 73 | "spotlight@2x" : "unpackage/res/icons/80x80.png", 74 | "spotlight@3x" : "unpackage/res/icons/120x120.png" 75 | } 76 | } 77 | }, 78 | "splashscreen" : { 79 | "useOriginalMsgbox" : true 80 | } 81 | } 82 | }, 83 | "quickapp" : {}, 84 | "mp-weixin" : { 85 | "appid" : "wx39075d0bde24f9f7", 86 | "setting" : { 87 | "urlCheck" : false 88 | }, 89 | "usingComponents" : true, 90 | "permission" : { 91 | "scope.userLocation" : { 92 | "desc" : "你的位置信息将用于小程序位置接口的效果展示" 93 | } 94 | }, 95 | "plugins" : {}, 96 | "requiredBackgroundModes" : [ "audio", "location" ] 97 | }, 98 | "mp-alipay" : { 99 | "usingComponents" : true 100 | }, 101 | "mp-baidu" : { 102 | "usingComponents" : true 103 | }, 104 | "mp-toutiao" : { 105 | "usingComponents" : true 106 | }, 107 | "uniStatistics" : { 108 | "enable" : false 109 | }, 110 | "vueVersion" : "2", 111 | "networkTimeout" : { 112 | "request" : 10000, 113 | "connectSocket" : 10000, 114 | "uploadFile" : 10000, 115 | "downloadFile" : 10000 116 | }, 117 | "h5" : { 118 | "optimization" : { 119 | "treeShaking" : { 120 | "enable" : false 121 | } 122 | }, 123 | "router" : { 124 | "base" : "./" 125 | } 126 | } 127 | } 128 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "lb-tabbar", 3 | "name": "lb-tabbar自定义tabbar", 4 | "version": "v1.0.3", 5 | "description": "通用自定义tabbar,兼容App、H5、各小程序", 6 | "keywords": [ 7 | "tabbar" 8 | ] 9 | } -------------------------------------------------------------------------------- /pages.json: -------------------------------------------------------------------------------- 1 | { 2 | "pages": [ 3 | { 4 | "path": "pages/index/index", 5 | "style": { 6 | "enablePullDownRefresh": true, 7 | "navigationStyle": "custom" 8 | } 9 | }, 10 | { 11 | "path": "pages/about/about", 12 | "style": { 13 | "enablePullDownRefresh": true 14 | } 15 | }, 16 | { 17 | "path": "pages/comments/comments", 18 | "style": { 19 | "enablePullDownRefresh": true 20 | } 21 | }, 22 | { 23 | "path": "pages/detail/detail", 24 | "style": { 25 | "enablePullDownRefresh": false, 26 | "backgroundTextStyle": "dark" 27 | } 28 | }, 29 | { 30 | "path": "pages/hot/hot", 31 | "style": { 32 | "navigationBarTitleText": "文章排行" 33 | } 34 | }, 35 | { 36 | "path": "pages/logs/logs", 37 | "style": { 38 | "navigationBarTitleText": "查看启动日志" 39 | } 40 | }, 41 | { 42 | "path": "pages/list/list", 43 | "style": {} 44 | }, 45 | { 46 | "path": "pages/page/page", 47 | "style": {} 48 | }, 49 | { 50 | "path": "pages/pay/pay", 51 | "style": {} 52 | }, 53 | { 54 | "path": "pages/poster/poster", 55 | "style": {} 56 | }, 57 | { 58 | "path": "pages/readlog/readlog", 59 | "style": { 60 | "navigationBarTitleText": "" 61 | } 62 | }, 63 | { 64 | "path": "pages/search/search", 65 | "style": { 66 | "enablePullDownRefresh": true, 67 | "backgroundTextStyle": "dark" 68 | } 69 | }, 70 | { 71 | "path": "pages/topic/topic", 72 | "style": {} 73 | }, 74 | { 75 | "path": "pages/theme/theme", 76 | "style": { 77 | "navigationStyle": "custom" 78 | } 79 | }, 80 | { 81 | "path": "pages/webpage/webpage", 82 | "style": {} 83 | }, 84 | { 85 | "path": "pages/tags/tags", 86 | "style": {} 87 | }, 88 | { 89 | "path": "pages/my/my", 90 | "style": {} 91 | } 92 | ],"easycom": { 93 | "ui-(.*)": "@/ui/components/ui-$1/ui-$1.vue", 94 | "app-(.*)": "@/app/components/app-$1/app-$1.vue" 95 | }, 96 | "tabBar": { 97 | "color": "#959595", 98 | "selectedColor": "#118fff", 99 | "borderStyle": "white", 100 | "backgroundColor": "#ffffff", 101 | "list": [ 102 | { 103 | "pagePath": "pages/index/index", 104 | "text": " " 105 | }, 106 | { 107 | "pagePath": "pages/topic/topic", 108 | "text": " " 109 | }, 110 | { 111 | "pagePath": "pages/hot/hot", 112 | "text": " " 113 | }, 114 | { 115 | "pagePath": "pages/my/my", 116 | "text": " " 117 | } 118 | ] 119 | }, 120 | "requiredBackgroundModes": [ 121 | "audio", 122 | "location" 123 | ], 124 | "networkTimeout": { 125 | "request": 10000, 126 | "connectSocket": 10000, 127 | "uploadFile": 10000, 128 | "downloadFile": 10000 129 | }, 130 | "sitemapLocation": "sitemap.json", 131 | "resizable": false, 132 | "darkmode": true, 133 | "globalStyle": { 134 | "backgroundTextStyle": "light", 135 | "navigationBarBackgroundColor": "#fff", 136 | "navigationBarTextStyle": "black", 137 | "pageOrientation": "portrait", 138 | "navigationStyle": "custom" 139 | }, 140 | "subPackages": [] 141 | } -------------------------------------------------------------------------------- /pages/logs/logs.vue: -------------------------------------------------------------------------------- 1 | 29 | 30 | 58 | -------------------------------------------------------------------------------- /pages/page/page.vue: -------------------------------------------------------------------------------- 1 | 32 | 33 | 143 | -------------------------------------------------------------------------------- /pages/poster/poster.vue: -------------------------------------------------------------------------------- 1 | 36 | 37 | 130 | -------------------------------------------------------------------------------- /pages/system/system.vue: -------------------------------------------------------------------------------- 1 | 37 | 38 | 120 | 125 | -------------------------------------------------------------------------------- /pages/theme/theme.vue: -------------------------------------------------------------------------------- 1 | 14 | 15 | 25 | 38 | -------------------------------------------------------------------------------- /pages/webpage/webpage.vue: -------------------------------------------------------------------------------- 1 | 18 | 19 | 99 | -------------------------------------------------------------------------------- /polyfill/README.md: -------------------------------------------------------------------------------- 1 | # 关于polyfill目录 2 | 3 | 用于抹平各平台差异化,使小程序转换uniapp项目后,能尽可能的少报错,尽可能的先运行起来。 4 | 5 | ## 文件结构 6 | 7 | ### base64Binary.js 8 | 9 | 用于 base64ToArrayBuffer, arrayBufferToBase64 两个函数的polyfill,因为这两函数仅app与微信小程序支持,特意制作此polyfill。 10 | 11 | 主要用于polyfill.js文件。 12 | 13 | ### mixins.js 14 | 15 | 有两个用途: 16 | 一是在使用富文本时,可以将后台传入的富文本字符串里面的转义符转换为普通字符,与mp-html插件配合使用。 17 | 二是this.setData()函数的polyfill,使转换后的uniapp项目,可以直接使用setData函数。 18 | 19 | ### polyfill.js 20 | 21 | 此文件,对大量api进行判断,如果在当前平台,不支持此函数,将会创建一个空函数,并输出一条提示,提示开发者,这个api需针对性的进行兼容处理。 22 | 23 | 如果不处理的话,会直接进行报错,并影响流程的运行,对转换者的心理有一定的影响。 24 | 25 | 因此制作此polyfill,让项目能先运行起来~ 26 | 27 | 28 | ## 注意 29 | 30 | 如果觉得这些文件不需要想删除它,请一定要先阅读关于每个文件的说明,明白它的作用,再进行删除,以免项目运行报错,感谢合作~ 31 | 32 | 如有不明白的地方,请联系作者(375890534@qq.com)或qq群(780359397、361784059、603659851)进行交流~ 33 | 34 | zhangdaren 2021-07-21 35 | 36 | -------------------------------------------------------------------------------- /polyfill/base64Binary.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: zhang peng 3 | * @Date: 2021-08-03 10:57:51 4 | * @LastEditTime: 2021-08-16 17:25:43 5 | * @LastEditors: zhang peng 6 | * @Description: 7 | * @FilePath: \miniprogram-to-uniapp2\src\project\template\polyfill\base64Binary.js 8 | * 9 | * 借鉴自:https://github.com/dankogai/js-base64/blob/main/base64.js 10 | * 因uniapp没有window,也无法使用Buffer,因此直接使用polyfill 11 | * 12 | */ 13 | const b64ch = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=' 14 | const b64chs = [...b64ch] 15 | const b64re = /^(?:[A-Za-z\d+\/]{4})*?(?:[A-Za-z\d+\/]{2}(?:==)?|[A-Za-z\d+\/]{3}=?)?$/ 16 | const b64tab = ((a) => { 17 | let tab = {} 18 | a.forEach((c, i) => tab[c] = i) 19 | return tab 20 | })(b64chs) 21 | const _fromCC = String.fromCharCode.bind(String) 22 | 23 | /** 24 | * polyfill version of `btoa` 25 | */ 26 | const btoaPolyfill = (bin) => { 27 | // console.log('polyfilled'); 28 | let u32, c0, c1, c2, asc = '' 29 | const pad = bin.length % 3 30 | for (let i = 0;i < bin.length;) { 31 | if ((c0 = bin.charCodeAt(i++)) > 255 || 32 | (c1 = bin.charCodeAt(i++)) > 255 || 33 | (c2 = bin.charCodeAt(i++)) > 255) 34 | throw new TypeError('invalid character found') 35 | u32 = (c0 << 16) | (c1 << 8) | c2 36 | asc += b64chs[u32 >> 18 & 63] 37 | + b64chs[u32 >> 12 & 63] 38 | + b64chs[u32 >> 6 & 63] 39 | + b64chs[u32 & 63] 40 | } 41 | return pad ? asc.slice(0, pad - 3) + "===".substring(pad) : asc 42 | } 43 | 44 | /** 45 | * polyfill version of `atob` 46 | */ 47 | const atobPolyfill = (asc) => { 48 | // console.log('polyfilled'); 49 | asc = asc.replace(/\s+/g, '') 50 | if (!b64re.test(asc)) 51 | throw new TypeError('malformed base64.') 52 | asc += '=='.slice(2 - (asc.length & 3)) 53 | let u24, bin = '', r1, r2 54 | for (let i = 0;i < asc.length;) { 55 | u24 = b64tab[asc.charAt(i++)] << 18 56 | | b64tab[asc.charAt(i++)] << 12 57 | | (r1 = b64tab[asc.charAt(i++)]) << 6 58 | | (r2 = b64tab[asc.charAt(i++)]) 59 | bin += r1 === 64 ? _fromCC(u24 >> 16 & 255) 60 | : r2 === 64 ? _fromCC(u24 >> 16 & 255, u24 >> 8 & 255) 61 | : _fromCC(u24 >> 16 & 255, u24 >> 8 & 255, u24 & 255) 62 | } 63 | return bin 64 | } 65 | 66 | /** 67 | * base64转ArrayBuffer 68 | */ 69 | function base64ToArrayBuffer (base64) { 70 | const binaryStr = atobPolyfill(base64) 71 | const byteLength = binaryStr.length 72 | const bytes = new Uint8Array(byteLength) 73 | for (let i = 0;i < byteLength;i++) { 74 | bytes[i] = binary.charCodeAt(i) 75 | } 76 | return bytes.buffer 77 | } 78 | 79 | /** 80 | * ArrayBuffer转base64 81 | */ 82 | function arrayBufferToBase64 (buffer) { 83 | let binaryStr = "" 84 | const bytes = new Uint8Array(buffer) 85 | var len = bytes.byteLength 86 | for (let i = 0;i < len;i++) { 87 | binaryStr += String.fromCharCode(bytes[i]) 88 | } 89 | return btoaPolyfill(binaryStr) 90 | } 91 | 92 | module.exports = { 93 | base64ToArrayBuffer, 94 | arrayBufferToBase64, 95 | } 96 | -------------------------------------------------------------------------------- /polyfill/mixins.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: zhang peng 3 | * @Date: 2021-08-03 10:57:51 4 | * @LastEditTime: 2021-10-15 20:27:53 5 | * @LastEditors: zhang peng 6 | * @Description: 7 | * @FilePath: \miniprogram-to-uniapp2\src\project\template\polyfill\mixins.js 8 | * 9 | * 如果你想删除本文件,请先确认它使用的范围,感谢合作~ 10 | * 如有疑问,请直接联系: 375890534@qq.com 11 | */ 12 | export default { 13 | methods: { 14 | /** 15 | * 转义符换成普通字符 16 | * @param {*} str 17 | * @returns 18 | */ 19 | escape2Html (str) { 20 | if (!str) return str 21 | var arrEntities = { 22 | 'lt': '<', 23 | 'gt': '>', 24 | 'nbsp': ' ', 25 | 'amp': '&', 26 | 'quot': '"' 27 | } 28 | return str.replace(/&(lt|gt|nbsp|amp|quot);/ig, function (all, t) { 29 | return arrEntities[t] 30 | }) 31 | }, 32 | /** 33 | * 普通字符转换成转义符 34 | * @param {*} sHtml 35 | * @returns 36 | */ 37 | html2Escape (sHtml) { 38 | if (!sHtml) return sHtml 39 | return sHtml.replace(/[<>&"]/g, function (c) { 40 | return { 41 | '<': '<', 42 | '>': '>', 43 | '&': '&', 44 | '"': '"' 45 | }[c] 46 | }) 47 | }, 48 | /** 49 | * setData polyfill 勿删!!! 50 | * 用于转换后的uniapp的项目能直接使用this.setData()函数 51 | * @param {*} obj 52 | * @param {*} callback 53 | */ 54 | setData: function (obj, callback) { 55 | let that = this 56 | const handleData = (tepData, tepKey, afterKey) => { 57 | var tepData2 = tepData 58 | tepKey = tepKey.split('.') 59 | tepKey.forEach(item => { 60 | if (tepData[item] === null || tepData[item] === undefined) { 61 | let reg = /^[0-9]+$/ 62 | tepData[item] = reg.test(afterKey) ? [] : {} 63 | tepData2 = tepData[item] 64 | } else { 65 | tepData2 = tepData[item] 66 | } 67 | }) 68 | return tepData2 69 | } 70 | const isFn = function (value) { 71 | return typeof value == 'function' || false 72 | } 73 | Object.keys(obj).forEach(function (key) { 74 | let val = obj[key] 75 | key = key.replace(/\]/g, '').replace(/\[/g, '.') 76 | let front, after 77 | let index_after = key.lastIndexOf('.') 78 | if (index_after != -1) { 79 | after = key.slice(index_after + 1) 80 | front = handleData(that, key.slice(0, index_after), after) 81 | } else { 82 | after = key 83 | front = that 84 | } 85 | if (front.$data && front.$data[after] === undefined) { 86 | Object.defineProperty(front, after, { 87 | get () { 88 | return front.$data[after] 89 | }, 90 | set (newValue) { 91 | front.$data[after] = newValue 92 | that.hasOwnProperty("$forceUpdate") && that.$forceUpdate() 93 | }, 94 | enumerable: true, 95 | configurable: true 96 | }) 97 | front[after] = val 98 | } else { 99 | that.$set(front, after, val) 100 | } 101 | }) 102 | // this.$forceUpdate(); 103 | isFn(callback) && this.$nextTick(callback) 104 | }, 105 | /** 106 | * 解析事件里的动态函数名,这种没有()的函数名,在uniapp不被执行 107 | * 比如:立即 108 | * @param {*} exp 109 | */ 110 | parseEventDynamicCode (exp) { 111 | if (typeof (eval("this." + exp)) === 'function') { 112 | eval("this." + exp + '()') 113 | } 114 | }, 115 | /** 116 | * 用于处理对props进行赋值的情况 117 | * //简单处理一下就行了 118 | * 119 | * @param {*} target 120 | * @returns 121 | */ 122 | deepClone (target) { 123 | //判断拷贝的要进行深拷贝的是数组还是对象,是数组的话进行数组拷贝,对象的话进行对象拷贝 124 | // const toString = Object.prototype.toString 125 | // toString.call(obj) === '[object Array]' ? clone = clone || [] : clone = clone || {} 126 | // for (const i in obj) { 127 | // if (typeof obj[i] === 'object' && obj[i]!==null) { 128 | // // 要考虑深复制问题了 129 | // if (Array.isArray(obj[i])) { 130 | // // 这是数组 131 | // clone[i] = [] 132 | // } else { 133 | // // 这是对象 134 | // clone[i] = {} 135 | // } 136 | // deepClone(obj[i], clone[i]) 137 | // } else { 138 | // clone[i] = obj[i] 139 | // } 140 | // } 141 | // return clone 142 | return JSON.parse(JSON.stringify(obj)) 143 | } 144 | } 145 | } 146 | -------------------------------------------------------------------------------- /project.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "description": "项目配置文件。", 3 | "setting": { 4 | "urlCheck": false, 5 | "es6": true, 6 | "enhance": true, 7 | "postcss": true, 8 | "preloadBackgroundData": false, 9 | "minified": true, 10 | "newFeature": true, 11 | "coverView": true, 12 | "nodeModules": true, 13 | "autoAudits": false, 14 | "showShadowRootInWxmlPanel": true, 15 | "scopeDataCheck": false, 16 | "uglifyFileName": true, 17 | "checkInvalidKey": true, 18 | "checkSiteMap": true, 19 | "uploadWithSourceMap": true, 20 | "compileHotReLoad": false, 21 | "lazyloadPlaceholderEnable": false, 22 | "useMultiFrameRuntime": true, 23 | "useApiHook": true, 24 | "useApiHostProcess": true, 25 | "babelSetting": { 26 | "ignore": [], 27 | "disablePlugins": [], 28 | "outputPath": "" 29 | }, 30 | "enableEngineNative": false, 31 | "useIsolateContext": true, 32 | "userConfirmedBundleSwitch": false, 33 | "packNpmManually": false, 34 | "packNpmRelationList": [], 35 | "minifyWXSS": true, 36 | "disableUseStrict": false, 37 | "minifyWXML": true, 38 | "showES6CompileOption": false, 39 | "useCompilerPlugins": [ 40 | "sass" 41 | ] 42 | }, 43 | "compileType": "miniprogram", 44 | "libVersion": "2.21.3", 45 | "appid": "wx39075d0bde24f9f7", 46 | "projectname": "www.watch-life.net", 47 | "simulatorType": "wechat", 48 | "simulatorPluginLibVersion": {}, 49 | "condition": { 50 | "search": { 51 | "list": [ 52 | { 53 | "name": "test", 54 | "pathName": "", 55 | "title": "", 56 | "cacheKey": "" 57 | } 58 | ] 59 | }, 60 | "conversation": { 61 | "list": [ 62 | { 63 | "name": "test", 64 | "query": "", 65 | "boxQI": "", 66 | "service": {} 67 | } 68 | ] 69 | }, 70 | "plugin": { 71 | "list": [] 72 | }, 73 | "game": { 74 | "list": [] 75 | }, 76 | "miniprogram": { 77 | "list": [ 78 | { 79 | "id": -1, 80 | "name": "评论", 81 | "pathName": "pages/comments/comments", 82 | "query": "", 83 | "scene": null 84 | }, 85 | { 86 | "id": -1, 87 | "name": "专题页", 88 | "pathName": "pages/topic/topic", 89 | "query": "", 90 | "scene": null 91 | }, 92 | { 93 | "id": -1, 94 | "name": "我的", 95 | "pathName": "pages/readlog/readlog", 96 | "query": "", 97 | "scene": null 98 | }, 99 | { 100 | "id": -1, 101 | "name": "文章详情", 102 | "pathName": "pages/detail/detail", 103 | "query": "id=1553", 104 | "scene": null 105 | } 106 | ] 107 | } 108 | } 109 | } -------------------------------------------------------------------------------- /project.private.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "setting": {}, 3 | "condition": { 4 | "plugin": { 5 | "list": [] 6 | }, 7 | "game": { 8 | "list": [] 9 | }, 10 | "gamePlugin": { 11 | "list": [] 12 | }, 13 | "miniprogram": { 14 | "list": [ 15 | { 16 | "id": -1, 17 | "name": "评论", 18 | "pathName": "pages/comments/comments", 19 | "query": "", 20 | "scene": null 21 | }, 22 | { 23 | "id": -1, 24 | "name": "专题页", 25 | "pathName": "pages/topic/topic", 26 | "query": "", 27 | "scene": null 28 | }, 29 | { 30 | "name": "我的", 31 | "pathName": "pages/readlog/readlog", 32 | "query": "key=2", 33 | "scene": null 34 | }, 35 | { 36 | "id": -1, 37 | "name": "文章详情", 38 | "pathName": "pages/detail/detail", 39 | "query": "id=1553", 40 | "scene": null 41 | }, 42 | { 43 | "name": "", 44 | "pathName": "pages/theme/theme", 45 | "query": "", 46 | "scene": null 47 | }, 48 | { 49 | "name": "", 50 | "pathName": "pages/pages/pages", 51 | "query": "", 52 | "scene": null 53 | }, 54 | { 55 | "name": "", 56 | "pathName": "pages/detail/detail", 57 | "query": "id=1909", 58 | "scene": null 59 | }, 60 | { 61 | "name": "", 62 | "pathName": "pages/my/my", 63 | "query": "", 64 | "scene": null, 65 | "partialCompile": { 66 | "enabled": true, 67 | "pages": [] 68 | } 69 | } 70 | ] 71 | } 72 | } 73 | } -------------------------------------------------------------------------------- /sitemap.json: -------------------------------------------------------------------------------- 1 | { 2 | "rules": [ 3 | { 4 | "action": "allow", 5 | "page": "pages/detail/detail", 6 | "params": ["id"], 7 | "matching": "inclusive" 8 | }, 9 | { 10 | "action": "allow", 11 | "page": "pages/list/list", 12 | "params": ["categoryID"], 13 | "matching": "inclusive" 14 | }, 15 | { 16 | "action": "allow", 17 | "page": "pages/index/index" 18 | }, 19 | { 20 | "action": "allow", 21 | "page": "pages/about/about" 22 | } 23 | ] 24 | } -------------------------------------------------------------------------------- /static/images/gravatar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/poisonboy/wordpressuniapp/86ad3d1869aa67b920cdb90592085324dc7afb0d/static/images/gravatar.png -------------------------------------------------------------------------------- /static/images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/poisonboy/wordpressuniapp/86ad3d1869aa67b920cdb90592085324dc7afb0d/static/images/logo.png -------------------------------------------------------------------------------- /static/images/logo700.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/poisonboy/wordpressuniapp/86ad3d1869aa67b920cdb90592085324dc7afb0d/static/images/logo700.png -------------------------------------------------------------------------------- /static/images/website-search.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/poisonboy/wordpressuniapp/86ad3d1869aa67b920cdb90592085324dc7afb0d/static/images/website-search.png -------------------------------------------------------------------------------- /static/images/website.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/poisonboy/wordpressuniapp/86ad3d1869aa67b920cdb90592085324dc7afb0d/static/images/website.png -------------------------------------------------------------------------------- /ui/components/ui-avatar-stack/ui-avatar-stack.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 24 | 25 | 35 | -------------------------------------------------------------------------------- /ui/components/ui-card/ui-card.vue: -------------------------------------------------------------------------------- 1 | 26 | 27 | 78 | 79 | 132 | -------------------------------------------------------------------------------- /ui/components/ui-change-theme/ui-change-theme.vue: -------------------------------------------------------------------------------- 1 | 57 | 58 | 89 | 90 | 130 | -------------------------------------------------------------------------------- /ui/components/ui-checkbox-group/ui-checkbox-group.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 100 | 101 | 102 | -------------------------------------------------------------------------------- /ui/components/ui-checkbox/ui-checkbox.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 116 | 117 | 172 | -------------------------------------------------------------------------------- /ui/components/ui-code/ui-code.vue: -------------------------------------------------------------------------------- 1 | 17 | 18 | 106 | 107 | 109 | -------------------------------------------------------------------------------- /ui/components/ui-color-picker/ui-color-picker.vue: -------------------------------------------------------------------------------- 1 | 18 | 19 | 76 | 77 | 83 | -------------------------------------------------------------------------------- /ui/components/ui-fixed/ui-fixed.vue: -------------------------------------------------------------------------------- 1 | 32 | 33 | 168 | 169 | 195 | -------------------------------------------------------------------------------- /ui/components/ui-form-group/ui-form-group.vue: -------------------------------------------------------------------------------- 1 | 12 | 13 | 76 | 77 | 145 | -------------------------------------------------------------------------------- /ui/components/ui-form/ui-form.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /ui/components/ui-img/ui-img.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 139 | 140 | 181 | -------------------------------------------------------------------------------- /ui/components/ui-loading/ui-loading.vue: -------------------------------------------------------------------------------- 1 | 16 | 17 | 55 | 56 | 167 | -------------------------------------------------------------------------------- /ui/components/ui-menu-item/ui-menu-item.vue: -------------------------------------------------------------------------------- 1 | 22 | 23 | 67 | 68 | 71 | -------------------------------------------------------------------------------- /ui/components/ui-menu/ui-menu.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 51 | 52 | 57 | -------------------------------------------------------------------------------- /ui/components/ui-progress/ui-progress.vue: -------------------------------------------------------------------------------- 1 | 14 | 15 | 86 | 87 | 173 | -------------------------------------------------------------------------------- /ui/components/ui-radio-group/ui-radio-group.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 66 | 67 | 68 | -------------------------------------------------------------------------------- /ui/components/ui-stepper/ui-stepper.vue: -------------------------------------------------------------------------------- 1 | 12 | 13 | 107 | 108 | 121 | -------------------------------------------------------------------------------- /ui/components/ui-steps/ui-steps.vue: -------------------------------------------------------------------------------- 1 | 17 | 18 | 67 | 68 | 241 | -------------------------------------------------------------------------------- /ui/components/ui-switch/ui-switch.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 60 | 61 | 106 | -------------------------------------------------------------------------------- /ui/components/ui-sys/ui-sys.vue: -------------------------------------------------------------------------------- 1 | 40 | 41 | 128 | 129 | 190 | -------------------------------------------------------------------------------- /ui/components/ui-tab-item/ui-tab-item.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 69 | 70 | 96 | -------------------------------------------------------------------------------- /ui/components/ui-tabbar/ui-tabbar.vue: -------------------------------------------------------------------------------- 1 | 19 | 20 | 107 | 108 | 170 | -------------------------------------------------------------------------------- /ui/components/ui-table/csv.js: -------------------------------------------------------------------------------- 1 | /* 2 | inspired by https://www.npmjs.com/package/react-csv-downloader 3 | now removed from Github 4 | */ 5 | 6 | const newLine = '\r\n'; 7 | const appendLine = (content, row, { separator, quoted }) => { 8 | const line = row.map(data => { 9 | if (!quoted) return data; 10 | // quote data 11 | data = typeof data === 'string' ? data.replace(/"/g, '"') : data; 12 | return `"${data}"`; 13 | }); 14 | content.push(line.join(separator)); 15 | }; 16 | 17 | const defaults = { 18 | separator: ',', 19 | quoted: false 20 | }; 21 | 22 | export default function csv(columns, datas, options, noHeader = false) { 23 | options = Object.assign({}, defaults, options); 24 | let columnOrder; 25 | const content = []; 26 | const column = []; 27 | 28 | if (columns) { 29 | columnOrder = columns.map(v => { 30 | if (typeof v === 'string') return v; 31 | if (!noHeader) { 32 | column.push(typeof v.title !== 'undefined' ? v.title : v.key); 33 | } 34 | return v.key; 35 | }); 36 | if (column.length > 0) appendLine(content, column, options); 37 | } else { 38 | columnOrder = []; 39 | datas.forEach(v => { 40 | if (!Array.isArray(v)) { 41 | columnOrder = columnOrder.concat(Object.keys(v)); 42 | } 43 | }); 44 | if (columnOrder.length > 0) { 45 | columnOrder = columnOrder.filter((value, index, self) => self.indexOf(value) === index); 46 | if (!noHeader) appendLine(content, columnOrder, options); 47 | } 48 | } 49 | 50 | if (Array.isArray(datas)) { 51 | datas.forEach(row => { 52 | if (!Array.isArray(row)) { 53 | row = columnOrder.map(k => (typeof row[k] !== 'undefined' ? row[k] : '')); 54 | } 55 | appendLine(content, row, options); 56 | }); 57 | } 58 | return content.join(newLine); 59 | } 60 | -------------------------------------------------------------------------------- /ui/components/ui-table/export-csv.js: -------------------------------------------------------------------------------- 1 | function has (browser) { 2 | const ua = navigator.userAgent; 3 | if (browser === 'ie') { 4 | const isIE = ua.indexOf('compatible') > -1 && ua.indexOf('MSIE') > -1; 5 | if (isIE) { 6 | const reIE = new RegExp('MSIE (\\d+\\.\\d+);'); 7 | reIE.test(ua); 8 | return parseFloat(RegExp['$1']); 9 | } else { 10 | return false; 11 | } 12 | } else { 13 | return ua.indexOf(browser) > -1; 14 | } 15 | } 16 | 17 | const csv = { 18 | _isIE11 () { 19 | let iev = 0; 20 | const ieold = (/MSIE (\d+\.\d+);/.test(navigator.userAgent)); 21 | const trident = !!navigator.userAgent.match(/Trident\/7.0/); 22 | const rv = navigator.userAgent.indexOf('rv:11.0'); 23 | 24 | if (ieold) { 25 | iev = Number(RegExp.$1); 26 | } 27 | if (navigator.appVersion.indexOf('MSIE 10') !== -1) { 28 | iev = 10; 29 | } 30 | if (trident && rv !== -1) { 31 | iev = 11; 32 | } 33 | 34 | return iev === 11; 35 | }, 36 | 37 | _isEdge () { 38 | return /Edge/.test(navigator.userAgent); 39 | }, 40 | 41 | _getDownloadUrl (text) { 42 | const BOM = '\uFEFF'; 43 | // Add BOM to text for open in excel correctly 44 | if (window.Blob && window.URL && window.URL.createObjectURL) { 45 | const csvData = new Blob([BOM + text], { type: 'text/csv' }); 46 | return URL.createObjectURL(csvData); 47 | } else { 48 | return 'data:attachment/csv;charset=utf-8,' + BOM + encodeURIComponent(text); 49 | } 50 | }, 51 | 52 | download (filename, text) { 53 | if (has('ie') && has('ie') < 10) { 54 | // has module unable identify ie11 and Edge 55 | const oWin = window.top.open('about:blank', '_blank'); 56 | oWin.document.charset = 'utf-8'; 57 | oWin.document.write(text); 58 | oWin.document.close(); 59 | oWin.document.execCommand('SaveAs', filename); 60 | oWin.close(); 61 | } else if (has('ie') === 10 || this._isIE11() || this._isEdge()) { 62 | const BOM = '\uFEFF'; 63 | const csvData = new Blob([BOM + text], { type: 'text/csv' }); 64 | navigator.msSaveBlob(csvData, filename); 65 | } else { 66 | const link = document.createElement('a'); 67 | link.download = filename; 68 | link.href = this._getDownloadUrl(text); 69 | document.body.appendChild(link); 70 | link.click(); 71 | document.body.removeChild(link); 72 | } 73 | } 74 | }; 75 | 76 | export default csv; -------------------------------------------------------------------------------- /ui/components/ui-tag/ui-tag.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 47 | 48 | 146 | -------------------------------------------------------------------------------- /ui/components/ui-text-size/ui-text-size.vue: -------------------------------------------------------------------------------- 1 | 16 | 17 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /ui/components/ui-toast/ui-toast.vue: -------------------------------------------------------------------------------- 1 | 13 | 14 | 82 | 83 | 142 | -------------------------------------------------------------------------------- /ui/index.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import store from '@/ui/store' 3 | import modal from '@/ui/js/modal.js' 4 | import request from '@/ui/js/request.js' 5 | import util from '@/ui/js/util.js' 6 | import mixin from '@/ui/js/mixin.js' 7 | import app from "@/app/index.js" 8 | 9 | if (uni.getStorageSync("VUE_APP_NAME") != process.env.VUE_APP_NAME) { 10 | uni.clearStorage(); 11 | uni.setStorageSync('VUE_APP_NAME', process.env.VUE_APP_NAME); 12 | } 13 | 14 | /*分析主题*/ 15 | var theme = uni.getStorageSync("sys_theme"); 16 | var main = uni.getStorageSync("sys_main"); 17 | var text = uni.getStorageSync("sys_text"); 18 | 19 | if (!theme) { 20 | theme = store.getters.getCustomTheme; 21 | } 22 | if (!main) { 23 | main = store.getters.getCustomMain; 24 | } 25 | if (!text) { 26 | text = store.getters.getCustomText; 27 | } 28 | store.commit('setTheme', theme); 29 | store.commit('setMain', main); 30 | store.commit('setText', text); 31 | -------------------------------------------------------------------------------- /ui/js/mixin.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import { 3 | mapState 4 | } from 'vuex'; 5 | const mixin = { 6 | data() { 7 | return { 8 | _uid: this._uid, //vue实例id 9 | sys_scrollTop: 0, //实例所在页面滚动值 10 | sys_atPage: true, //实例是否在页面里显示 11 | sys_layer: 0, //实例层级 12 | slots:{} 13 | }; 14 | }, 15 | watch: { 16 | 17 | }, 18 | computed: { 19 | ...mapState({ 20 | sys_theme: state => state.sys_theme, 21 | sys_main: state => state.sys_main, 22 | sys_info: state => state.sys_info, 23 | sys_text: state => state.sys_text, 24 | sys_statusBar: state => state.sys_statusBar, 25 | sys_homePath: state => state.app.homePath 26 | }), 27 | sys_navBar() { 28 | return this.$store.getters.sys_navBar 29 | }, 30 | sys_capsule() { 31 | return this.$store.getters.sys_capsule 32 | }, 33 | sys_isFirstPage() { 34 | //实例是否为路由栈的第一个页面 35 | let pages = getCurrentPages(); 36 | return pages.length == 1 37 | }, 38 | isPc(){ 39 | return uni.getSystemInfoSync().windowWidth > 750 40 | } 41 | }, 42 | created() { 43 | if (this._uid != this.$root._uid) { 44 | this._onShow(); 45 | } 46 | if (this.$parent) { 47 | this.sys_layer = (this.$parent.sys_layer ? this.$parent.sys_layer : 0) + 1 48 | } 49 | }, 50 | onLoad() { 51 | 52 | 53 | }, 54 | onShow() { 55 | uni.$emit('_onShow_' + this._uid); 56 | }, 57 | onReachBottom() { 58 | uni.$emit('_onReachBottom_' + this._uid); 59 | }, 60 | mounted() { 61 | uni.$on('_onShow_' + this.$root._uid, () => { 62 | this._onShow(); 63 | }) 64 | uni.$on('_onHide_' + this.$root._uid, () => { 65 | this._onHide(); 66 | }) 67 | uni.$on('_onReachBottom_' + this.$root._uid, () => { 68 | this._onReachBottom(); 69 | }) 70 | this.slots=this.$scopedSlots 71 | }, 72 | onReady() { 73 | this._h5SetScrollTop(); 74 | // // #ifdef H5 75 | // this.sys_isFirstPage = window.history.length <= 1; 76 | // // #endif 77 | // // #ifndef H5 78 | // // #endif 79 | 80 | }, 81 | onShow() { 82 | this._h5SetScrollTop(); 83 | }, 84 | onHide() { 85 | uni.$emit('_onHide_' + this._uid); 86 | }, 87 | destroyed() { 88 | uni.$off('_onShow_' + this._uid); 89 | uni.$off('_onHide_' + this._uid); 90 | this.sys_atPage = false; 91 | }, 92 | onPageScroll(e) { 93 | this.sys_scrollTop = e.scrollTop; 94 | uni.$emit('_scrollTop_' + this._uid, e.scrollTop) 95 | if (e.scrollTop < 0) { 96 | return false 97 | } 98 | }, 99 | methods: { 100 | _h5SetScrollTop(){ 101 | this.$nextTick(function() { 102 | // #ifdef H5 103 | // 刷新后保持导航栏位置x 104 | let top = window.pageYOffset || document.body.scrollTop || document.documentElement.scrollTop 105 | this.sys_scrollTop = top; 106 | uni.$emit('_scrollTop_' + this.$root._uid, top); 107 | // #endif 108 | uni.$emit('_hideLoading_' + this.$root._uid, false); 109 | }); 110 | }, 111 | _onShow() { 112 | this.sys_atPage = true; 113 | // console.log('component: ' + this._uid + ' onShow in '+ this.$root._uid); 114 | }, 115 | _onReachBottom() {}, 116 | _onHide() { 117 | this.sys_atPage = false; 118 | // console.log('component: ' + this._uid + ' onHide in '+ this.$root._uid); 119 | }, 120 | _backPage() { 121 | if (this.sys_isFirstPage) { 122 | this._toHome(); 123 | } else { 124 | // #ifdef H5 125 | window.history.back(); 126 | // #endif 127 | 128 | // #ifndef H5 129 | uni.navigateBack({ 130 | delta: 1, 131 | fail(res) { 132 | console.log(res); 133 | } 134 | }); 135 | 136 | // #endif 137 | } 138 | }, 139 | _toHome() { 140 | uni.switchTab({ 141 | url: this.sys_homePath, 142 | fail(res) { 143 | console.log(res); 144 | } 145 | }); 146 | }, 147 | _has(data,str) { 148 | return data.indexOf(str) != -1 149 | }, 150 | _to(url, type = '') { 151 | switch (type) { 152 | case 'switchTab': 153 | uni.switchTab({ 154 | url: url, 155 | fail(res) { 156 | console.log(res); 157 | } 158 | }); 159 | break; 160 | case 'reLaunch': 161 | uni.reLaunch({ 162 | url: url, 163 | success(res) { 164 | console.log(res); 165 | }, 166 | fail(res) { 167 | console.log(res); 168 | } 169 | }); 170 | break; 171 | case 'redirectTo': 172 | uni.redirectTo({ 173 | url: url, 174 | fail(res) { 175 | console.log(res); 176 | } 177 | }); 178 | break; 179 | default: 180 | uni.navigateTo({ 181 | url: url, 182 | fail(res) { 183 | console.log(res); 184 | } 185 | }) 186 | break; 187 | } 188 | }, 189 | _getParent(name) { 190 | let parent = this.$parent; 191 | if (parent) { 192 | let parentName = parent.$options.name; 193 | while (parentName !== name) { 194 | parent = parent.$parent; 195 | if (parent) { 196 | parentName = parent.$options.name; 197 | } else { 198 | return null; 199 | } 200 | } 201 | return parent; 202 | } 203 | return null; 204 | }, 205 | } 206 | } 207 | 208 | export default mixin 209 | Vue.mixin(mixin) 210 | -------------------------------------------------------------------------------- /ui/js/modal.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import store from '@/ui/store' 3 | const modal = { 4 | show(name) { 5 | store.commit('setTarget', name); 6 | }, 7 | hide() { 8 | store.commit('setTarget', ''); 9 | }, 10 | dialog(dialog) { 11 | store.commit('setDialog', dialog); 12 | }, 13 | tips(title,duration=1500) { 14 | store.commit('setToast', {title:title,duration:duration}); 15 | }, 16 | toast(toast) { 17 | store.commit('setToast', toast); 18 | }, 19 | success(title='成功',duration=1500) { 20 | store.commit('setToast', {icon:'_icon-check',title:title,duration:duration}); 21 | }, 22 | error(title='错误',duration=1500) { 23 | store.commit('setToast', {icon:'_icon-warn',title:title,duration:duration}); 24 | }, 25 | loading(title='加载中') { 26 | store.commit('setToast', {icon:'_icon-loading',title:title,isLoading:true}); 27 | }, 28 | hideloading() { 29 | store.commit('setToast', {title:'',isLoading:false}); 30 | }, 31 | } 32 | 33 | Vue.prototype.$Modal = modal 34 | Vue.prototype.$Tips = modal.tips 35 | Vue.prototype.$Toast = modal.toast 36 | Vue.prototype.$Success = modal.success 37 | Vue.prototype.$Error = modal.error 38 | Vue.prototype.$Loading = modal.loading 39 | Vue.prototype.$HideLoading = modal.hideloading 40 | export default modal 41 | -------------------------------------------------------------------------------- /ui/js/request.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import store from '@/ui/store' 3 | 4 | function request(url, data = {}, method = "GET") { 5 | return new Promise(function(resolve, reject) { 6 | let header = { 7 | "Accept": "application/json", 8 | }; 9 | if (uni.getStorageSync("token")) { 10 | header['Authorization'] = 'Bearer ' + uni.getStorageSync("token") 11 | } 12 | uni.request({ 13 | url: store.getters.getDomain+ store.getters.getApiPath + url, 14 | data: data, 15 | method: method, 16 | header: header, 17 | success(res) { 18 | if (res.statusCode == 200) { 19 | if (res.data.code == 401) { 20 | uni.showToast({ 21 | title: res.data.msg, 22 | icon: 'none' 23 | }) 24 | setTimeout(() => { 25 | uni.removeStorageSync('token'); 26 | store.commit('setLogin', false); 27 | uni.reLaunch({ 28 | url: '/pages/login/login' 29 | }); 30 | }, 1500) 31 | } 32 | if (res.data.code == 200) { 33 | resolve(res.data); 34 | } else { 35 | reject(res.data) 36 | uni.showToast({ 37 | title: res.data.msg, 38 | icon: 'none' 39 | }) 40 | uni.hideLoading(); 41 | } 42 | } else { 43 | if (res.statusCode == 401) { 44 | uni.showToast({ 45 | title: res.message, 46 | icon: 'none' 47 | }) 48 | setTimeout(() => { 49 | uni.removeStorageSync('token'); 50 | store.commit('setLogin', false); 51 | uni.reLaunch({ 52 | url: '/pages/login/login' 53 | }); 54 | }, 1500) 55 | } else { 56 | reject(res.data) 57 | uni.showToast({ 58 | title: 'Network Error', 59 | icon: 'none' 60 | }) 61 | uni.hideLoading(); 62 | } 63 | } 64 | }, 65 | fail(err) { 66 | console.log(err) 67 | reject(err) 68 | } 69 | }) 70 | }); 71 | } 72 | 73 | Vue.prototype.$request = request 74 | export default request 75 | -------------------------------------------------------------------------------- /ui/js/toast.js: -------------------------------------------------------------------------------- 1 | import store from '@/ui/store' 2 | const toast = (content)=>{ 3 | store.commit('setDialog', content); 4 | } 5 | 6 | export default toast -------------------------------------------------------------------------------- /ui/js/util.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | /** 3 | * getUuid 生成唯一id 4 | */ 5 | function getUuid() { 6 | return Number(Math.random().toString().substr(3, 3) + Date.now() * Math.random()).toString(36) 7 | } 8 | 9 | /** 10 | * getColor 随机生成库内颜色名 11 | */ 12 | function getColor() { 13 | let colorArr = ['yellow', 'orange', 'red', 'pink', 'mauve', 'purple', 'blue', 'cyan', 'green', 'olive', 'grey', 14 | 'brown' 15 | ]; 16 | return colorArr[Math.floor(Math.random() * colorArr.length)] 17 | } 18 | 19 | /** 20 | * showTips 显示系统提示 21 | */ 22 | function showTips(msg) { 23 | uni.showToast({ 24 | title: msg, 25 | icon: 'none' 26 | }) 27 | } 28 | 29 | /** 30 | * copyText 多端复制文本 31 | */ 32 | function copyText(text) { 33 | // #ifndef H5 34 | uni.setClipboardData({ 35 | data: text, 36 | success: function() { 37 | showTips('复制成功!') 38 | }, 39 | fail: function() { 40 | showTips('复制失败!') 41 | }, 42 | }); 43 | // #endif 44 | // #ifdef H5 45 | var createInput = document.createElement('textarea'); 46 | createInput.value = text; 47 | document.body.appendChild(createInput); 48 | createInput.select(); 49 | document.execCommand('Copy'); 50 | createInput.className = 'createInput'; 51 | createInput.style.display = 'none'; 52 | showTips('复制成功!') 53 | // #endif 54 | } 55 | const util = { 56 | getUuid, 57 | getColor, 58 | showTips, 59 | copyText 60 | } 61 | export default util 62 | 63 | Vue.prototype.$util = util; 64 | -------------------------------------------------------------------------------- /ui/scss/_mixins.scss: -------------------------------------------------------------------------------- 1 | @mixin bg-square { 2 | background: { 3 | color: #fff; 4 | image: linear-gradient(45deg, #eee 25%, transparent 25%, transparent 75%, #eee 75%), linear-gradient(45deg, #eee 25%, transparent 25%, transparent 75%, #eee 75%); 5 | size: 40rpx 40rpx; 6 | position: 0 0, 20rpx 20rpx; 7 | } 8 | } 9 | 10 | @mixin flex { 11 | position: relative; 12 | display: flex; 13 | align-items: center; 14 | } 15 | @mixin flex-bar { 16 | position: relative; 17 | display: flex; 18 | align-items: center; 19 | justify-content: space-between; 20 | } 21 | @mixin flex-center { 22 | display: flex; 23 | align-items: center; 24 | justify-content: center; 25 | } 26 | 27 | @mixin arrow { 28 | content: ''; 29 | height: 0; 30 | width: 0; 31 | position: absolute; 32 | } 33 | @mixin arrow-top { 34 | @include arrow; 35 | // border-color: transparent transparent $ui-BG; 36 | border-style: none solid solid; 37 | border-width: 0 20rpx 20rpx; 38 | } 39 | 40 | @mixin arrow-right { 41 | @include arrow; 42 | // border-color: transparent $ui-BG transparent; 43 | border-style: solid solid solid none; 44 | border-width: 20rpx 20rpx 20rpx 0; 45 | } 46 | @mixin position-center { 47 | position: absolute !important; 48 | top: 0; 49 | right: 0; 50 | bottom: 0; 51 | left: 0; 52 | margin: auto; 53 | } 54 | 55 | @mixin blur { 56 | -webkit-backdrop-filter: blur(20px); 57 | backdrop-filter: blur(20px); 58 | color: var(--ui-TC); 59 | } 60 | -------------------------------------------------------------------------------- /ui/scss/_var.scss: -------------------------------------------------------------------------------- 1 | @import '@/app/scss/var'; 2 | @import '@/ui/scss/mixins'; -------------------------------------------------------------------------------- /ui/scss/icon/_style.scss: -------------------------------------------------------------------------------- 1 | 2 | @import './icon'; //核心图标库 3 | @import '@/app/scss/icon/style'; //核心图标库 4 | .icon-spin { 5 | animation: icon-spin 2s infinite linear; 6 | } 7 | 8 | .icon-pulse { 9 | animation: icon-spin 1s infinite steps(8); 10 | } 11 | 12 | @keyframes icon-spin { 13 | 0% { 14 | transform: rotate(0deg); 15 | } 16 | 100% { 17 | transform: rotate(359deg); 18 | } 19 | } 20 | .icon-90 { 21 | transform: rotate(90deg); 22 | } 23 | .icon-180 { 24 | transform: rotate(180deg); 25 | } 26 | .icon-270 { 27 | transform: rotate(270deg); 28 | } 29 | .icon-x { 30 | transform: scale(-1, 1); 31 | } 32 | .icon-y { 33 | transform: scale(1, -1); 34 | } 35 | .icon-fw { 36 | width: (18em / 14); 37 | text-align: center; 38 | } 39 | @each $class, $value in $iconsize { 40 | .icon-#{$class} { 41 | transform: scale(#{$value}); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /ui/scss/style/_avatar.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/poisonboy/wordpressuniapp/86ad3d1869aa67b920cdb90592085324dc7afb0d/ui/scss/style/_avatar.scss -------------------------------------------------------------------------------- /ui/scss/style/_border.scss: -------------------------------------------------------------------------------- 1 | /* ================== 2 | 边框 3 | ==================== */ 4 | /* -- 实线 -- */ 5 | .border { 6 | overflow: initial !important; 7 | @at-root [class*='border'], 8 | [class*='dashed'] { 9 | position: relative; 10 | &.dline{ 11 | --ui-Border:var(--ui-BG-3) 12 | } 13 | &::after { 14 | content: ' '; 15 | width: 200%; 16 | height: 200%; 17 | position: absolute; 18 | z-index: 0; 19 | top: 0; 20 | left: 0; 21 | transform: scale(0.5); 22 | transform-origin: 0 0; 23 | pointer-events: none; 24 | box-sizing: border-box; 25 | border-radius: inherit; 26 | } 27 | &.radius::after { 28 | border-radius: calc(#{$radius} * 2); 29 | } 30 | &.round::after { 31 | border-radius: #{$round-pill}; 32 | } 33 | } 34 | &::after { 35 | border: 1px solid var(--ui-Border); 36 | } 37 | &s::after { 38 | border: 4rpx solid var(--ui-Border); 39 | } 40 | &ss::after { 41 | border: 8rpx solid var(--ui-Border); 42 | } 43 | @each $value in (top, right, bottom, left) { 44 | &-#{$value}::after { 45 | border-#{$value}: 1px solid var(--ui-Border); 46 | } 47 | &s-#{$value}::after { 48 | border-#{$value}: 4rpx solid var(--ui-Border); 49 | } 50 | &ss-#{$value}::after { 51 | border-#{$value}: 8rpx solid var(--ui-Border); 52 | } 53 | } 54 | } 55 | /* -- 虚线 -- */ 56 | .dashed { 57 | &::after { 58 | border: 4rpx dashed var(--ui-Border); 59 | } 60 | &s::after { 61 | border: 6rpx dashed var(--ui-Border); 62 | } 63 | @each $value in (top, right, bottom, left) { 64 | &-#{$value}::after { 65 | border-#{$value}: 4rpx dashed var(--ui-Border); 66 | } 67 | &s-#{$value}::after { 68 | border-#{$value}: 6rpx dashed var(--ui-Border); 69 | } 70 | } 71 | } 72 | @each $color, $value in map-merge($colors, map-merge($darks, $grays)) { 73 | .border-#{$color}::after,.border-#{$color}[class*='-shine']::before { 74 | border-color: $value !important; 75 | } 76 | } 77 | @each $value in (a, b, c, d, e) { 78 | .main-#{$value}-border::after, 79 | .main-#{$value}-border[class*='-shine']::before { 80 | border-color: var(--main-#{$value}) !important; 81 | } 82 | } 83 | .dashed-shine, 84 | .dasheds-shine { 85 | position: relative; 86 | overflow: hidden; 87 | &::after, 88 | &::before { 89 | border-style: dashed; 90 | border-color: var(--ui-Border); 91 | animation: shineafter 1s infinite linear; 92 | width: calc(200% + 40px); 93 | height: 200%; 94 | border-width: 2px 0; 95 | } 96 | &::before { 97 | content: ' '; 98 | position: absolute; 99 | transform: scale(0.5); 100 | transform-origin: 0 0; 101 | pointer-events: none; 102 | box-sizing: border-box; 103 | animation: shinebefore 1s infinite linear; 104 | width: 200%; 105 | height: calc(200% + 40px); 106 | border-width: 0 2px; 107 | } 108 | } 109 | .dasheds-shine { 110 | &::after, 111 | &::before { 112 | border-width: 4px 0; 113 | } 114 | &::before { 115 | border-width: 0 4px; 116 | } 117 | } 118 | 119 | @keyframes shineafter { 120 | 0% { 121 | top: 0; 122 | left: -22px; 123 | } 124 | 100% { 125 | top: 0px; 126 | left: 0px; 127 | } 128 | } 129 | 130 | @keyframes shinebefore { 131 | 0% { 132 | top: -22px; 133 | left: 0; 134 | } 135 | 100% { 136 | top: 0px; 137 | left: 0px; 138 | } 139 | } 140 | -------------------------------------------------------------------------------- /ui/scss/style/_button.scss: -------------------------------------------------------------------------------- 1 | .ui-btn-box { 2 | display: inline-block; 3 | } 4 | .ui-btn { 5 | position: relative; 6 | border: 0rpx; 7 | display: inline-block; 8 | align-items: center; 9 | justify-content: center; 10 | box-sizing: border-box; 11 | padding: .7857em 1.5em .7857em; 12 | font-size: 28rpx; 13 | line-height: 1em; 14 | text-align: center; 15 | text-decoration: none; 16 | overflow: visible; 17 | margin: 0 0.25em 0 0; 18 | transform: translate(0rpx, 0rpx); 19 | border-radius: $radius; 20 | white-space: nowrap; 21 | color: var(--text-a); 22 | background-color: var(--ui-BG); 23 | vertical-align: baseline; 24 | &:first-child:last-child{ 25 | margin: 0; 26 | } 27 | &:not([class*='round'])::after { 28 | border-radius: calc(#{$radius} * 2); 29 | } 30 | &:not([class*='border'])::after { 31 | // content: ' '; 32 | // width: 200%; 33 | // height: 200%; 34 | // display: block; 35 | // position: absolute; 36 | // z-index: 0; 37 | // top: 0; 38 | // left: 0; 39 | // transform: scale(0.5); 40 | // transform-origin: 0 0; 41 | // pointer-events: none; 42 | // box-sizing: border-box; 43 | display: none; 44 | } 45 | &.round::after { 46 | border-radius: #{$round-pill}; 47 | } 48 | &.icon { 49 | padding: 0.8em 0.8em; 50 | } 51 | 52 | &.sm { 53 | font-size: 24rpx; 54 | } 55 | 56 | &.lg { 57 | font-size: 32rpx; 58 | } 59 | 60 | &.xl { 61 | font-size: 36rpx; 62 | } 63 | 64 | &.block { 65 | width: 100%; 66 | display: block; 67 | font-size: 32rpx; 68 | } 69 | 70 | &[disabled] { 71 | opacity: 0.6; 72 | } 73 | 74 | &.none-style { 75 | background-color: transparent !important; 76 | position: absolute; 77 | width: 100%; 78 | height: 100%; 79 | top: 0; 80 | left: 0; 81 | display: flex; 82 | } 83 | } 84 | 85 | .ui-btn:not(.icon) [class*='icon-'] { 86 | margin: 0 .25em; 87 | } -------------------------------------------------------------------------------- /ui/scss/style/_code.scss: -------------------------------------------------------------------------------- 1 | .ui-code { 2 | font-family: Monaco, Menlo, Consolas, 'Courier New'; 3 | font-size: 90%; 4 | position: relative; 5 | z-index: 1; 6 | color: var(--ui-TC); 7 | .ui-rich-text { 8 | display: inline-block; 9 | } 10 | 11 | &.code { 12 | display: inline-block; 13 | padding: 0 10rpx; 14 | margin: 0 10rpx; 15 | border-radius: $radius-sm; 16 | line-height: 1.6; 17 | vertical-align: baseline; 18 | } 19 | 20 | &.pre { 21 | display: block; 22 | margin: 1em 0; 23 | line-height: 1.6; 24 | &.hasTitle { 25 | margin: 3.2em 0 1em; 26 | } 27 | // border-radius: $radius-sm; 28 | .ui-code-title { 29 | position: absolute; 30 | top: -2.2em; 31 | color: var(--ui-TC-2); 32 | left: 0; 33 | } 34 | .ui-rich-text { 35 | padding: 40rpx; 36 | white-space: pre-wrap; 37 | word-break: break-all; 38 | word-wrap: break-word; 39 | } 40 | .ui-scroll-view { 41 | &.ui-scroll { 42 | max-height: 500px; 43 | white-space: pre; 44 | } 45 | } 46 | .ui-copy-btn { 47 | position: absolute; 48 | z-index: 2; 49 | top: 0; 50 | right: 0; 51 | padding: 0.8em; 52 | border-radius: 0 $radius-sm 0 $radius-sm; 53 | } 54 | } 55 | } 56 | 57 | @import '@/app/scss/style/prism.scss'; //代码高亮 58 | -------------------------------------------------------------------------------- /ui/scss/style/_flex.scss: -------------------------------------------------------------------------------- 1 | /* ================== 2 | 弹性布局 3 | ==================== */ 4 | .flex { 5 | display: flex !important; 6 | &-sub { 7 | flex: 1 !important; 8 | } 9 | &-twice { 10 | flex: 2 !important; 11 | } 12 | &-treble { 13 | flex: 3 !important; 14 | } 15 | &-column { 16 | flex-direction: column !important; 17 | } 18 | &-row { 19 | flex-direction: row !important; 20 | } 21 | &-column-reverse { 22 | flex-direction: column-reverse !important; 23 | } 24 | &-row-reverse { 25 | flex-direction: row-reverse !important; 26 | } 27 | &-wrap { 28 | flex-wrap: wrap !important; 29 | } 30 | &-center { 31 | @include flex-center; 32 | } 33 | &-bar { 34 | @include flex-bar; 35 | } 36 | } 37 | .basis { 38 | @each $class, $value in (xs: 20%, sm: 40%, df: 50%, lg: 60%, xl: 80%) { 39 | &-#{$class} { 40 | flex-basis: $value !important; 41 | } 42 | } 43 | } 44 | .align { 45 | @each $class, $value in (start: flex-start, end: flex-end, center: center, stretch: stretch, baseline: baseline) { 46 | &-#{$class} { 47 | align-items: $value !important; 48 | } 49 | } 50 | } 51 | .self { 52 | @each $class, $value in (start: flex-start, end: flex-end, center: center, stretch: stretch, baseline: baseline) { 53 | &-#{$class} { 54 | align-self: $value !important; 55 | } 56 | } 57 | } 58 | .justify { 59 | @each $class, $value in (start: flex-start, end: flex-end, center: center, between: space-between, around: space-around) { 60 | &-#{$class} { 61 | justify-content: $value !important; 62 | } 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /ui/scss/style/_form.scss: -------------------------------------------------------------------------------- 1 | /* ================== 2 | 表单 3 | ==================== */ 4 | .ui-form-groups { 5 | padding: 1rpx 24rpx; 6 | display: flex; 7 | align-items: center; 8 | min-height: 100rpx; 9 | justify-content: space-between; 10 | .title { 11 | text-align: justify; 12 | padding-right: 30rpx; 13 | font-size: 30rpx; 14 | position: relative; 15 | height: 60rpx; 16 | line-height: 60rpx; 17 | } 18 | .content { 19 | flex: 1; 20 | } 21 | input { 22 | flex: 1; 23 | font-size: 30rpx; 24 | color: #555; 25 | padding-right: 20rpx; 26 | } 27 | text[class*='icon-'] { 28 | font-size: 36rpx; 29 | padding: 0; 30 | box-sizing: border-box; 31 | } 32 | textarea { 33 | margin: 32rpx 0 30rpx; 34 | height: 4.6em; 35 | width: 100%; 36 | line-height: 1.2em; 37 | flex: 1; 38 | font-size: 28rpx; 39 | padding: 0; 40 | } 41 | picker, 42 | .arrow { 43 | flex: 1; 44 | padding-right: 40rpx; 45 | overflow: hidden; 46 | position: relative; 47 | } 48 | picker .picker, 49 | .arrow > view { 50 | line-height: 100rpx; 51 | text-overflow: ellipsis; 52 | white-space: nowrap; 53 | overflow: hidden; 54 | width: 100%; 55 | } 56 | picker::after, 57 | .arrow::after { 58 | font-family: 'ui'; 59 | display: block; 60 | content: '\e605'; 61 | position: absolute; 62 | font-size: 34rpx; 63 | color: #8799a3; 64 | line-height: 100rpx; 65 | width: 60rpx; 66 | text-align: center; 67 | top: 0; 68 | bottom: 0; 69 | right: -20rpx; 70 | margin: auto; 71 | } 72 | textarea[disabled], 73 | textarea[disabled] .placeholder { 74 | color: transparent; 75 | } 76 | &.align-start .title { 77 | height: 1em; 78 | margin-top: 32rpx; 79 | line-height: 1em; 80 | } 81 | .grid-square { 82 | > view { 83 | background-color: #f8f8f8; 84 | border-radius: 12rpx; 85 | .mask { 86 | background-color: rgba(0, 0, 0, 0.6); 87 | position: absolute; 88 | font-size: 20rpx; 89 | color: #ffffff; 90 | width: 100%; 91 | bottom: 0; 92 | text-align: center; 93 | padding: 6rpx 0; 94 | &.red-mask { 95 | background-color: rgba(255, 80, 80, 0.6); 96 | } 97 | } 98 | [class*='icon'] { 99 | position: absolute; 100 | width: 100%; 101 | height: 100%; 102 | display: flex; 103 | align-items: center; 104 | transform: scale(1.5); 105 | justify-content: center; 106 | } 107 | .text-gray { 108 | position: absolute; 109 | width: 100%; 110 | font-size: 24rpx; 111 | text-align: center; 112 | bottom: 20rpx; 113 | } 114 | } 115 | } 116 | } 117 | .disabled { 118 | opacity: 0.6; 119 | cursor: not-allowed !important; 120 | } 121 | -------------------------------------------------------------------------------- /ui/scss/style/_grid.scss: -------------------------------------------------------------------------------- 1 | /* ================== 2 | 栅栏 3 | ==================== */ 4 | 5 | .ui-container { 6 | box-sizing: border-box; 7 | margin-left: auto; 8 | margin-right: auto; 9 | padding-left: 30rpx; 10 | padding-right: 30rpx; 11 | width: 100%; 12 | max-width: 1440px; 13 | &-fluid{ 14 | max-width: 100%; 15 | padding-left: 0; 16 | padding-right: 0; 17 | } 18 | } 19 | .ui-grid { 20 | display: flex; 21 | flex-wrap: wrap; 22 | &.multi-column{ 23 | display: block; 24 | column-count: 2; 25 | column-width: 0px; 26 | column-gap: 0px;; 27 | > .ui-item { 28 | break-inside: avoid; 29 | padding: 0.001em; 30 | } 31 | } 32 | &.grid-square { 33 | overflow: hidden; 34 | > .ui-item { 35 | margin-right: 20rpx; 36 | margin-bottom: 20rpx; 37 | position: relative; 38 | overflow: hidden; 39 | } 40 | @for $i from 1 through 12 { 41 | &.ui-cols-#{$i} > .ui-item { 42 | padding-bottom: calc((100% - #{20rpx * ($i - 1)}) / #{$i}); 43 | height: 0; 44 | width: calc((100% - #{20rpx * ($i - 1)}) / #{$i}); 45 | } 46 | } 47 | @for $i from 1 through 12 { 48 | &.ui-cols-#{$i} > .ui-item:nth-child(#{$i}n) { 49 | margin-right: 0; 50 | } 51 | } 52 | } 53 | } 54 | @for $i from 1 through 12 { 55 | .ui-cols-#{$i} .ui-item { 56 | width: calc(100% / #{$i}); 57 | } 58 | } 59 | @for $i from 1 through 12 { 60 | .ui-col-#{$i} { 61 | width: calc(100% / 12 * #{$i}); 62 | } 63 | } 64 | 65 | @mixin make_col($screen) { 66 | @for $i from 1 through 12 { 67 | .ui-col-#{$screen}-#{$i} { 68 | width: calc(100% / 12 * #{$i}); 69 | } 70 | .ui-cols-#{$screen}-#{$i} .ui-item { 71 | width: calc(100% / #{$i}); 72 | } 73 | } 74 | } 75 | 76 | // 小屏 77 | @media screen and (min-width: 0px) { 78 | @include make_col('xs'); 79 | } 80 | 81 | // 小屏 82 | @media screen and (min-width: 320px) { 83 | @include make_col('sm'); 84 | } 85 | 86 | // 中屏 87 | @media screen and (min-width: 768px) { 88 | @include make_col('md'); 89 | } 90 | 91 | // 普通屏 92 | @media screen and (min-width: 1025px) { 93 | @include make_col('lg'); 94 | } 95 | 96 | // 大屏 97 | @media screen and (min-width: 1440px) { 98 | @include make_col('xl'); 99 | } 100 | 101 | // 超大屏 102 | @media screen and (min-width: 1920px) { 103 | @include make_col('xxl'); 104 | } 105 | -------------------------------------------------------------------------------- /ui/scss/style/_markdown.scss: -------------------------------------------------------------------------------- 1 | .cu-markdown { 2 | position: relative; 3 | z-index: 1; 4 | &.selectable { 5 | cursor: auto; 6 | user-select: text; 7 | } 8 | inline { 9 | display: inline-block; 10 | } 11 | 12 | .list { 13 | .list-item { 14 | line-height: 1.8; 15 | .list { 16 | margin-left: 1.28571em; 17 | .ui-title { 18 | transform: scale(0.6); 19 | &:before { 20 | content: '\e716'; 21 | } 22 | } 23 | } 24 | } 25 | .list-item-p { 26 | position: relative; 27 | padding-left: 1.5em; 28 | .list-item-t { 29 | display: block; 30 | width: 1.3em; 31 | text-align: center; 32 | position: absolute; 33 | left: 0; 34 | } 35 | } 36 | } 37 | .md-table + .md-table { 38 | margin-top: 30rpx; 39 | } 40 | } 41 | 42 | .paragraph { 43 | margin: 0 0 40rpx; 44 | line-height: 1.8; 45 | } 46 | 47 | .blockquote { 48 | @extend .paragraph; 49 | padding: 20rpx 30rpx; 50 | border-left-style: solid; 51 | border-left-width: 10rpx; 52 | border-color: var(--ui-Border); 53 | background: none repeat scroll 0 0 rgba(102, 128, 153, 0.05); 54 | 55 | .paragraph { 56 | margin-bottom: 30rpx; 57 | } 58 | 59 | .paragraph:last-child { 60 | margin-bottom: 0; 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /ui/scss/style/_menu.scss: -------------------------------------------------------------------------------- 1 | .ui-menu{ 2 | background-color: var(--ui-BG); 3 | } 4 | 5 | .ui-menu-item { 6 | position: relative; 7 | @include flex-bar; 8 | min-height: 4em; 9 | padding: 0 30rpx; 10 | .ui-menu-item-icon { 11 | width: 1.7em; 12 | margin-right: 0.3em; 13 | position: relative; 14 | display: flex; 15 | align-items: center; 16 | justify-content: center; 17 | transform: scale(1.3); 18 | } 19 | .ui-menu-item-icon .ui-menu-item-image { 20 | width: 1.2em; 21 | height: 1.2em; 22 | display: inline-block; 23 | } 24 | .ui-menu-item-content { 25 | flex: 1; 26 | position: relative; 27 | @include flex-bar; 28 | } 29 | .ui-menu-item-arrow { 30 | width: 1.6em; 31 | text-align: center; 32 | color: var(--ui-TC-3); 33 | } 34 | 35 | &.first-item::after { 36 | display: none; 37 | } 38 | &:first-child::after{ 39 | display: none; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /ui/scss/style/_shadow.scss: -------------------------------------------------------------------------------- 1 | /* ================== 2 | 阴影 3 | ==================== */ 4 | 5 | .shadow { 6 | box-shadow: var(--ui-Shadow); 7 | &-sm { 8 | box-shadow: var(--ui-Shadow-sm); 9 | } 10 | &-lg { 11 | box-shadow: var(--ui-Shadow-lg); 12 | } 13 | &-inset { 14 | box-shadow: var(--ui-Shadow-inset); 15 | } 16 | @each $color, $value in $colors { 17 | @at-root .shadow-#{$color} { 18 | box-shadow: 0 .5em 1em rgba($value, var(--ui-Shadow-opacity)); 19 | } 20 | &-sm.shadow-#{$color} { 21 | box-shadow: 0 .125em .25em rgba($value, var(--ui-Shadow-opacity)); 22 | } 23 | &-lg.shadow-#{$color} { 24 | box-shadow: 0 1em 3em rgba($value, var(--ui-Shadow-opacity-lg)); 25 | } 26 | } 27 | 28 | &-warp { 29 | position: relative; 30 | } 31 | &-warp:before, 32 | &-warp:after { 33 | position: absolute; 34 | content: ''; 35 | bottom: -10rpx; 36 | left: 20rpx; 37 | width: calc(50% - #{40rpx}); 38 | height: 30rpx; 39 | transform: skew(0deg, -6deg); 40 | transform-origin: 50% 50%; 41 | background-color: rgba(0, 0, 0, var(--ui-Shadow-opacity)); 42 | filter: blur(20rpx); 43 | z-index: -1; 44 | opacity: 0.5; 45 | } 46 | &-warp:after { 47 | right: 20rpx; 48 | left: auto; 49 | transform: skew(0deg, 6deg); 50 | } 51 | &-blur { 52 | position: relative; 53 | } 54 | &-blur::before { 55 | content: ''; 56 | display: block; 57 | background: inherit; 58 | filter: blur(20rpx); 59 | position: absolute; 60 | width: 100%; 61 | height: 100%; 62 | top: .5em; 63 | left: .5em; 64 | z-index: -1; 65 | opacity: var(--ui-Shadow-opacity-lg); 66 | transform-origin: 0 0; 67 | border-radius: inherit; 68 | transform: scale(1, 1); 69 | } 70 | } 71 | .drop-shadow { 72 | filter: drop-shadow(0 0 30rpx rgba(0, 0, 0, 0.1)); 73 | &-sm { 74 | filter: drop-shadow( 0 4rpx 4rpx rgba(0, 0, 0, 0.06)); 75 | } 76 | &-lg { 77 | filter: drop-shadow( 0 30rpx 60rpx rgba(0, 0, 0, 0.2)); 78 | } 79 | @each $color, $value in $colors { 80 | @at-root .drop-shadow-#{$color} { 81 | filter: drop-shadow( 0 15rpx 15rpx rgba(darken($value, 10%), 0.3)); 82 | } 83 | &-sm.drop-shadow-#{$color} { 84 | filter: drop-shadow( 0 4rpx 4rpx rgba(darken($value, 10%), 0.3)); 85 | } 86 | &-lg.drop-shadow-#{$color} { 87 | filter: drop-shadow( 0 50rpx 100rpx rgba(darken($value, 10%), 0.2)); 88 | } 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /ui/scss/style/_table.scss: -------------------------------------------------------------------------------- 1 | .ui-table { 2 | background-color: var(--ui-BG); 3 | max-width: 100%; 4 | display: table; 5 | &.table-full { 6 | width: 100%; 7 | } 8 | &.table-radius{ 9 | border-radius: $radius; 10 | .ui-table-header { 11 | .ui-table-tr { 12 | border-top-left-radius: $radius; 13 | border-top-right-radius: $radius; 14 | } 15 | .ui-table-th { 16 | &:first-child { 17 | border-top-left-radius: $radius; 18 | } 19 | &:last-child { 20 | border-top-right-radius: $radius; 21 | } 22 | } 23 | } 24 | } 25 | .ui-table-header { 26 | display: table-header-group; 27 | .ui-table-th { 28 | font-weight: bold; 29 | border-bottom: 1px solid var(--ui-Border); 30 | white-space: nowrap; 31 | 32 | padding: 1em .8em; 33 | } 34 | } 35 | 36 | .ui-table-tr { 37 | display: table-row; 38 | z-index: 1; 39 | } 40 | 41 | .ui-table-body { 42 | display: table-row-group; 43 | position: relative; 44 | .ui-table-tr:hover { 45 | background-color: var(--ui-BG-1) !important; 46 | } 47 | .ui-table-loading { 48 | min-height: 300px; 49 | position: absolute !important; 50 | width: 100%; 51 | height: 100%; 52 | z-index: 2; 53 | display: flex; 54 | align-items: center; 55 | justify-content: center; 56 | border: 1px solid var(--ui-Border); 57 | } 58 | } 59 | 60 | .ui-table-td, 61 | .ui-table-th { 62 | display: table-cell; 63 | text-align: unset; 64 | padding: 0.5em .8em; 65 | // font-size: 90%; 66 | vertical-align: middle; 67 | } 68 | } 69 | 70 | .ui-table.table-border { 71 | &, 72 | & .ui-table-td, 73 | & .ui-table-th { 74 | position: relative; 75 | &::after { 76 | content: ' '; 77 | width: 200%; 78 | height: 200%; 79 | position: absolute; 80 | top: 0; 81 | left: 0; 82 | border-radius: inherit; 83 | transform: scale(0.5); 84 | transform-origin: 0 0; 85 | pointer-events: none; 86 | box-sizing: border-box; 87 | border: 1px solid var(--ui-Border); 88 | z-index: 1; 89 | } 90 | } 91 | .ui-table-td, 92 | .ui-table-th { 93 | &::after { 94 | border-width: 1px 1px 0 0; 95 | } 96 | &:last-child::after { 97 | border-right: none; 98 | } 99 | } 100 | } 101 | .ui-table.table-radius { 102 | &::after { 103 | border-radius: calc(#{$radius} * 2); 104 | } 105 | & .ui-table-tr .ui-table-th:first-child{ 106 | border-top-left-radius: calc(#{$radius} * 2); 107 | } 108 | & .ui-table-tr .ui-table-th:last-child { 109 | border-top-right-radius: calc(#{$radius} * 2); 110 | } 111 | & .ui-table-tr:last-child .ui-table-td:first-child{ 112 | border-bottom-left-radius: #{$radius}; 113 | } 114 | & .ui-table-tr:last-child .ui-table-td:last-child { 115 | border-bottom-right-radius: #{$radius}; 116 | } 117 | } 118 | .ui-table.table-striped > .ui-table-body > .ui-table-tr:nth-child(2n + 1), 119 | .ui-table.table-striped > .ui-table-body > .ui-table-tr:nth-child(2n + 1) { 120 | background-color: var(--ui-BG-1); 121 | } 122 | 123 | .table-responsive { 124 | width: inherit; 125 | height: 100%; 126 | max-width: 100%; 127 | overflow: hidden; 128 | box-sizing: border-box; 129 | .table-responsive-box { 130 | position: relative; 131 | overflow: hidden; 132 | } 133 | } -------------------------------------------------------------------------------- /ui/scss/style/_tag.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/poisonboy/wordpressuniapp/86ad3d1869aa67b920cdb90592085324dc7afb0d/ui/scss/style/_tag.scss -------------------------------------------------------------------------------- /ui/scss/style/_text.scss: -------------------------------------------------------------------------------- 1 | /* ================== 2 | 文本 3 | ==================== */ 4 | .font-0{ 5 | font-size: 24rpx; 6 | --textSize:-4rpx; 7 | } 8 | .font-1{ 9 | font-size: 28rpx; 10 | --textSize:0rpx; 11 | } 12 | .font-2{ 13 | font-size: 32rpx; 14 | --textSize:4rpx; 15 | } 16 | .font-3{ 17 | font-size: 36rpx; 18 | --textSize:8rpx; 19 | } 20 | .font-4{ 21 | font-size: 40rpx; 22 | --textSize:12rpx; 23 | } 24 | .text { 25 | @each $class, $value in $fontsize { 26 | &-#{$class}, 27 | &-#{$value / 2} { 28 | font-size: calc(#{$value}rpx + var(--textSize)) !important; 29 | } 30 | } 31 | &-cut { 32 | text-overflow: ellipsis; 33 | white-space: nowrap; 34 | overflow: hidden; 35 | } 36 | @at-root [class*='text-linecut'] { 37 | display: -webkit-box; 38 | -webkit-box-orient: vertical; 39 | -webkit-line-clamp: 2; 40 | overflow: hidden; 41 | word-break: break-all; 42 | } 43 | @for $i from 2 through 10 { 44 | &-linecut-#{$i} { 45 | -webkit-line-clamp: #{$i}; 46 | } 47 | } 48 | &-justify { 49 | text-align: justify; 50 | } 51 | &-justify-line { 52 | text-align: justify; 53 | line-height: 0.5em; 54 | margin-top: 0.5em; 55 | &::after { 56 | content: '.'; 57 | display: inline-block; 58 | width: 100%; 59 | } 60 | } 61 | 62 | &-Abc { 63 | text-transform: Capitalize !important; 64 | } 65 | &-ABC { 66 | text-transform: Uppercase !important; 67 | } 68 | &-abc { 69 | text-transform: Lowercase !important; 70 | } 71 | &-del, 72 | &-line { 73 | text-decoration: line-through !important; 74 | } 75 | &-bottomline { 76 | text-decoration: underline !important; 77 | } 78 | &-italic { 79 | font-style: italic !important; 80 | } 81 | &-style-none { 82 | text-decoration: none !important; 83 | } 84 | &-break { 85 | word-break: break-word !important; 86 | overflow-wrap: break-word !important; 87 | } 88 | &-reset { 89 | color: inherit !important; 90 | } 91 | &-price::before { 92 | content: '¥'; 93 | font-size: 80%; 94 | margin-right: 4rpx; 95 | } 96 | &-hide { 97 | font: 0/0 a; 98 | color: transparent; 99 | text-shadow: none; 100 | background-color: transparent; 101 | border: 0; 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /ui/scss/theme/_dark.scss: -------------------------------------------------------------------------------- 1 | // 核心主题样式文件 2 | @mixin theme-dark { 3 | 4 | // 背景色 5 | --ui-BG: #393939; 6 | --ui-BG-1: #333333; 7 | --ui-BG-2: #2c2c2c; 8 | --ui-BG-3: #292929; 9 | --ui-BG-4: #222222; 10 | 11 | // 文本色 12 | --ui-TC: #ffffff; 13 | --ui-TC-1: #d4d4d4; 14 | --ui-TC-2: #919191; 15 | --ui-TC-3: #6a6a6a; 16 | --ui-TC-4: #474747; 17 | 18 | // 模糊 19 | --ui-Blur: rgba(38, 38, 38, 0.98); 20 | --ui-Blur-1: rgba(38, 38, 38, 0.75); 21 | --ui-Blur-2: rgba(38, 38, 38, 0.25); 22 | --ui-Blur-3: rgba(38, 38, 38, 0.05); 23 | 24 | // 边框 25 | --ui-Border: rgba(119, 119, 119, 0.25); 26 | --ui-Outline: rgba(255,255,255,0.1); 27 | --ui-Line: rgba(119,119,119,0.25); 28 | 29 | // 透明与阴影 30 | --ui-Shadow: 0 .5em 1em rgba(0, 0, 0, 0.45); 31 | --ui-Shadow-sm: 0 .125em .25em rgba(0, 0, 0, 0.475); 32 | --ui-Shadow-lg: 0 1em 3em rgba(0, 0, 0, 0.475); 33 | --ui-Shadow-inset: inset 0 1px 2px rgba(0, 0, 0, 0.475); 34 | 35 | --ui-Shadow-opacity: 0.55; 36 | --ui-Shadow-opacity-sm: 0.175; 37 | --ui-Shadow-opacity-lg: 0.75; 38 | 39 | --ui-BG-opacity: .1; 40 | } 41 | -------------------------------------------------------------------------------- /ui/scss/theme/_light.scss: -------------------------------------------------------------------------------- 1 | // 核心主题样式文件 2 | @mixin theme-light { 3 | 4 | // 背景色 5 | --ui-BG: #ffffff; 6 | --ui-BG-1: #f6f6f6; 7 | --ui-BG-2: #f1f1f1; 8 | --ui-BG-3: #e8e8e8; 9 | --ui-BG-4: #e0e0e0; 10 | 11 | // 文本色 12 | --ui-TC: #303030; 13 | --ui-TC-1: #525252; 14 | --ui-TC-2: #777777; 15 | --ui-TC-3: #9e9e9e; 16 | --ui-TC-4: #c6c6c6; 17 | 18 | // 模糊 19 | --ui-Blur: rgba(255, 255, 255, 0.98); 20 | --ui-Blur-1: rgba(255, 255, 255, 0.75); 21 | --ui-Blur-2: rgba(255,255,255,0.25); 22 | --ui-Blur-3: rgba(255,255,255,0.05); 23 | 24 | // 边框 25 | --ui-Border: rgba(119,119,119,0.25); 26 | --ui-Outline: rgba(0,0,0,0.1); 27 | --ui-Line: rgba(119,119,119,0.25); 28 | 29 | // 透明与阴影 30 | --ui-Shadow: 0 .5em 1em rgba(0, 0, 0, 0.15); 31 | --ui-Shadow-sm: 0 .125em .25em rgba(0, 0, 0, 0.075); 32 | --ui-Shadow-lg: 0 1em 3em rgba(0, 0, 0, 0.175); 33 | --ui-Shadow-inset: inset 0 .1em .2em rgba(0, 0, 0, 0.075); 34 | 35 | --ui-Shadow-opacity: 0.45; 36 | --ui-Shadow-opacity-sm: 0.075; 37 | --ui-Shadow-opacity-lg: 0.65; 38 | 39 | --ui-BG-opacity: .1; 40 | } 41 | -------------------------------------------------------------------------------- /ui/scss/theme/_style.scss: -------------------------------------------------------------------------------- 1 | @import './light'; //浅蓝主题 2 | @import './dark'; //深蓝主题 3 | // 多主题 4 | .theme-light { 5 | @include theme-light; 6 | } 7 | .theme-dark { 8 | @include theme-dark; 9 | } 10 | .theme-auto { 11 | @include theme-light; 12 | } 13 | @media (prefers-color-scheme: dark) { 14 | .theme-auto { 15 | @include theme-dark; 16 | } 17 | } 18 | 19 | @each $value in ('', '-1', '-2', '-3', '-4') { 20 | .ui-BG#{$value} { 21 | background-color: var(--ui-BG#{$value}) !important; 22 | color: var(--ui-TC); 23 | } 24 | .ui-TC#{$value} { 25 | color: var(--ui-TC#{$value}) !important; 26 | } 27 | .ui-BG-Main#{$value} { 28 | background-color: var(--ui-BG-Main#{$value}) !important; 29 | color: var(--ui-BG-Main-TC) !important; 30 | } 31 | .ui-TC-Main#{$value} { 32 | color: var(--ui-BG-Main#{$value}) !important; 33 | } 34 | } 35 | 36 | @each $color, $value in $colors { 37 | .main-#{$color} { 38 | --ui-BG-Main: #{$value}; 39 | --ui-BG-Main-1: #{mix(rgba(255, 255, 255, 0.7), desaturate($value, 20%), 10%)}; 40 | --ui-BG-Main-2: #{mix(rgba(255, 255, 255, 0.6), desaturate($value, 40%), 20%)}; 41 | --ui-BG-Main-3: #{mix(rgba(119, 119, 119, 0.2), desaturate($value, 40%), 40%)}; 42 | --ui-BG-Main-4: #{mix(rgba(119, 119, 119, 0.1), desaturate($value, 40%), 60%)}; 43 | 44 | @if $color == 'yellow' { 45 | --ui-BG-Main-TC: #333333 !important; 46 | } @else { 47 | --ui-BG-Main-TC: #ffffff !important; 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /ui/scss/ui.scss: -------------------------------------------------------------------------------- 1 | @import '@/app/scss/theme/style'; //自定义主题 2 | @import '@/ui/scss/theme/style';//系统主题 3 | @import './main'; //主样式* 4 | 5 | @import './style/background'; //背景 6 | @import './style/grid'; //列 7 | @import './style/flex'; //布局 8 | @import './style/border'; //边框 9 | @import './style/text'; //文本 10 | @import './style/shadow'; //阴影 11 | @import './icon/style'; //图标 12 | @import './style/tag'; //标签 13 | @import './style/button'; //按钮 14 | @import './style/avatar'; //头像 15 | @import './style/table'; //表格 16 | @import './style/code'; //代码片段 17 | @import './style/form'; //表单 18 | @import './style/menu'; //表单 19 | @import './style/markdown'; //表单 20 | @import './style/card'; //表单 21 | 22 | @import '@/app/scss/app'; 23 | -------------------------------------------------------------------------------- /ui/store/index.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import Vuex from 'vuex' 3 | import app from '@/app/store' 4 | import modal from '@/ui/store/modal.js' 5 | 6 | Vue.use(Vuex) 7 | const store = new Vuex.Store({ 8 | state: { 9 | sys_theme: uni.getStorageSync('sys_theme') ? uni.getStorageSync('sys_theme') : app.state.theme, // light dark 10 | sys_main: uni.getStorageSync('sys_main') ? uni.getStorageSync('sys_main') : app.state.main, // color 11 | sys_text: 1, 12 | sys_info: uni.getSystemInfoSync(), 13 | sys_statusBar: uni.getSystemInfoSync().statusBarHeight, 14 | }, 15 | getters: { 16 | sys_capsule() { 17 | // #ifdef MP 18 | // #ifndef MP-ALIPAY 19 | let capsule = uni.getMenuButtonBoundingClientRect(); 20 | if (!capsule) { 21 | console.log('getMenuButtonBoundingClientRect error'); 22 | capsule = { 23 | bottom: 56, 24 | height: 32, 25 | left: 278, 26 | right: 365, 27 | top: 24, 28 | width: 87 29 | }; 30 | } 31 | return capsule; 32 | // #endif 33 | // #endif 34 | 35 | // #ifndef MP 36 | return { 37 | bottom: 56, 38 | height: 32, 39 | left: 278, 40 | right: 365, 41 | top: 24, 42 | width: 87 43 | }; 44 | // #endif 45 | }, 46 | sys_navBar() { 47 | // #ifndef MP 48 | return uni.getSystemInfoSync().statusBarHeight + 50; 49 | // #endif 50 | 51 | // #ifdef MP 52 | // #ifndef MP-ALIPAY 53 | let capsule = uni.getMenuButtonBoundingClientRect(); 54 | if (!capsule) { 55 | console.log('getMenuButtonBoundingClientRect error'); 56 | capsule = { 57 | bottom: 56, 58 | height: 32, 59 | left: 278, 60 | right: 365, 61 | top: 24, 62 | width: 87 63 | }; 64 | } 65 | return capsule.bottom + capsule.top - uni.getSystemInfoSync().statusBarHeight; 66 | // #endif 67 | // #endif 68 | 69 | // #ifdef MP-ALIPAY 70 | return uni.getSystemInfoSync().statusBarHeight + uni.getSystemInfoSync().titleBarHeight; 71 | // #endif 72 | } 73 | }, 74 | mutations: { 75 | //设置主题 76 | setTheme(state, data) { 77 | uni.setStorageSync('sys_theme', data); 78 | state.sys_theme = data; 79 | // #ifdef H5 80 | document.getElementsByTagName('html')[0].className = 81 | `theme-${state.sys_theme} main-${state.sys_main}`; 82 | // #endif 83 | 84 | if (data == 'auto') { 85 | // #ifdef MP 86 | this.commit('setStatusStyle',uni.getSystemInfoSync().theme == 'light' ? 'dark' : 'light'); 87 | // #endif 88 | } else { 89 | this.commit('setStatusStyle',data == 'light' ? 'dark' : 'light'); 90 | } 91 | }, 92 | setText(state, data) { 93 | uni.setStorageSync('sys_text', data); 94 | state.sys_text = data; 95 | }, 96 | setStatusStyle(state, status) { 97 | // console.log('theme=>',uni.getSystemInfoSync().theme,'status=>',status); 98 | // #ifdef H5 99 | return false 100 | // #endif 101 | if (status == 'light') { 102 | // #ifndef MP-ALIPAY 103 | uni.setNavigationBarColor({ 104 | frontColor: '#ffffff', 105 | backgroundColor: '#000000', 106 | animation: { 107 | duration: 200, 108 | timingFunc: 'easeIn' 109 | } 110 | }); 111 | // #endif 112 | 113 | // #ifdef APP-PLUS 114 | plus.navigator.setStatusBarStyle('light'); 115 | // #endif 116 | 117 | // #ifdef MP-ALIPAY 118 | uni.setNavigationBarColor({ 119 | frontColor: '#ffffff', 120 | backgroundColor: '#000000' 121 | }); 122 | // #endif 123 | } else { 124 | // #ifndef MP-ALIPAY 125 | uni.setNavigationBarColor({ 126 | frontColor: '#000000', 127 | backgroundColor: '#ffffff', 128 | animation: { 129 | duration: 200, 130 | timingFunc: 'easeIn' 131 | } 132 | }); 133 | // #endif 134 | 135 | // #ifdef APP-PLUS 136 | plus.navigator.setStatusBarStyle('dark'); 137 | // #endif 138 | 139 | // #ifdef MP-ALIPAY 140 | uni.setNavigationBarColor({ 141 | frontColor: '#000000' 142 | backgroundColor: '#ffffff' 143 | }); 144 | // #endif 145 | } 146 | }, 147 | //设置主颜色 148 | setMain(state, data) { 149 | uni.setStorageSync('sys_main', data); 150 | state.sys_main = data; 151 | // #ifdef H5 152 | document.getElementsByTagName('html')[0].className = 153 | `theme-${state.sys_theme} main-${state.sys_main}`; 154 | // #endif 155 | }, 156 | }, 157 | actions: { 158 | }, 159 | modules: { 160 | app, 161 | modal 162 | } 163 | }) 164 | 165 | 166 | Vue.prototype.$store = store 167 | export default store; 168 | -------------------------------------------------------------------------------- /ui/store/modal.js: -------------------------------------------------------------------------------- 1 | export default { 2 | state: { 3 | target:'', 4 | dialog:{ 5 | title:'', 6 | content:'', 7 | showCancel:true, 8 | cancelText:'取消', 9 | cancelColor:'', 10 | confirmText:'确定', 11 | confirmColor:'', 12 | success:()=>{}, 13 | }, 14 | toast:{ 15 | title:'', 16 | icon:'', 17 | image:'', 18 | duration:1500, 19 | mask:false, 20 | isLoading:false, 21 | success:()=>{}, 22 | }, 23 | }, 24 | getters: { 25 | 26 | 27 | }, 28 | mutations: { 29 | setTarget(state, data) { 30 | state.target = data; 31 | }, 32 | setDialog(state, data) { 33 | state.target = 'sys_dialog'; 34 | state.dialog = Object.assign(state.dialog,data); 35 | }, 36 | setToast(state, data) { 37 | state.toast = Object.assign(state.toast,data); 38 | }, 39 | }, 40 | actions: {} 41 | } 42 | -------------------------------------------------------------------------------- /uni.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * 这里是uni-app内置的常用样式变量 3 | * 4 | * uni-app 官方扩展插件及插件市场(https://ext.dcloud.net.cn)上很多三方插件均使用了这些样式变量 5 | * 如果你是插件开发者,建议你使用scss预处理,并在插件代码中直接使用这些变量(无需 import 这个文件),方便用户通过搭积木的方式开发整体风格一致的App 6 | * 7 | */ 8 | 9 | /** 10 | * 如果你是App开发者(插件使用者),你可以通过修改这些变量来定制自己的插件主题,实现自定义主题功能 11 | * 12 | * 如果你的项目同样使用了scss预处理,你也可以直接在你的 scss 代码中使用如下变量,同时无需 import 这个文件 13 | */ 14 | @import '@/ui/scss/var'; 15 | /* 颜色变量 */ 16 | 17 | /* 行为相关颜色 */ 18 | $uni-color-primary: #007aff; 19 | $uni-color-success: #4cd964; 20 | $uni-color-warning: #f0ad4e; 21 | $uni-color-error: #dd524d; 22 | 23 | /* 文字基本颜色 */ 24 | $uni-text-color:#333;//基本色 25 | $uni-text-color-inverse:#fff;//反色 26 | $uni-text-color-grey:#999;//辅助灰色,如加载更多的提示信息 27 | $uni-text-color-placeholder: #808080; 28 | $uni-text-color-disable:#c0c0c0; 29 | 30 | /* 背景颜色 */ 31 | $uni-bg-color:#ffffff; 32 | $uni-bg-color-grey:#f8f8f8; 33 | $uni-bg-color-hover:#f1f1f1;//点击状态颜色 34 | $uni-bg-color-mask:rgba(0, 0, 0, 0.4);//遮罩颜色 35 | 36 | /* 边框颜色 */ 37 | $uni-border-color:#c8c7cc; 38 | 39 | /* 尺寸变量 */ 40 | 41 | /* 文字尺寸 */ 42 | $uni-font-size-sm:12px; 43 | $uni-font-size-base:14px; 44 | $uni-font-size-lg:16; 45 | 46 | /* 图片尺寸 */ 47 | $uni-img-size-sm:20px; 48 | $uni-img-size-base:26px; 49 | $uni-img-size-lg:40px; 50 | 51 | /* Border Radius */ 52 | $uni-border-radius-sm: 2px; 53 | $uni-border-radius-base: 3px; 54 | $uni-border-radius-lg: 6px; 55 | $uni-border-radius-circle: 50%; 56 | 57 | /* 水平间距 */ 58 | $uni-spacing-row-sm: 5px; 59 | $uni-spacing-row-base: 10px; 60 | $uni-spacing-row-lg: 15px; 61 | 62 | /* 垂直间距 */ 63 | $uni-spacing-col-sm: 4px; 64 | $uni-spacing-col-base: 8px; 65 | $uni-spacing-col-lg: 12px; 66 | 67 | /* 透明度 */ 68 | $uni-opacity-disabled: 0.3; // 组件禁用态的透明度 69 | 70 | /* 文章场景相关 */ 71 | $uni-color-title: #2C405A; // 文章标题颜色 72 | $uni-font-size-title:20px; 73 | $uni-color-subtitle: #555555; // 二级标题颜色 74 | $uni-font-size-subtitle:26px; 75 | $uni-color-paragraph: #3F536E; // 文章段落颜色 76 | $uni-font-size-paragraph:15px; 77 | -------------------------------------------------------------------------------- /uni_modules/mp-html/changelog.md: -------------------------------------------------------------------------------- 1 | ## v2.2.1(2021-12-24) 2 | 1. `A` `editable` 插件增加上下移动标签功能 3 | 2. `U` `editable` 插件支持在文本中间光标处插入内容 4 | 3. `F` 修复了 `nvue` 端设置 `margin` 后可能导致高度不正确的问题 5 | 4. `F` 修复了 `highlight` 插件使用压缩版的 `prism.css` 可能导致背景失效的问题 [详细](https://github.com/jin-yufeng/mp-html/issues/367) 6 | 5. `F` 修复了编辑状态下使用 `emoji` 插件内容为空时可能报错的问题 [详细](https://github.com/jin-yufeng/mp-html/issues/371) 7 | 6. `F` 修复了使用 `editable` 插件后将 `selectable` 属性设置为 `force` 不生效的问题 8 | ## v2.2.0(2021-10-12) 9 | 1. `A` 增加 `customElements` 配置项,便于添加自定义功能性标签 [详细](https://github.com/jin-yufeng/mp-html/issues/350) 10 | 2. `A` `editable` 插件增加切换音视频自动播放状态的功能 [详细](https://github.com/jin-yufeng/mp-html/pull/341) by [@leeseett](https://github.com/leeseett) 11 | 3. `A` `editable` 插件删除媒体标签时触发 `remove` 事件,便于删除已上传的文件 12 | 4. `U` `editable` 插件 `insertImg` 方法支持同时插入多张图片 [详细](https://github.com/jin-yufeng/mp-html/issues/342) 13 | 5. `U` `editable` 插入图片和音视频时支持拼接 `domian` 主域名 14 | 6. `F` 修复了内部链接参数中包含 `://` 时被认为是外部链接的问题 [详细](https://github.com/jin-yufeng/mp-html/issues/356) 15 | 7. `F` 修复了部分 `svg` 标签名或属性名大小写不正确时不生效的问题 [详细](https://github.com/jin-yufeng/mp-html/issues/351) 16 | 8. `F` 修复了 `nvue` 页面运行到非 `app` 平台时可能样式错误的问题 17 | ## v2.1.5(2021-08-13) 18 | 1. `A` 增加支持标签的 `dir` 属性 19 | 2. `F` 修复了 `ruby` 标签文字与拼音没有居中对齐的问题 [详细](https://github.com/jin-yufeng/mp-html/issues/325) 20 | 3. `F` 修复了音视频标签内有 `a` 标签时可能无法播放的问题 21 | 4. `F` 修复了 `externStyle` 中的 `class` 名包含下划线或数字时可能失效的问题 [详细](https://github.com/jin-yufeng/mp-html/issues/326) 22 | 5. `F` 修复了 `h5` 端引入 `externStyle` 可能不生效的问题 [详细](https://github.com/jin-yufeng/mp-html/issues/326) 23 | ## v2.1.4(2021-07-14) 24 | 1. `F` 修复了 `rt` 标签无法设置样式的问题 [详细](https://github.com/jin-yufeng/mp-html/issues/318) 25 | 2. `F` 修复了表格中有单元格同时合并行和列时可能显示不正确的问题 26 | 3. `F` 修复了 `app` 端无法关闭图片长按菜单的问题 [详细](https://github.com/jin-yufeng/mp-html/issues/322) 27 | 4. `F` 修复了 `editable` 插件只能添加图片链接不能修改的问题 [详细](https://github.com/jin-yufeng/mp-html/pull/312) by [@leeseett](https://github.com/leeseett) 28 | ## v2.1.3(2021-06-12) 29 | 1. `A` `editable` 插件增加 `insertTable` 方法 30 | 2. `U` `editable` 插件支持编辑表格中的空白单元格 [详细](https://github.com/jin-yufeng/mp-html/issues/310) 31 | 3. `F` 修复了 `externStyle` 中使用伪类可能失效的问题 [详细](https://github.com/jin-yufeng/mp-html/issues/298) 32 | 4. `F` 修复了多个组件同时使用时 `tag-style` 属性时可能互相影响的问题 [详细](https://github.com/jin-yufeng/mp-html/pull/305) by [@woodguoyu](https://github.com/woodguoyu) 33 | 5. `F` 修复了包含 `linearGradient` 的 `svg` 可能无法显示的问题 34 | 6. `F` 修复了编译到头条小程序时可能报错的问题 35 | 7. `F` 修复了 `nvue` 端不触发 `click` 事件的问题 36 | 8. `F` 修复了 `editable` 插件尾部插入时无法撤销的问题 37 | 9. `F` 修复了 `editable` 插件的 `insertHtml` 方法只能在末尾插入的问题 38 | 10. `F` 修复了 `editable` 插件插入音频不显示的问题 39 | ## v2.1.2(2021-04-24) 40 | 1. `A` 增加了 [img-cache](https://jin-yufeng.gitee.io/mp-html/#/advanced/plugin#img-cache) 插件,可以在 `app` 端缓存图片 [详细](https://github.com/jin-yufeng/mp-html/issues/292) by [@PentaTea](https://github.com/PentaTea) 41 | 2. `U` 支持通过 `container-style` 属性设置 `white-space` 来保留连续空格和换行符 [详细](https://jin-yufeng.gitee.io/mp-html/#/question/faq#space) 42 | 3. `U` 代码风格符合 [standard](https://standardjs.com) 标准 43 | 4. `U` `editable` 插件编辑状态下支持预览视频 [详细](https://github.com/jin-yufeng/mp-html/issues/286) 44 | 5. `F` 修复了 `svg` 标签内嵌 `svg` 时无法显示的问题 45 | 6. `F` 修复了编译到支付宝和头条小程序时部分区域不可复制的问题 [详细](https://github.com/jin-yufeng/mp-html/issues/291) 46 | ## v2.1.1(2021-04-09) 47 | 1. 修复了对 `p` 标签设置 `tag-style` 可能不生效的问题 48 | 2. 修复了 `svg` 标签中的文本无法显示的问题 49 | 3. 修复了使用 `editable` 插件编辑表格时可能报错的问题 50 | 4. 修复了使用 `highlight` 插件运行到头条小程序时可能没有样式的问题 [详细](https://github.com/jin-yufeng/mp-html/issues/280) 51 | 5. 修复了使用 `editable` 插件 `editable` 属性为 `false` 时会报错的问题 [详细](https://github.com/jin-yufeng/mp-html/issues/284) 52 | 6. 修复了 `style` 插件连续子选择器失效的问题 53 | 7. 修复了 `editable` 插件无法修改图片和字体大小的问题 54 | ## v2.1.0.2(2021-03-21) 55 | 修复了 `nvue` 端使用可能报错的问题 56 | ## v2.1.0(2021-03-20) 57 | 1. `A` 增加了 [container-style](https://jin-yufeng.gitee.io/mp-html/#/basic/prop#container-style) 属性 [详细](https://gitee.com/jin-yufeng/mp-html/pulls/1) 58 | 2. `A` 增加支持 `strike` 标签 59 | 3. `A` `editable` 插件增加 `placeholder` 属性 [详细](https://jin-yufeng.gitee.io/mp-html/#/advanced/plugin#editable) 60 | 4. `A` `editable` 插件增加 `insertHtml` 方法 [详细](https://jin-yufeng.gitee.io/mp-html/#/advanced/plugin#editable) 61 | 5. `U` 外部样式支持标签名选择器 [详细](https://jin-yufeng.gitee.io/mp-html/#/overview/quickstart#setting) 62 | 6. `F` 修复了 `nvue` 端部分情况下可能不显示的问题 63 | ## v2.0.5(2021-03-12) 64 | 1. `U` [linktap](https://jin-yufeng.gitee.io/mp-html/#/basic/event#linktap) 事件增加返回内部文本内容 `innerText` [详细](https://github.com/jin-yufeng/mp-html/issues/271) 65 | 2. `U` [selectable](https://jin-yufeng.gitee.io/mp-html/#/basic/prop#selectable) 属性设置为 `force` 时能够在微信 `iOS` 端生效(文本块会变成 `inline-block`) [详细](https://github.com/jin-yufeng/mp-html/issues/267) 66 | 3. `F` 修复了部分情况下竖向无法滚动的问题 [详细](https://github.com/jin-yufeng/mp-html/issues/182) 67 | 4. `F` 修复了多次修改富文本数据时部分内容可能不显示的问题 68 | 5. `F` 修复了 [腾讯视频](https://jin-yufeng.gitee.io/mp-html/#/advanced/plugin#txv-video) 插件可能无法播放的问题 [详细](https://github.com/jin-yufeng/mp-html/issues/265) 69 | 6. `F` 修复了 [highlight](https://jin-yufeng.gitee.io/mp-html/#/advanced/plugin#highlight) 插件没有设置高亮语言时没有应用默认样式的问题 [详细](https://github.com/jin-yufeng/mp-html/issues/276) by [@fuzui](https://github.com/fuzui) 70 | -------------------------------------------------------------------------------- /uni_modules/mp-html/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "mp-html", 3 | "displayName": "mp-html 富文本组件【全端支持,可编辑】", 4 | "version": "v2.2.1", 5 | "description": "一个强大的富文本组件,高效轻量,功能丰富", 6 | "keywords": [ 7 | "富文本", 8 | "编辑器", 9 | "html", 10 | "rich-text", 11 | "editor" 12 | ], 13 | "repository": "https://github.com/jin-yufeng/mp-html", 14 | "dcloudext": { 15 | "category": [ 16 | "前端组件", 17 | "通用组件" 18 | ], 19 | "sale": { 20 | "regular": { 21 | "price": "0.00" 22 | }, 23 | "sourcecode": { 24 | "price": "0.00" 25 | } 26 | }, 27 | "contact": { 28 | "qq": "" 29 | }, 30 | "declaration": { 31 | "ads": "无", 32 | "data": "无", 33 | "permissions": "无" 34 | }, 35 | "npmurl": "https://www.npmjs.com/package/mp-html" 36 | }, 37 | "uni_modules": { 38 | "platforms": { 39 | "cloud": { 40 | "tcb": "y", 41 | "aliyun": "y" 42 | }, 43 | "client": { 44 | "App": { 45 | "app-vue": "y", 46 | "app-nvue": "y" 47 | }, 48 | "H5-mobile": { 49 | "Safari": "y", 50 | "Android Browser": "y", 51 | "微信浏览器(Android)": "y", 52 | "QQ浏览器(Android)": "y" 53 | }, 54 | "H5-pc": { 55 | "Chrome": "y", 56 | "IE": "u", 57 | "Edge": "y", 58 | "Firefox": "y", 59 | "Safari": "y" 60 | }, 61 | "小程序": { 62 | "微信": "y", 63 | "阿里": "y", 64 | "百度": "y", 65 | "字节跳动": "y", 66 | "QQ": "y" 67 | }, 68 | "快应用": { 69 | "华为": "y", 70 | "联盟": "y" 71 | }, 72 | "Vue": { 73 | "vue2": "y", 74 | "vue3": "u" 75 | } 76 | } 77 | } 78 | } 79 | } -------------------------------------------------------------------------------- /uni_modules/mp-html/static/app-plus/mp-html/js/handler.js: -------------------------------------------------------------------------------- 1 | "use strict";function t(t){for(var e=Object.create(null),n=t.attributes.length;n--;)e[t.attributes[n].name]=t.attributes[n].value;return e}function e(){o[1]&&(this.src=o[1],this.onerror=null),this.onclick=null,this.ontouchstart=null,uni.postMessage({data:{action:"onError",source:"img",attrs:t(this)}})}function n(r,i,s){for(var c=0;c0&&void 0!==arguments[0]?arguments[0]:{},n=e.url;a("navigateTo",{url:encodeURI(n)})},navigateBack:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},n=e.delta;a("navigateBack",{delta:parseInt(n)||1})},switchTab:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},n=e.url;a("switchTab",{url:encodeURI(n)})},reLaunch:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},n=e.url;a("reLaunch",{url:encodeURI(n)})},redirectTo:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},n=e.url;a("redirectTo",{url:encodeURI(n)})},getEnv:function(e){window.plus?e({plus:!0}):e({h5:!0})},postMessage:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};a("postMessage",e.data||{})}},r=/uni-app/i.test(navigator.userAgent),d=/Html5Plus/i.test(navigator.userAgent),s=/complete|loaded|interactive/;var w=window.my&&navigator.userAgent.indexOf("AlipayClient")>-1;var u=window.swan&&window.swan.webView&&/swan/i.test(navigator.userAgent);var c=window.qq&&window.qq.miniProgram&&/QQ/i.test(navigator.userAgent)&&/miniProgram/i.test(navigator.userAgent);var g=window.tt&&window.tt.miniProgram&&/toutiaomicroapp/i.test(navigator.userAgent);var v=window.wx&&window.wx.miniProgram&&/micromessenger/i.test(navigator.userAgent)&&/miniProgram/i.test(navigator.userAgent);var p=window.qa&&/quickapp/i.test(navigator.userAgent);for(var l,_=function(){window.UniAppJSBridge=!0,document.dispatchEvent(new CustomEvent("UniAppJSBridgeReady",{bubbles:!0,cancelable:!0}))},f=[function(e){if(r||d)return window.__dcloud_weex_postMessage||window.__dcloud_weex_?document.addEventListener("DOMContentLoaded",e):window.plus&&s.test(document.readyState)?setTimeout(e,0):document.addEventListener("plusready",e),o},function(e){if(v)return window.WeixinJSBridge&&window.WeixinJSBridge.invoke?setTimeout(e,0):document.addEventListener("WeixinJSBridgeReady",e),window.wx.miniProgram},function(e){if(c)return window.QQJSBridge&&window.QQJSBridge.invoke?setTimeout(e,0):document.addEventListener("QQJSBridgeReady",e),window.qq.miniProgram},function(e){if(w){document.addEventListener("DOMContentLoaded",e);var n=window.my;return{navigateTo:n.navigateTo,navigateBack:n.navigateBack,switchTab:n.switchTab,reLaunch:n.reLaunch,redirectTo:n.redirectTo,postMessage:n.postMessage,getEnv:n.getEnv}}},function(e){if(u)return document.addEventListener("DOMContentLoaded",e),window.swan.webView},function(e){if(g)return document.addEventListener("DOMContentLoaded",e),window.tt.miniProgram},function(e){if(p){window.QaJSBridge&&window.QaJSBridge.invoke?setTimeout(e,0):document.addEventListener("QaJSBridgeReady",e);var n=window.qa;return{navigateTo:n.navigateTo,navigateBack:n.navigateBack,switchTab:n.switchTab,reLaunch:n.reLaunch,redirectTo:n.redirectTo,postMessage:n.postMessage,getEnv:n.getEnv}}},function(e){return document.addEventListener("DOMContentLoaded",e),o}],m=0;m
-------------------------------------------------------------------------------- /utils/adapter.js: -------------------------------------------------------------------------------- 1 | var wxRequest = require('./wxRequest.js'); 2 | 3 | var Api = require('./api.js'); // 获取小程序插屏广告 4 | 5 | function setInterstitialAd(pagetype) { 6 | var getOptionsRequest = wxRequest.getRequest(Api.getOptions()); 7 | getOptionsRequest.then((res) => { 8 | // 获取广告id,创建插屏广告组件 9 | var adUnitId = res.data.interstitialAdId; 10 | var enableAd = false; 11 | var enable_index_interstitial_ad = res.data.enable_index_interstitial_ad; 12 | var enable_detail_interstitial_ad = res.data.enable_detail_interstitial_ad; 13 | var enable_topic_interstitial_ad = res.data.enable_topic_interstitial_ad; 14 | var enable_list_interstitial_ad = res.data.enable_list_interstitial_ad; 15 | var enable_hot_interstitial_ad = res.data.enable_hot_interstitial_ad; 16 | var enable_comments_interstitial_ad = res.data.enable_comments_interstitial_ad; 17 | var enable_live_interstitial_ad = res.data.enable_live_interstitial_ad; 18 | if (!adUnitId) return; 19 | let interstitialAd = uni.createInterstitialAd({ 20 | adUnitId: adUnitId 21 | }); // 监听插屏错误事件 22 | 23 | 24 | 25 | if (interstitialAd) { 26 | switch (pagetype) { 27 | case 'enable_index_interstitial_ad': 28 | if (enable_index_interstitial_ad == '1') { 29 | enableAd = true; 30 | } 31 | 32 | break; 33 | 34 | case 'enable_detail_interstitial_ad': 35 | if (enable_detail_interstitial_ad == '1') { 36 | enableAd = true; 37 | } 38 | 39 | break; 40 | 41 | case 'enable_topic_interstitial_ad': 42 | if (enable_topic_interstitial_ad == '1') { 43 | enableAd = true; 44 | } 45 | 46 | break; 47 | 48 | case 'enable_list_interstitial_ad': 49 | if (enable_list_interstitial_ad == '1') { 50 | enableAd = true; 51 | } 52 | 53 | break; 54 | 55 | case 'enable_hot_interstitial_ad': 56 | if (enable_hot_interstitial_ad == '1') { 57 | enableAd = true; 58 | } 59 | 60 | break; 61 | 62 | case 'enable_comments_interstitial_ad': 63 | if (enable_comments_interstitial_ad == '1') { 64 | enableAd = true; 65 | } 66 | 67 | break; 68 | 69 | case 'enable_live_interstitial_ad': 70 | if (enable_live_interstitial_ad == '1') { 71 | enableAd = true; 72 | } 73 | 74 | break; 75 | } 76 | 77 | if (enableAd) { 78 | interstitialAd.show().catch((err) => { 79 | console.error(err); 80 | }); 81 | } 82 | } 83 | }); 84 | } 85 | 86 | module.exports = { 87 | setInterstitialAd: setInterstitialAd 88 | }; 89 | -------------------------------------------------------------------------------- /utils/config.js: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * 微慕小程序开源版 4 | * author: jianbo 5 | * organization: 微慕 www.minapper.com 6 | * github: https://github.com/iamxjb/winxin-app-watch-life.net 7 | * 技术支持微信号:iamxjb 8 | * 开源协议:MIT 9 | * Copyright (c) 2017 微慕 https://www.minapper.com All rights reserved. 10 | */ 11 | //配置域名,域名只修改此处。 12 | //如果wordpress没有安装在网站根目录请加上目录路径,例如:"www.watch-life.net/blog" 13 | var DOMAIN = "www.watch-life.net"; 14 | var WEBSITENAME = "守望轩"; //网站名称 15 | 16 | var PAGECOUNT = '10'; //每页文章数目 17 | 18 | var WECHAT = '微信号:poisonkid'; //联系方式如:微信号:iamxjb 邮箱:468909765@qq.com 19 | //是否启用小程序扫描二维码登录网站 true 启用 false 不启用 20 | //未安装微慕登录插件不要启用 21 | 22 | const enableScanLogin = true; ////////////////////////////////////////////////////// 23 | //微慕小程序端版本,请勿修改 24 | 25 | const minapperVersion = 4.2; 26 | const minapperSource = "free"; ////////////////////////////////////////////////////// 27 | 28 | export default { 29 | data() { 30 | return {} 31 | }, 32 | getDomain: DOMAIN, 33 | getWebsiteName: WEBSITENAME, 34 | getPageCount: PAGECOUNT, 35 | getWecat: WECHAT, 36 | enableScanLogin, 37 | minapperVersion, 38 | minapperSource 39 | } 40 | -------------------------------------------------------------------------------- /utils/uiconfig.js: -------------------------------------------------------------------------------- 1 | //框架核心配置 2 | import ColorUI from '../mp-cu/main'; 3 | export const colorUI = new ColorUI({ 4 | config: { 5 | theme: 'auto', 6 | main: 'blue', 7 | footer: false, 8 | text: 1, 9 | tabBar: [ 10 | { 11 | title: '首页', 12 | icon: 'cicon-home-sm-o', 13 | curIcon: 'cicon-home-line', 14 | url: '/pages/index/index', 15 | type: 'tab' 16 | }, 17 | { 18 | title: '分类', 19 | icon: 'cicon-discover-o', 20 | curIcon: 'cicon-discover', 21 | url: '/pages/topic/topic', 22 | type: 'tab' 23 | }, 24 | { 25 | title: '排行', 26 | icon: 'cicon-upstage-o', 27 | curIcon: 'cicon-upstage', 28 | url: '/pages/hot/hot', 29 | type: 'tab' 30 | }, 31 | { 32 | title: '我的', 33 | icon: 'cicon-my-o', 34 | curIcon: 'cicon-my', 35 | url: '/pages/my/my', 36 | type: 'tab' 37 | } 38 | ] 39 | } 40 | }); 41 | -------------------------------------------------------------------------------- /utils/wxApi.js: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * 微慕小程序开源版 4 | * author: jianbo 5 | * organization: 微慕 www.minapper.com 6 | * github: https://github.com/iamxjb/winxin-app-watch-life.net 7 | * 技术支持微信号:iamxjb 8 | * 开源协议:MIT 9 | * *Copyright (c) 2017 https://www.minapper.com All rights reserved. 10 | * 11 | */ 12 | function wxPromisify(fn) { 13 | return function (obj = {}) { 14 | return new Promise((resolve, reject) => { 15 | obj.success = function (res) { 16 | //成功 17 | resolve(res); 18 | }; 19 | 20 | obj.fail = function (res) { 21 | //失败 22 | reject(res); 23 | }; 24 | 25 | fn(obj); 26 | }); 27 | }; 28 | } //无论promise对象最后状态如何都会执行 29 | 30 | 31 | if (!Promise.prototype.finally) { 32 | Promise.prototype.finally = function (callback) { 33 | let P = this.constructor; 34 | return this.then(value => P.resolve(callback()).then(() => value), reason => P.resolve(callback()).then(() => { 35 | throw reason; 36 | })); 37 | }; 38 | } 39 | /** 40 | * 微信用户登录,获取code 41 | */ 42 | 43 | 44 | function wxLogin() { 45 | return wxPromisify(uni.login); 46 | } 47 | /** 48 | * 获取微信用户信息 49 | * 注意:须在登录之后调用 50 | */ 51 | 52 | 53 | function wxGetUserInfo() { 54 | return wxPromisify(uni.getUserInfo); 55 | } 56 | /** 57 | * 获取系统信息 58 | */ 59 | 60 | 61 | function wxGetSystemInfo() { 62 | return wxPromisify(uni.getSystemInfo); 63 | } 64 | /** 65 | * 保留当前页面,跳转到应用内的某个页面 66 | * url:'../index/index' 67 | * params:{key:value1} 68 | */ 69 | 70 | 71 | function wxNavigateTo(url, params) { 72 | var wxNavigateTo = wxPromisify(uni.navigateTo); 73 | const serializedParams = this.paramSerializer(params); 74 | 75 | if (serializedParams.length > 0) { 76 | url += (url.indexOf('?') == -1 ? '?' : '&') + serializedParams; 77 | } 78 | 79 | return wxNavigateTo({ 80 | url: url 81 | }); 82 | } 83 | 84 | module.exports = { 85 | wxPromisify: wxPromisify, 86 | wxLogin: wxLogin, 87 | wxGetUserInfo: wxGetUserInfo, 88 | wxGetSystemInfo: wxGetSystemInfo 89 | }; -------------------------------------------------------------------------------- /utils/wxRequest.js: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * 微慕小程序开源版 4 | * author: jianbo 5 | * organization: 微慕 www.minapper.com 6 | * github: https://github.com/iamxjb/winxin-app-watch-life.net 7 | * 技术支持微信号:iamxjb 8 | * 开源协议:MIT 9 | * *Copyright (c) 2017 https://www.minapper.com All rights reserved. 10 | * 11 | */ 12 | function wxPromisify(fn) { 13 | return function (obj = {}) { 14 | return new Promise((resolve, reject) => { 15 | obj.success = function (res) { 16 | //成功 17 | uni.hideNavigationBarLoading(); 18 | resolve(res); 19 | }; 20 | 21 | obj.fail = function (res) { 22 | //失败 23 | reject(res); 24 | uni.hideNavigationBarLoading(); 25 | console.log(res); 26 | }; 27 | 28 | fn(obj); 29 | }); 30 | }; 31 | } //无论promise对象最后状态如何都会执行 32 | 33 | 34 | if (!Promise.prototype.finally) { 35 | Promise.prototype.finally = function (callback) { 36 | let P = this.constructor; 37 | uni.hideNavigationBarLoading(); 38 | return this.then(value => P.resolve(callback()).then(() => value), reason => P.resolve(callback()).then(() => { 39 | throw reason; 40 | })); 41 | }; 42 | } 43 | /** 44 | * 微信请求get方法 45 | * url 46 | * data 以对象的格式传入 47 | */ 48 | 49 | 50 | function getRequest(url, data) { 51 | var getRequest = wxPromisify(uni.request); 52 | uni.showNavigationBarLoading(); 53 | return getRequest({ 54 | url: url, 55 | method: 'GET', 56 | data: data, 57 | header: { 58 | 'Content-Type': 'application/json' 59 | } 60 | }); 61 | } 62 | /** 63 | * 微信请求post方法封装 64 | * url 65 | * data 以对象的格式传入 66 | */ 67 | 68 | 69 | function postRequest(url, data) { 70 | var postRequest = wxPromisify(uni.request); 71 | uni.showNavigationBarLoading(); 72 | return postRequest({ 73 | url: url, 74 | method: 'POST', 75 | data: data, 76 | header: { 77 | "content-type": "application/json" 78 | } 79 | }); 80 | } 81 | 82 | module.exports = { 83 | postRequest: postRequest, 84 | getRequest: getRequest 85 | }; --------------------------------------------------------------------------------