├── .editorconfig ├── .eslintrc ├── .gitignore ├── .swan └── editor.json ├── LICENSE ├── README.md ├── config ├── dev.js ├── index.js └── prod.js ├── package-lock.json ├── package.json ├── project.config.json ├── project.swan.json ├── src ├── actions │ └── counter.js ├── app.jsx ├── app.scss ├── assets │ └── images │ │ ├── courses │ │ └── bg.png │ │ ├── help │ │ ├── help_account.png │ │ ├── help_guide.png │ │ └── help_update.png │ │ ├── index │ │ ├── crown.png │ │ ├── guide_bg_left.png │ │ ├── guide_bg_right.png │ │ ├── index_bg.png │ │ ├── message.png │ │ ├── notice.png │ │ └── ok.png │ │ ├── no_data │ │ ├── address.png │ │ ├── message.png │ │ ├── network.png │ │ ├── notice.png │ │ └── record.png │ │ ├── other │ │ ├── AppPreview.jpg │ │ ├── QRCode.jpg │ │ ├── arrow_right.png │ │ ├── avatar.png │ │ └── loading.png │ │ ├── tab_bar │ │ ├── courses.png │ │ ├── courses_select.png │ │ ├── home.png │ │ ├── home_select.png │ │ ├── users.png │ │ └── users_select.png │ │ ├── tmp │ │ └── banner.jpg │ │ └── users │ │ ├── close-eyes.png │ │ ├── icon │ │ ├── course.png │ │ ├── crown.png │ │ ├── customer.png │ │ ├── help.png │ │ ├── message.png │ │ ├── notice.png │ │ ├── praise.png │ │ └── setting.png │ │ ├── open-eyes.png │ │ └── users_bg.png ├── constants │ └── counter.js ├── index.html ├── pages │ ├── courses │ │ ├── courses_list.jsx │ │ ├── courses_list.module.scss │ │ ├── index.jsx │ │ └── index.module.scss │ ├── index │ │ ├── index.jsx │ │ ├── index.module.scss │ │ ├── message_list.jsx │ │ ├── message_list.module.scss │ │ ├── notice_list.jsx │ │ ├── notice_list.module.scss │ │ ├── recomm_list.jsx │ │ └── recomm_list.module.scss │ ├── users │ │ ├── help_detail.jsx │ │ ├── help_list.jsx │ │ ├── help_list.module.scss │ │ ├── index.jsx │ │ ├── index.module.scss │ │ ├── setting.jsx │ │ └── setting.module.scss │ └── webview │ │ ├── article_detail.jsx │ │ └── index.jsx ├── reducers │ ├── counter.js │ └── index.js ├── store │ └── index.js └── utils │ ├── index.js │ └── request.js └── yarn.lock /.editorconfig: -------------------------------------------------------------------------------- 1 | # http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | indent_style = space 6 | indent_size = 2 7 | charset = utf-8 8 | trim_trailing_whitespace = true 9 | insert_final_newline = true 10 | 11 | [*.md] 12 | trim_trailing_whitespace = false 13 | -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["taro"], 3 | "rules": { 4 | "no-unused-vars": ["error", { "varsIgnorePattern": "Taro" }], 5 | "react/jsx-filename-extension": [1, { "extensions": [".js", ".jsx", ".tsx"] }] 6 | }, 7 | "parser": "babel-eslint" 8 | } 9 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | dist/ 2 | deploy_versions/ 3 | .temp/ 4 | rn_temp/ 5 | node_modules/ 6 | .DS_Store 7 | -------------------------------------------------------------------------------- /.swan/editor.json: -------------------------------------------------------------------------------- 1 | { 2 | "editor": { 3 | "curPath": "", 4 | "expands": [], 5 | "markdownUploadTimeMap": {}, 6 | "paths": [], 7 | "recentlyFiles": [] 8 | } 9 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 MichaelXu1983 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 | # 袋小鼠爱编程 2 | ## 简介 3 | 本项目是使用 [Taro](https://taro.aotu.io/) 开发的应用,目前支持 H5 和微信、QQ、百度、支付宝、字节跳动小程序。 4 | 该应用主要是面对 4-18 岁青少儿在线编程课程的学习。核心课程来自于 Code.org®,它是一家非营利组织,致力于通过在更多学校推出计算机科学,以及增加女性和代表性不足的学生的参与度来扩大计算机科学的参与。他们很自豪能够在全球范围内完全免费提供他们的所有课程和课程内容,而无需任何必要的合作伙伴关系来在您的学校或组织中使用我们的材料!而我们也基于此种精神,致力于扩大 4-18 岁中国孩子学习计算机科学的机会,尽可能帮助他们从小建立编程思维,从而培养解决问题的能力。 5 | 我们的愿景是:让中国每个学校的每个学生都能像语文、数学、外语一样学习计算机科学。 6 | 7 | ## 截图 8 | 9 | ![](./src/assets/images/other/AppPreview.jpg) 10 | 11 | ![](./src/assets/images/other/QRCode.jpg) 12 | 13 | ## 目录 14 | 1. [环境安装](#环境安装) 15 | * [安装Nvm](#安装Nvm) 16 | * [安装Node](#安装Node) 17 | * [安装Nrm](#安装Nrm) 18 | * [安装Homebrew](#安装Homebrew) 19 | * [安装Yarn](#安装Yarn) 20 | * [安装Tarojs](#安装Tarojs) 21 | 2. [学习Tarojs](#学习Tarojs) 22 | * [开发前注意事项](#开发前注意事项) 23 | * [特殊问题的处理](#特殊问题的处理) 24 | * [教程](#教程) 25 | 3. [使用Tarojs](#使用Tarojs) 26 | * [创建项目](#创建项目) 27 | * [配置项目](#配置项目) 28 | * [开启CSS Modules](#开启CSSModules) 29 | * [设置alias别名](#设置alias别名) 30 | * [自定义主题](#自定义主题) 31 | 32 | ## 环境安装 33 | ### 安装Nvm 34 | ```shell 35 | # 安装 nvm (npm 安装和版本管理工具,最新版本请到 https://github.com/nvm-sh/nvm 查看) 36 | curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.34.0/install.sh | bash 37 | ``` 38 | 39 | ### 安装Node 40 | ```shell 41 | # 其他版本号,请查看 https://nodejs.org/zh-cn/download/releases/ ,也可执行 `npm install -g n` 和 `sudo n stable` 命令升级 42 | nvm install 8.16.0 43 | ``` 44 | 45 | ### 安装Nrm 46 | ```shell 47 | # 安装 nrm 48 | npm install -g nrm 49 | 50 | # 列出 npm 源列表 51 | nrm ls 52 | 53 | # 切换为淘宝源 54 | nrm use taobao 55 | ``` 56 | 57 | ### 安装Homebrew 58 | ```shell 59 | # 安装 Homebrew(Mac 系统的包管理器,用于安装 macOS 没有预装,但你需要的东西) 60 | /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)" 61 | 62 | # 卸载 Homebrew 63 | /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/uninstall)" 64 | 65 | # 验证 Homebrew 是否正确安装 66 | brew doctor 67 | 68 | # 修改 Homebrew 源(因为默认是链接国外服务器,速度会很慢,此处修改为国内的) 69 | cd "$(brew --repo)" 70 | git remote set-url origin https://mirrors.tuna.tsinghua.edu.cn/git/homebrew/brew.git 71 | cd "$(brew --repo)/Library/Taps/homebrew/homebrew-core" 72 | git remote set-url origin https://mirrors.tuna.tsinghua.edu.cn/git/homebrew/homebrew-core.git 73 | ``` 74 | 75 | ### 安装Yarn 76 | ```shell 77 | # 安装 yarn (如果您选择手动安装,用以下步骤添加 Yarn 到 path 变量) 78 | brew install yarn --ignore-dependencies 79 | 80 | # 修改 yarn 源 81 | yarn config set registry https://registry.npm.taobao.org --global 82 | yarn config set disturl https://npm.taobao.org/dist --global 83 | ``` 84 | 85 | ### 安装Tarojs 86 | ```shell 87 | # 安装最新的 @tarojs/cli 88 | npm i -g @tarojs/cli@latest 89 | 90 | # 或者 91 | yarn global add @tarojs/cli@latest 92 | ``` 93 | 94 | ## 学习Tarojs 95 | ### 开发前注意事项 96 | [传送门](https://nervjs.github.io/taro/docs/before-dev-remind.html) 97 | 98 | ### 特殊问题的处理 99 | [传送门](https://nervjs.github.io/taro/docs/specials.html) 100 | 101 | ### 教程 102 | [传送门](https://nervjs.github.io/taro/docs/spec-for-taro.html) 103 | 104 | ### 进阶指南 105 | [传送门](https://nervjs.github.io/taro/docs/config.html) 106 | 107 | ## 使用Tarojs 108 | ### 创建项目 109 | ``` 110 | # 初始化项目,并按提示输入项目相关信息 111 | taro init student-multi-web-client 112 | ``` 113 | 114 | ### 配置项目 115 | ```shell 116 | 👽 Taro v1.3.13 117 | 118 | Taro即将创建一个新项目! 119 | Need help? Go and open issue: https://github.com/NervJS/taro/issues/new 120 | 121 | ✔ 拉取远程模板仓库成功! 122 | ? 请输入项目介绍! 学生web多端 123 | ? 是否需要使用 TypeScript ? No 124 | ? 请选择 CSS 预处理器(Sass/Less/Stylus) Sass 125 | ? 请选择模板 redux 126 | 127 | ✔ 创建项目: student-multi-web-client 128 | ✔ 创建文件: student-multi-web-client/.editorconfig 129 | ✔ 创建文件: student-multi-web-client/.eslintrc 130 | ✔ 创建文件: student-multi-web-client/.gitignore 131 | ✔ 创建文件: student-multi-web-client/package.json 132 | ✔ 创建文件: student-multi-web-client/project.config.json 133 | ✔ 创建文件: student-multi-web-client/config/dev.js 134 | ✔ 创建文件: student-multi-web-client/config/index.js 135 | ✔ 创建文件: student-multi-web-client/config/prod.js 136 | ✔ 创建文件: student-multi-web-client/src/app.scss 137 | ✔ 创建文件: student-multi-web-client/src/app.jsx 138 | ✔ 创建文件: student-multi-web-client/src/index.html 139 | ✔ 创建文件: student-multi-web-client/src/actions/counter.js 140 | ✔ 创建文件: student-multi-web-client/src/constants/counter.js 141 | ✔ 创建文件: student-multi-web-client/src/reducers/counter.js 142 | ✔ 创建文件: student-multi-web-client/src/reducers/index.js 143 | ✔ 创建文件: student-multi-web-client/src/store/index.js 144 | ✔ 创建文件: student-multi-web-client/src/pages/index/index.scss 145 | ✔ 创建文件: student-multi-web-client/src/pages/index/index.jsx 146 | 147 | ✔ cd student-multi-web-client, 执行 git init 148 | ✔ 安装成功 149 | warning @tarojs/webpack-runner > dart-sass@1.17.3: use the "sass" package instead 150 | warning @tarojs/webpack-runner > webpack-format-messages > kleur@2.0.2: Please upgrade to kleur@3 or migrate to 'ansi-colors' if you prefer the old syntax. Visit for migration path(s). 151 | warning stylelint > file-entry-cache > flat-cache > circular-json@0.3.3: CircularJSON is in maintenance only, flatted is its successor. 152 | yarn install v1.6.0 153 | info No lockfile found. 154 | [1/4] Resolving packages... 155 | [2/4] Fetching packages... 156 | [3/4] Linking dependencies... 157 | [4/4] Building fresh packages... 158 | success Saved lockfile. 159 | Done in 60.08s. 160 | 161 | 创建项目 student-multi-web-client 成功! 162 | 请进入项目目录 student-multi-web-client 开始工作吧!😝 163 | ``` 164 | 165 | ### 开启 CSS Modules 166 | [传送门](https://taro-docs.jd.com/taro/docs/css-modules.html) 167 | 168 | ```bash 169 | vim index.module.scss 170 | 171 | ... 172 | .text { 173 | color: #ff0; 174 | } 175 | 176 | :global { 177 | .taro-text { 178 | color: #ff0; 179 | } 180 | } 181 | ... 182 | 183 | ``` 184 | 185 | ### 设置 alias 别名 186 | ```shell 187 | vim config/index.js 188 | ``` 189 | ```js 190 | const path = require('path') 191 | ... 192 | defineConstants: { 193 | }, 194 | alias: { 195 | '@/src': path.resolve(__dirname, '..', 'src'), 196 | }, 197 | copy: { 198 | patterns: [ 199 | ], 200 | options: { 201 | } 202 | }, 203 | ... 204 | ``` 205 | 206 | ### 自定义主题 207 | > RN 端不支持 208 | [传送门](https://nervjs.github.io/taro/docs/css-modules.html) 209 | ```shell 210 | # 安装 Taro UI 主题 211 | npm install taro-ui 212 | 213 | # 使用自定义主题生成器生成主题文件 custom-theme.scss:https://nervjs.github.io/taro-ui-theme-preview/ 214 | 215 | # 引用主题样式 216 | cp custom-theme.scss src 217 | vim custom-theme.scss // 引入 Taro UI 默认样式:@import "~taro-ui/dist/style/index.scss" 218 | vim app.jsx // 引入 Taro UI 主题样式:import './custom-theme.scss' 219 | ``` -------------------------------------------------------------------------------- /config/dev.js: -------------------------------------------------------------------------------- 1 | // eslint-disable-next-line import/no-commonjs 2 | module.exports = { 3 | env: { 4 | NODE_ENV: '"development"' 5 | }, 6 | defineConstants: { 7 | }, 8 | weapp: {}, 9 | h5: {} 10 | } 11 | -------------------------------------------------------------------------------- /config/index.js: -------------------------------------------------------------------------------- 1 | // eslint-disable-next-line import/no-commonjs 2 | const path = require("path"); 3 | 4 | const config = { 5 | projectName: "student-multi-web-client", 6 | date: "2020-2-3", 7 | designWidth: 750, 8 | deviceRatio: { 9 | "640": 2.34 / 2, 10 | "750": 1, 11 | "828": 1.81 / 2 12 | }, 13 | sourceRoot: "src", 14 | outputRoot: "dist", 15 | babel: { 16 | sourceMap: true, 17 | presets: [ 18 | [ 19 | "env", 20 | { 21 | modules: false 22 | } 23 | ] 24 | ], 25 | plugins: [ 26 | "transform-decorators-legacy", 27 | "transform-class-properties", 28 | "transform-object-rest-spread", 29 | [ 30 | "transform-runtime", 31 | { 32 | helpers: false, 33 | polyfill: false, 34 | regenerator: true, 35 | moduleName: "babel-runtime" 36 | } 37 | ] 38 | ] 39 | }, 40 | defineConstants: {}, 41 | alias: { 42 | "@/src": path.resolve(__dirname, "..", "src") 43 | }, 44 | mini: { 45 | postcss: { 46 | autoprefixer: { 47 | enable: true, 48 | config: { 49 | browsers: ["last 3 versions", "Android >= 4.1", "ios >= 8"] 50 | } 51 | }, 52 | pxtransform: { 53 | enable: true, 54 | config: {} 55 | }, 56 | url: { 57 | enable: true, 58 | config: { 59 | limit: 10240 // 设定转换尺寸上限 60 | } 61 | }, 62 | cssModules: { 63 | enable: true, // 默认为 false,如需使用 css modules 功能,则设为 true 64 | config: { 65 | namingPattern: "module", // 转换模式,取值为 global/module 66 | generateScopedName: "[name]__[local]___[hash:base64:5]" 67 | } 68 | } 69 | } 70 | }, 71 | h5: { 72 | publicPath: "/", 73 | staticDirectory: "static", 74 | postcss: { 75 | autoprefixer: { 76 | enable: true, 77 | config: { 78 | browsers: ["last 3 versions", "Android >= 4.1", "ios >= 8"] 79 | } 80 | }, 81 | cssModules: { 82 | enable: true, // 默认为 false,如需使用 css modules 功能,则设为 true 83 | config: { 84 | namingPattern: "module", // 转换模式,取值为 global/module 85 | generateScopedName: "[name]__[local]___[hash:base64:5]" 86 | } 87 | } 88 | } 89 | } 90 | }; 91 | 92 | module.exports = function(merge) { 93 | if (process.env.NODE_ENV === "development") { 94 | return merge({}, config, require("./dev")); 95 | } 96 | return merge({}, config, require("./prod")); 97 | }; 98 | -------------------------------------------------------------------------------- /config/prod.js: -------------------------------------------------------------------------------- 1 | // eslint-disable-next-line import/no-commonjs 2 | module.exports = { 3 | env: { 4 | NODE_ENV: '"production"' 5 | }, 6 | defineConstants: { 7 | }, 8 | weapp: {}, 9 | h5: { 10 | /** 11 | * 如果h5端编译后体积过大,可以使用webpack-bundle-analyzer插件对打包体积进行分析。 12 | * 参考代码如下: 13 | * webpackChain (chain) { 14 | * chain.plugin('analyzer') 15 | * .use(require('webpack-bundle-analyzer').BundleAnalyzerPlugin, []) 16 | * } 17 | */ 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "student-multi-web-client", 3 | "version": "1.0.0", 4 | "private": true, 5 | "description": "学生web多端", 6 | "templateInfo": { 7 | "name": "redux", 8 | "typescript": false, 9 | "css": "sass" 10 | }, 11 | "scripts": { 12 | "build:weapp": "taro build --type weapp", 13 | "build:qq": "taro build --type qq", 14 | "build:swan": "taro build --type swan", 15 | "build:alipay": "taro build --type alipay", 16 | "build:tt": "taro build --type tt", 17 | "build:h5": "taro build --type h5", 18 | "build:rn": "taro build --type rn", 19 | "dev:weapp": "npm run build:weapp -- --watch", 20 | "dev:qq": "npm run build:qq -- --watch", 21 | "dev:swan": "npm run build:swan -- --watch", 22 | "dev:alipay": "npm run build:alipay -- --watch", 23 | "dev:tt": "npm run build:tt -- --watch", 24 | "dev:h5": "npm run build:h5 -- --watch", 25 | "dev:rn": "npm run build:rn -- --watch" 26 | }, 27 | "author": "", 28 | "license": "MIT", 29 | "dependencies": { 30 | "@tarojs/components": "2.0.3", 31 | "@tarojs/redux": "2.0.3", 32 | "@tarojs/redux-h5": "2.0.3", 33 | "@tarojs/router": "2.0.3", 34 | "@tarojs/taro": "2.0.3", 35 | "@tarojs/taro-alipay": "2.0.3", 36 | "@tarojs/taro-h5": "2.0.3", 37 | "@tarojs/taro-qq": "2.0.3", 38 | "@tarojs/taro-rn": "^2.0.3", 39 | "@tarojs/taro-swan": "2.0.3", 40 | "@tarojs/taro-tt": "2.0.3", 41 | "@tarojs/taro-weapp": "2.0.3", 42 | "babel-runtime": "^6.26.0", 43 | "nerv-devtools": "^1.5.6", 44 | "nervjs": "^1.5.6", 45 | "redux": "^4.0.0", 46 | "redux-logger": "^3.0.6", 47 | "redux-thunk": "^2.3.0", 48 | "@tarojs/components-rn": "^2.0.3", 49 | "@tarojs/taro-router-rn": "^2.0.3", 50 | "@tarojs/taro-redux-rn": "^2.0.3", 51 | "react": "16.8.0", 52 | "react-native": "0.59.9", 53 | "tslib": "^1.8.0" 54 | }, 55 | "devDependencies": { 56 | "@tarojs/mini-runner": "2.0.3", 57 | "@tarojs/plugin-babel": "2.0.3", 58 | "@tarojs/plugin-csso": "2.0.3", 59 | "@tarojs/plugin-sass": "2.0.3", 60 | "@tarojs/plugin-uglifyjs": "2.0.3", 61 | "@tarojs/webpack-runner": "2.0.3", 62 | "@types/react": "^16.4.8", 63 | "@types/webpack-env": "^1.13.6", 64 | "babel-eslint": "^8.2.3", 65 | "babel-plugin-transform-class-properties": "^6.24.1", 66 | "babel-plugin-transform-decorators-legacy": "^1.3.4", 67 | "babel-plugin-transform-jsx-stylesheet": "^0.6.5", 68 | "babel-plugin-transform-object-rest-spread": "^6.26.0", 69 | "babel-plugin-transform-runtime": "^6.23.0", 70 | "babel-preset-env": "^1.6.1", 71 | "eslint": "^5.16.0", 72 | "eslint-config-taro": "2.0.3", 73 | "eslint-plugin-import": "^2.12.0", 74 | "eslint-plugin-react": "^7.8.2", 75 | "eslint-plugin-react-hooks": "^1.6.1", 76 | "eslint-plugin-taro": "2.0.3", 77 | "stylelint": "9.3.0", 78 | "stylelint-config-taro-rn": "2.0.3", 79 | "stylelint-taro-rn": "2.0.3" 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /project.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "miniprogramRoot": "dist/", 3 | "projectname": "student-multi-web-client", 4 | "description": "学生web多端", 5 | "appid": "wx40bb0d56af8e4e3c", 6 | "setting": { 7 | "urlCheck": true, 8 | "es6": false, 9 | "postcss": false, 10 | "minified": false, 11 | "newFeature": true 12 | }, 13 | "compileType": "miniprogram", 14 | "simulatorType": "wechat", 15 | "simulatorPluginLibVersion": {}, 16 | "qqappid": "1109760374", 17 | "scripts": { 18 | "beforeCompile": "", 19 | "beforePreview": "", 20 | "beforeUpload": "" 21 | }, 22 | "condition": {} 23 | } -------------------------------------------------------------------------------- /project.swan.json: -------------------------------------------------------------------------------- 1 | { 2 | "appid": "16977080", 3 | "compilation-args": { 4 | "options": [], 5 | "selected": 0 6 | }, 7 | "developType": "normal", 8 | "editor": { 9 | "curPath": "", 10 | "expands": [], 11 | "markdownUploadTimeMap": {}, 12 | "paths": [], 13 | "recentlyFiles": [] 14 | }, 15 | "host": "baiduboxapp", 16 | "preview": { 17 | "packageId": 611816 18 | }, 19 | "projectname": "StudentMultiWebClient", 20 | "publish": { 21 | "version": "1.2.1.0" 22 | }, 23 | "setting": { 24 | "urlCheck": true 25 | }, 26 | "smartProgramRoot": "dist/", 27 | "swan": { 28 | "baiduboxapp": { 29 | "extensionJsVersion": "1.4.5", 30 | "swanJsVersion": "3.90.7" 31 | } 32 | } 33 | } -------------------------------------------------------------------------------- /src/actions/counter.js: -------------------------------------------------------------------------------- 1 | import { 2 | ADD, 3 | MINUS 4 | } from '../constants/counter' 5 | 6 | export const add = () => { 7 | return { 8 | type: ADD 9 | } 10 | } 11 | export const minus = () => { 12 | return { 13 | type: MINUS 14 | } 15 | } 16 | 17 | // 异步的action 18 | export function asyncAdd () { 19 | return dispatch => { 20 | setTimeout(() => { 21 | dispatch(add()) 22 | }, 2000) 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/app.jsx: -------------------------------------------------------------------------------- 1 | import Taro, { Component } from "@tarojs/taro"; 2 | import { Provider } from "@tarojs/redux"; 3 | 4 | import Index from "./pages/index"; 5 | 6 | import configStore from "./store"; 7 | 8 | import "./app.scss"; 9 | 10 | // import { getSystemInfo } from '@/src/utils/index' 11 | 12 | // 如果需要在 h5 环境中开启 React Devtools 13 | // 取消以下注释: 14 | // if (process.env.NODE_ENV !== 'production' && process.env.TARO_ENV === 'h5') { 15 | // require('nerv-devtools') 16 | // } 17 | 18 | const store = configStore(); 19 | 20 | class App extends Component { 21 | config = { 22 | pages: [ 23 | "pages/index/index", 24 | "pages/index/notice_list", 25 | // "pages/index/message_list", 26 | "pages/index/recomm_list", 27 | "pages/courses/index", 28 | "pages/courses/courses_list", 29 | "pages/users/index", 30 | "pages/users/setting", 31 | "pages/users/help_list", 32 | "pages/users/help_detail", 33 | "pages/webview/index", 34 | "pages/webview/article_detail", 35 | ], 36 | window: { 37 | navigationBarBackgroundColor: "#fff", 38 | navigationBarTitleText: "袋小鼠爱编程", 39 | navigationBarTextStyle: "black", 40 | navigationStyle: "default", // 导航栏样式:default 默认样式;custom 自定义导航栏,只保留右上角胶囊按钮 41 | backgroundColor: "#f7f7f9", // 窗口的背景色 42 | backgroundColorTop: "#ffffff", // 顶部窗口的背景色,仅 iOS 支持 43 | backgroundColorBottom: "#ffffff", // 底部窗口的背景色,仅 iOS 支持 44 | enablePullDownRefresh: false, // 是否开启当前页面的下拉刷新 45 | backgroundTextStyle: "light", // 下拉 loading 的样式,仅支持 dark / light 46 | onReachBottomDistance: 200, // 页面上拉触底事件触发时距页面底部距离,单位为 px 47 | pageOrientation: "auto", // 屏幕旋转设置,支持 auto / portrait / landscape 48 | disableSwipeBack: false, // 禁止页面右滑手势返回 49 | }, 50 | tabBar: { 51 | list: [ 52 | { 53 | pagePath: "pages/index/index", // 页面路径,必须在 pages 中先定义 54 | text: "首页", 55 | iconPath: "./assets/images/tab_bar/home.png", 56 | selectedIconPath: "./assets/images/tab_bar/home_select.png", //icon 大小限制为40kb,建议尺寸为 81px * 81px,不支持网络图片。当 position 为 top 时,不显示 icon 57 | }, 58 | { 59 | pagePath: "pages/courses/index", 60 | text: "课程", 61 | iconPath: "./assets/images/tab_bar/courses.png", 62 | selectedIconPath: "./assets/images/tab_bar/courses_select.png", 63 | }, 64 | { 65 | pagePath: "pages/users/index", 66 | text: "我的", 67 | iconPath: "./assets/images/tab_bar/users.png", 68 | selectedIconPath: "./assets/images/tab_bar/users_select.png", 69 | }, 70 | ], 71 | position: "bottom", // tabBar的位置,仅支持 bottom / top 72 | custom: false, // 自定义 tabBar 73 | color: "#8a8a8a", 74 | selectedColor: "#7d4c9f", 75 | backgroundColor: "#fff", 76 | borderStyle: "black", 77 | }, 78 | networkTimeout: { 79 | request: 6000, 80 | connectSocket: 10000, 81 | uploadFile: 10000, 82 | downloadFile: 10000, 83 | }, 84 | debug: true, 85 | }; 86 | 87 | // componentDidMount() { 88 | // getSystemInfo() // 获取设备信息,并储存 LS 89 | // } 90 | 91 | componentDidShow() {} 92 | 93 | componentDidHide() {} 94 | 95 | componentDidCatchError() {} 96 | 97 | // 在 App 类中的 render() 函数没有实际作用 98 | // 请勿修改此函数 99 | render() { 100 | return ( 101 | 102 | 103 | 104 | ); 105 | } 106 | } 107 | 108 | Taro.render(, document.getElementById("app")); 109 | -------------------------------------------------------------------------------- /src/app.scss: -------------------------------------------------------------------------------- 1 | // 建议将 RN 不支持的但 H5 端又必不可少的样式放到下面 postcss-pxtransform... 标签内,组件的引入样式的优先级高于全局样式的优先级,处理器借助 css-to-react-native 将 Scss/Less 样式转换为 RN Stylesheet objects。如:样式重制相关的代码,不支持组合选择器的写法,不支持伪类及伪元素 2 | // RN 只支持 Flex 布局,参考:http://www.ruanyifeng.com/blog/2015/07/flex-grammar.html 3 | // RN 支持CSS属性,参考:https://nervjs.github.io/taro/docs/before-dev-remind.html,https://reactnative.cn/docs/0.47/layout-props.html 4 | // RN 已知不支持:box-shadow,animation,transform 5 | /*postcss-pxtransform rn eject enable*/ 6 | 7 | body { 8 | padding: 0; 9 | margin: 0; 10 | background-color: #fff; 11 | } 12 | .fixed { 13 | bottom: 0; 14 | /* 在 H5 模式下 tabBar 可能会挡住页面 fixed 元素问题,所以以下代码将会编译成 margin-bottom: 50px,在小程序模式下则会忽略,来解决此问题*/ 15 | margin-bottom: taro-tabbar-height; 16 | } 17 | /*postcss-pxtransform rn eject disable*/ 18 | /* 该自定义组件的默认样式 */ 19 | 20 | /* user-defined 21 | ========================================================================== */ 22 | 23 | /** 24 | * Empty 25 | */ 26 | .global-empty { 27 | width: 300px; 28 | margin: 120px auto; 29 | /* #ifndef rn */ 30 | text-align: center; 31 | /* #endif */ 32 | } 33 | .global-empty__pic, 34 | .global-empty__intro { 35 | width: 300px; 36 | margin: 20px auto; 37 | } 38 | .global-empty__pic-img { 39 | width: 300px; 40 | height: 300px; 41 | } 42 | .global-empty__text { 43 | font-size: 28px; 44 | color: #777; 45 | text-align: center; 46 | } 47 | /** 48 | * Button 49 | */ 50 | .am-button-primary, 51 | .am-button-disabled, 52 | .am-button-ghost { 53 | margin: 60px 0 0 0; 54 | } 55 | .am-button-primary { 56 | /* #ifndef rn */ 57 | background-image: linear-gradient(-135deg, #69409e 0%, #dd84a5 100%); 58 | /* #endif */ 59 | background-color: #6b40bd; 60 | border-color: transparent; 61 | } 62 | .am-button-disabled { 63 | /* #ifndef rn */ 64 | background-image: linear-gradient(90deg, #e0e0e0 0%, #afafaf 100%); 65 | /* #endif */ 66 | background-color: #afafaf; 67 | border-color: transparent; 68 | } 69 | .am-button-ghost { 70 | border: 2px solid #aa66a2; 71 | border-color: #aa66a2; 72 | } 73 | .am-button-primary-text, 74 | .am-button-ghost-text { 75 | letter-spacing: 4px; 76 | } 77 | .am-button-primary-text { 78 | color: #fff; 79 | } 80 | .am-button-ghost-text { 81 | color: #aa66a2; 82 | } 83 | .am-buttons { 84 | margin: 60px 5%; 85 | } 86 | /** 87 | * Empty 88 | */ 89 | .article-detail { 90 | min-height: 100%; 91 | padding: 40px; 92 | } 93 | .article-detail__title { 94 | margin: 20px 0; 95 | font-size: 38px; 96 | font-weight: bold; 97 | text-align: left; 98 | } 99 | .article-detail__subtitle { 100 | margin-bottom: 20px; 101 | font-size: 30px; 102 | font-weight: bold; 103 | text-align: left; 104 | } 105 | .article-detail__text { 106 | margin-bottom: 20px; 107 | font-size: 30px; 108 | line-height: 60px; 109 | color: #444; 110 | text-align: left; 111 | } 112 | .article-detail__img { 113 | width: 100%; 114 | margin: 20px auto; 115 | } 116 | .article-detail__img-block { 117 | /* #ifndef rn */ 118 | display: block; 119 | /* #endif */ 120 | max-width: 100%; 121 | margin: 20px auto; 122 | } 123 | .article-detail__richtext { 124 | max-width: 100%; 125 | min-height: 100%; 126 | text-align: left; 127 | img { 128 | max-width: 100%; 129 | height: auto !important; 130 | } 131 | } 132 | .article-detail__richtext img { 133 | max-width: 100%; 134 | height: auto !important; 135 | } 136 | -------------------------------------------------------------------------------- /src/assets/images/courses/bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MichaelXu1983/StudentMultiWebClient/3f85db539eed9932d296d6b677990b4eaea11283/src/assets/images/courses/bg.png -------------------------------------------------------------------------------- /src/assets/images/help/help_account.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MichaelXu1983/StudentMultiWebClient/3f85db539eed9932d296d6b677990b4eaea11283/src/assets/images/help/help_account.png -------------------------------------------------------------------------------- /src/assets/images/help/help_guide.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MichaelXu1983/StudentMultiWebClient/3f85db539eed9932d296d6b677990b4eaea11283/src/assets/images/help/help_guide.png -------------------------------------------------------------------------------- /src/assets/images/help/help_update.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MichaelXu1983/StudentMultiWebClient/3f85db539eed9932d296d6b677990b4eaea11283/src/assets/images/help/help_update.png -------------------------------------------------------------------------------- /src/assets/images/index/crown.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MichaelXu1983/StudentMultiWebClient/3f85db539eed9932d296d6b677990b4eaea11283/src/assets/images/index/crown.png -------------------------------------------------------------------------------- /src/assets/images/index/guide_bg_left.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MichaelXu1983/StudentMultiWebClient/3f85db539eed9932d296d6b677990b4eaea11283/src/assets/images/index/guide_bg_left.png -------------------------------------------------------------------------------- /src/assets/images/index/guide_bg_right.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MichaelXu1983/StudentMultiWebClient/3f85db539eed9932d296d6b677990b4eaea11283/src/assets/images/index/guide_bg_right.png -------------------------------------------------------------------------------- /src/assets/images/index/index_bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MichaelXu1983/StudentMultiWebClient/3f85db539eed9932d296d6b677990b4eaea11283/src/assets/images/index/index_bg.png -------------------------------------------------------------------------------- /src/assets/images/index/message.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MichaelXu1983/StudentMultiWebClient/3f85db539eed9932d296d6b677990b4eaea11283/src/assets/images/index/message.png -------------------------------------------------------------------------------- /src/assets/images/index/notice.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MichaelXu1983/StudentMultiWebClient/3f85db539eed9932d296d6b677990b4eaea11283/src/assets/images/index/notice.png -------------------------------------------------------------------------------- /src/assets/images/index/ok.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MichaelXu1983/StudentMultiWebClient/3f85db539eed9932d296d6b677990b4eaea11283/src/assets/images/index/ok.png -------------------------------------------------------------------------------- /src/assets/images/no_data/address.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MichaelXu1983/StudentMultiWebClient/3f85db539eed9932d296d6b677990b4eaea11283/src/assets/images/no_data/address.png -------------------------------------------------------------------------------- /src/assets/images/no_data/message.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MichaelXu1983/StudentMultiWebClient/3f85db539eed9932d296d6b677990b4eaea11283/src/assets/images/no_data/message.png -------------------------------------------------------------------------------- /src/assets/images/no_data/network.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MichaelXu1983/StudentMultiWebClient/3f85db539eed9932d296d6b677990b4eaea11283/src/assets/images/no_data/network.png -------------------------------------------------------------------------------- /src/assets/images/no_data/notice.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MichaelXu1983/StudentMultiWebClient/3f85db539eed9932d296d6b677990b4eaea11283/src/assets/images/no_data/notice.png -------------------------------------------------------------------------------- /src/assets/images/no_data/record.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MichaelXu1983/StudentMultiWebClient/3f85db539eed9932d296d6b677990b4eaea11283/src/assets/images/no_data/record.png -------------------------------------------------------------------------------- /src/assets/images/other/AppPreview.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MichaelXu1983/StudentMultiWebClient/3f85db539eed9932d296d6b677990b4eaea11283/src/assets/images/other/AppPreview.jpg -------------------------------------------------------------------------------- /src/assets/images/other/QRCode.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MichaelXu1983/StudentMultiWebClient/3f85db539eed9932d296d6b677990b4eaea11283/src/assets/images/other/QRCode.jpg -------------------------------------------------------------------------------- /src/assets/images/other/arrow_right.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MichaelXu1983/StudentMultiWebClient/3f85db539eed9932d296d6b677990b4eaea11283/src/assets/images/other/arrow_right.png -------------------------------------------------------------------------------- /src/assets/images/other/avatar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MichaelXu1983/StudentMultiWebClient/3f85db539eed9932d296d6b677990b4eaea11283/src/assets/images/other/avatar.png -------------------------------------------------------------------------------- /src/assets/images/other/loading.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MichaelXu1983/StudentMultiWebClient/3f85db539eed9932d296d6b677990b4eaea11283/src/assets/images/other/loading.png -------------------------------------------------------------------------------- /src/assets/images/tab_bar/courses.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MichaelXu1983/StudentMultiWebClient/3f85db539eed9932d296d6b677990b4eaea11283/src/assets/images/tab_bar/courses.png -------------------------------------------------------------------------------- /src/assets/images/tab_bar/courses_select.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MichaelXu1983/StudentMultiWebClient/3f85db539eed9932d296d6b677990b4eaea11283/src/assets/images/tab_bar/courses_select.png -------------------------------------------------------------------------------- /src/assets/images/tab_bar/home.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MichaelXu1983/StudentMultiWebClient/3f85db539eed9932d296d6b677990b4eaea11283/src/assets/images/tab_bar/home.png -------------------------------------------------------------------------------- /src/assets/images/tab_bar/home_select.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MichaelXu1983/StudentMultiWebClient/3f85db539eed9932d296d6b677990b4eaea11283/src/assets/images/tab_bar/home_select.png -------------------------------------------------------------------------------- /src/assets/images/tab_bar/users.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MichaelXu1983/StudentMultiWebClient/3f85db539eed9932d296d6b677990b4eaea11283/src/assets/images/tab_bar/users.png -------------------------------------------------------------------------------- /src/assets/images/tab_bar/users_select.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MichaelXu1983/StudentMultiWebClient/3f85db539eed9932d296d6b677990b4eaea11283/src/assets/images/tab_bar/users_select.png -------------------------------------------------------------------------------- /src/assets/images/tmp/banner.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MichaelXu1983/StudentMultiWebClient/3f85db539eed9932d296d6b677990b4eaea11283/src/assets/images/tmp/banner.jpg -------------------------------------------------------------------------------- /src/assets/images/users/close-eyes.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MichaelXu1983/StudentMultiWebClient/3f85db539eed9932d296d6b677990b4eaea11283/src/assets/images/users/close-eyes.png -------------------------------------------------------------------------------- /src/assets/images/users/icon/course.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MichaelXu1983/StudentMultiWebClient/3f85db539eed9932d296d6b677990b4eaea11283/src/assets/images/users/icon/course.png -------------------------------------------------------------------------------- /src/assets/images/users/icon/crown.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MichaelXu1983/StudentMultiWebClient/3f85db539eed9932d296d6b677990b4eaea11283/src/assets/images/users/icon/crown.png -------------------------------------------------------------------------------- /src/assets/images/users/icon/customer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MichaelXu1983/StudentMultiWebClient/3f85db539eed9932d296d6b677990b4eaea11283/src/assets/images/users/icon/customer.png -------------------------------------------------------------------------------- /src/assets/images/users/icon/help.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MichaelXu1983/StudentMultiWebClient/3f85db539eed9932d296d6b677990b4eaea11283/src/assets/images/users/icon/help.png -------------------------------------------------------------------------------- /src/assets/images/users/icon/message.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MichaelXu1983/StudentMultiWebClient/3f85db539eed9932d296d6b677990b4eaea11283/src/assets/images/users/icon/message.png -------------------------------------------------------------------------------- /src/assets/images/users/icon/notice.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MichaelXu1983/StudentMultiWebClient/3f85db539eed9932d296d6b677990b4eaea11283/src/assets/images/users/icon/notice.png -------------------------------------------------------------------------------- /src/assets/images/users/icon/praise.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MichaelXu1983/StudentMultiWebClient/3f85db539eed9932d296d6b677990b4eaea11283/src/assets/images/users/icon/praise.png -------------------------------------------------------------------------------- /src/assets/images/users/icon/setting.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MichaelXu1983/StudentMultiWebClient/3f85db539eed9932d296d6b677990b4eaea11283/src/assets/images/users/icon/setting.png -------------------------------------------------------------------------------- /src/assets/images/users/open-eyes.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MichaelXu1983/StudentMultiWebClient/3f85db539eed9932d296d6b677990b4eaea11283/src/assets/images/users/open-eyes.png -------------------------------------------------------------------------------- /src/assets/images/users/users_bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MichaelXu1983/StudentMultiWebClient/3f85db539eed9932d296d6b677990b4eaea11283/src/assets/images/users/users_bg.png -------------------------------------------------------------------------------- /src/constants/counter.js: -------------------------------------------------------------------------------- 1 | export const ADD = 'ADD' 2 | export const MINUS = 'MINUS' 3 | -------------------------------------------------------------------------------- /src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 15 | 16 | 17 |
18 | 19 | 20 | -------------------------------------------------------------------------------- /src/pages/courses/courses_list.jsx: -------------------------------------------------------------------------------- 1 | import Taro, { Component } from '@tarojs/taro' 2 | import { View, Image, Text, Navigator } from '@tarojs/components' 3 | import coursesListBg from '@/src/assets/images/courses/bg.png' 4 | import styles from './courses_list.module.scss' 5 | 6 | class CoursesList extends Component { 7 | 8 | constructor() { 9 | super(...arguments) 10 | this.state = { 11 | courseId: 1 12 | } 13 | this.env = process.env.TARO_ENV 14 | } 15 | componentWillMount() { 16 | this.setState({ 17 | courseId: this.$router.params.courseId 18 | }) 19 | } 20 | config = { 21 | navigationBarTitleText: '课程', 22 | } 23 | render() { 24 | const { courseId } = this.state 25 | return ( 26 | 27 | 28 | 29 | 30 | 课程 {courseId} 31 | 32 | 33 | 旨在能让初学者创建计算机程序,在这个过程中帮助他们学习如何与他人进行协作、提高解决问题的能力,并通过不断努力完成艰巨的任务。 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 游戏实验室 43 | 44 | 45 | 46 | 总共 12 小节 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 游戏实验室 57 | 58 | 59 | 60 | 总共 12 小节 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | ) 69 | } 70 | } 71 | export default CoursesList 72 | -------------------------------------------------------------------------------- /src/pages/courses/courses_list.module.scss: -------------------------------------------------------------------------------- 1 | .courses-list { 2 | width: 100%; 3 | min-height: 100%; 4 | background-color: #fff; 5 | /* #ifndef rn */ 6 | line-height: 1.2; 7 | /* #endif */ 8 | } 9 | 10 | .courses-list-header { 11 | position: relative; 12 | width: 100%; 13 | height: 480px; 14 | } 15 | .courses-list__bg { 16 | position: absolute; 17 | top: 0; 18 | left: 0; 19 | z-index: 79; 20 | width: 100%; 21 | height: 100%; 22 | } 23 | .courses-list-header__intro-maintitle { 24 | position: relative; 25 | z-index: 99; 26 | padding: 50px 60px 0 60px; 27 | } 28 | .courses-list-header__intro-subtitle { 29 | /* #ifndef rn */ 30 | display: -webkit-box; 31 | -webkit-box-orient: vertical; 32 | -webkit-line-clamp: 4; 33 | /* #endif */ 34 | overflow: hidden; 35 | position: relative; 36 | z-index: 99; 37 | padding: 20px 60px 0 60px; 38 | max-height: 230px; 39 | } 40 | 41 | .courses-list-header__maintitle-text { 42 | color: #fff; 43 | font-size: 36px; 44 | letter-spacing: 2px; 45 | } 46 | .courses-list-header__subtitle-text { 47 | color: #fff; 48 | font-size: 28px; 49 | line-height: 47px; 50 | letter-spacing: 2px; 51 | } 52 | 53 | .courses-list-item__container { 54 | position: relative; 55 | z-index: 99; 56 | width: 90%; 57 | min-height: 100%; 58 | margin: -100px auto 0 auto; 59 | } 60 | 61 | .courses-list-item { 62 | /* #ifndef rn */ 63 | display: flex; 64 | 65 | /* #endif */ 66 | flex-direction: row; 67 | width: 100%; 68 | height: 224px; 69 | margin-bottom: 50px; 70 | background-color: #f7f7f9; 71 | border-top-right-radius: 20px; 72 | border-bottom-right-radius: 20px; 73 | } 74 | .courses-list-item, 75 | .courses-list-item__thumb, 76 | .courses-list-item__thumb-img { 77 | border-top-left-radius: 20px; 78 | border-bottom-left-radius: 20px; 79 | } 80 | .courses-list-item__intro-container { 81 | position: relative; 82 | flex: 1; 83 | margin: 26px 30px; 84 | } 85 | .courses-list-item__thumb { 86 | line-height: 0; 87 | background-color: #f7f7f9; 88 | } 89 | .courses-list-item__thumb-img { 90 | width: 200px; 91 | height: 100%; 92 | } 93 | .courses-list-item__intro { 94 | position: absolute; 95 | bottom: 0; 96 | right: 0; 97 | width: 100%; 98 | height: 60px; 99 | 100 | /* #ifndef rn */ 101 | display: -webkit-box; 102 | -webkit-box-orient: vertical; 103 | -webkit-line-clamp: 1; 104 | /* #endif */ 105 | 106 | overflow: hidden; 107 | text-align: left; 108 | } 109 | .courses-list-item__intro-maintitle { 110 | height: 106px; 111 | /* #ifndef rn */ 112 | display: -webkit-box; 113 | -webkit-box-orient: vertical; 114 | -webkit-line-clamp: 2; 115 | /* #endif */ 116 | 117 | overflow: hidden; 118 | } 119 | .courses-list-item__maintitle { 120 | color: #70449e; 121 | font-size: 34px; 122 | line-height: 50px; 123 | } 124 | .courses-list-item__subtitle { 125 | color: #444; 126 | font-size: 30px; 127 | } 128 | .courses-list-item__text { 129 | line-height: 60px; 130 | color: #777; 131 | font-size: 26px; 132 | } 133 | -------------------------------------------------------------------------------- /src/pages/courses/index.jsx: -------------------------------------------------------------------------------- 1 | import Taro, { Component } from "@tarojs/taro"; 2 | import { View, Image, Text, Navigator } from "@tarojs/components"; 3 | import { getGlobalData } from "@/src/utils"; 4 | import { showShareMenu } from "@/src/utils/index"; 5 | import httpRequest from "@/src/utils/request"; 6 | import coursesBg from "@/src/assets/images/courses/bg.png"; 7 | import styles from "./index.module.scss"; 8 | 9 | class Courses extends Component { 10 | constructor() { 11 | super(...arguments); 12 | this.state = { 13 | list: [], 14 | mainTitle: "", 15 | subTitle: "", 16 | }; 17 | this.env = process.env.TARO_ENV; 18 | } 19 | componentDidMount() { 20 | httpRequest.get("/api/v1/contents/1/153").then((r) => { 21 | this.setState({ 22 | list: r.data.value, 23 | mainTitle: r.data.value[0].author, 24 | subTitle: r.data.value[0].summary, 25 | }); 26 | }); 27 | showShareMenu(); // 开启页面分享按钮 28 | } 29 | 30 | config = { 31 | navigationBarTitleText: "课程", 32 | }; 33 | render() { 34 | const { list, mainTitle, subTitle } = this.state; 35 | return ( 36 | 37 | 38 | 39 | 40 | 41 | {mainTitle} 42 | 43 | 44 | 45 | 46 | {subTitle} 47 | 48 | 49 | 50 | 51 | {list.map((item) => ( 52 | 57 | 58 | 59 | 62 | 66 | 67 | 68 | 69 | {item.title} 70 | 71 | {item.subTitle} 72 | 73 | 74 | 75 | 76 | 77 | {item.summary} 78 | 79 | 80 | 81 | 82 | ))} 83 | 84 | 85 | ); 86 | } 87 | } 88 | export default Courses; 89 | -------------------------------------------------------------------------------- /src/pages/courses/index.module.scss: -------------------------------------------------------------------------------- 1 | .courses { 2 | width: 100%; 3 | min-height: 100%; 4 | background-color: #fff; 5 | /* #ifndef rn */ 6 | line-height: 1.2; 7 | /* #endif */ 8 | padding-bottom: 100px; 9 | } 10 | // courses-header 11 | .courses-header { 12 | position: relative; 13 | width: 100%; 14 | height: 480px; 15 | } 16 | .courses__bg { 17 | position: absolute; 18 | top: 0; 19 | left: 0; 20 | z-index: 79; 21 | width: 100%; 22 | height: 100%; 23 | } 24 | .courses-header__intro { 25 | width: 92%; 26 | margin: 0 auto; 27 | } 28 | .courses-header__intro-maintitle { 29 | position: relative; 30 | z-index: 99; 31 | padding: 50px 10px 0 10px; 32 | } 33 | .courses-header__intro-subtitle { 34 | /* #ifndef rn */ 35 | display: -webkit-box; 36 | -webkit-box-orient: vertical; 37 | -webkit-line-clamp: 4; 38 | /* #endif */ 39 | 40 | overflow: hidden; 41 | position: relative; 42 | z-index: 99; 43 | padding: 20px 10px 0 10px; 44 | max-height: 230px; 45 | } 46 | .courses-header__maintitle-text { 47 | color: #fff; 48 | font-size: 36px; 49 | letter-spacing: 2px; 50 | } 51 | .courses-header__subtitle-text { 52 | color: #fff; 53 | font-size: 28px; 54 | line-height: 47px; 55 | letter-spacing: 2px; 56 | } 57 | 58 | //courses-item__container 59 | .courses-item__container { 60 | position: relative; 61 | z-index: 99; 62 | width: 92%; 63 | min-height: 100%; 64 | margin: -100px auto -50px auto; 65 | } 66 | @media screen and (min-width: 30em) and (orientation: landscape) { 67 | .courses-item__container { 68 | display: flex; 69 | flex-wrap: wrap; 70 | align-items: stretch; 71 | & > div { 72 | width: 48%; 73 | margin: 0 1%; 74 | } 75 | } 76 | } 77 | .courses-item { 78 | margin: 0 10px 50px 10px; 79 | background-color: #f7f7f9; 80 | border-radius: 20px; 81 | } 82 | .courses-item__thumb, 83 | .courses-item__thumb-img { 84 | position: relative; 85 | z-index: 99; 86 | width: 100%; 87 | height: auto; 88 | border-top-left-radius: 20px; 89 | border-top-right-radius: 20px; 90 | } 91 | .courses-item__thumb-loading { 92 | position: absolute; 93 | top: 0; 94 | left: 0; 95 | z-index: 19; 96 | width: 100%; 97 | height: 100%; 98 | opacity: 0.6; 99 | } 100 | .courses-item__maintitle { 101 | line-height: 40px; 102 | padding: 40px 40px 0 40px; 103 | text-align: left; 104 | } 105 | .courses-item__subtitle { 106 | line-height: 40px; 107 | padding: 20px 40px 40px 40px; 108 | text-align: left; 109 | } 110 | .courses-item__maintitle-text { 111 | letter-spacing: 2px; 112 | line-height: 56px; 113 | color: #70449e; 114 | font-size: 36px; 115 | } 116 | .courses-item__subtitle-text { 117 | line-height: 46px; 118 | color: #444; 119 | font-size: 30px; 120 | } 121 | .courses-item__subscript { 122 | padding-left: 20px; 123 | line-height: 42px; 124 | color: #777; 125 | font-size: 26px; 126 | } 127 | // courses-item__container 128 | .courses-swiper__container { 129 | /* #ifndef rn */ 130 | display: block; 131 | /* #endif */ 132 | height: 100%; 133 | text-align: center; 134 | } 135 | .courses-swiper__item { 136 | min-height: 700px; 137 | height: 100%; 138 | border-radius: 20px; 139 | } 140 | .courses-swiper__container-img { 141 | position: relative; 142 | z-index: 99; 143 | width: auto; 144 | max-width: 100%; 145 | height: auto; 146 | margin: 0 10px; 147 | border-top-left-radius: 20px; 148 | border-top-right-radius: 20px; 149 | } 150 | -------------------------------------------------------------------------------- /src/pages/index/index.jsx: -------------------------------------------------------------------------------- 1 | import Taro, { Component } from "@tarojs/taro"; 2 | import { 3 | View, 4 | Text, 5 | Swiper, 6 | SwiperItem, 7 | Image, 8 | Navigator 9 | } from "@tarojs/components"; 10 | 11 | import indexBg from "@/src/assets/images/index/index_bg.png"; 12 | import messageIcon from "@/src/assets/images/index/crown.png"; 13 | import noticeIcon from "@/src/assets/images/index/notice.png"; 14 | import ok from "@/src/assets/images/index/ok.png"; 15 | import { showShareMenu, getGlobalData } from "@/src/utils/index"; 16 | import httpRequest from "@/src/utils/request"; 17 | import styles from "./index.module.scss"; 18 | 19 | class Index extends Component { 20 | constructor() { 21 | super(...arguments); 22 | this.state = { 23 | recomList: [], 24 | guideList: [], 25 | hasNewNotice: false, // 新公告提示红点 26 | hasNewMessage: false // 新消息提示红点 27 | }; 28 | this.env = process.env.TARO_ENV; 29 | } 30 | componentDidMount() { 31 | httpRequest.get("/api/v1/contents/1/172").then(r => { 32 | this.setState({ 33 | recomList: r.data.value 34 | }); 35 | }); 36 | httpRequest.get("/api/v1/contents/1/174").then(r => { 37 | this.setState({ 38 | guideList: r.data.value 39 | }); 40 | }); 41 | showShareMenu(); // 开启页面分享按钮 42 | } 43 | componentWillReceiveProps(nextProps) { 44 | console.log(this.props, nextProps); 45 | } 46 | componentWillUnmount() {} 47 | componentDidShow() {} 48 | componentDidHide() {} 49 | config = { 50 | navigationBarTitleText: "首页" 51 | }; 52 | 53 | render() { 54 | const { recomList, guideList } = this.state; 55 | return ( 56 | 57 | 58 | 59 | 60 | 64 | 65 | {this.state.hasNewNotice && ( 66 | 67 | 70 | 71 | )} 72 | 73 | 77 | 78 | {this.state.hasNewMessage && ( 79 | 80 | 83 | 84 | )} 85 | 86 | 87 | 88 | 89 | 90 | 亲爱的小朋友 91 | 92 | 93 | 98 | 99 | 100 | 开始学习 101 | 102 | 103 | 104 | 105 | 106 | 点击【开始学习】,开始你的编程之旅吧 107 | 108 | 109 | 110 | 111 | 112 | 思维 113 | 114 | 115 | 116 | 创新 117 | 118 | 119 | 120 | 合作 121 | 122 | 123 | 124 | 125 | 126 | 127 | 为您推荐 128 | 129 | 138 | {Array.isArray(recomList) && 139 | recomList.length !== 0 && 140 | recomList.map(item => ( 141 | 142 | 146 | 150 | 151 | 152 | ))} 153 | 154 | 155 | 156 | 157 | 操作指南 158 | 159 | 164 | {Array.isArray(guideList) && 165 | guideList.length !== 0 && 166 | guideList.map(item => ( 167 | 168 | 172 | 176 | 177 | 178 | ))} 179 | 180 | 181 | 182 | ); 183 | } 184 | } 185 | 186 | export default Index; 187 | -------------------------------------------------------------------------------- /src/pages/index/index.module.scss: -------------------------------------------------------------------------------- 1 | // container 2 | .index { 3 | position: absolute; 4 | top: 0; 5 | left: 0; 6 | width: 100%; 7 | min-height: 100%; 8 | background-color: #fff; 9 | } 10 | .index__bg { 11 | position: absolute; 12 | top: 0; 13 | left: 0; 14 | z-index: 1; 15 | width: 100%; 16 | height: 540px; 17 | } 18 | .index-container { 19 | width: 92%; 20 | margin: 20px auto 0 auto; 21 | } 22 | .index-header { 23 | position: relative; 24 | z-index: 19; 25 | height: 50px; 26 | margin: 0 10px; 27 | } 28 | // card 29 | .index__message, 30 | .index__notice { 31 | position: absolute; 32 | top: 0; 33 | left: 0; 34 | z-index: 89; 35 | width: 37px; 36 | height: 46px; 37 | } 38 | .index__message { 39 | left: auto; 40 | right: 0; 41 | width: 46px; 42 | height: 46px; 43 | } 44 | 45 | .index__notice-status, 46 | .index__message-status { 47 | position: absolute; 48 | top: 10px; 49 | left: 0px; 50 | z-index: 109; 51 | width: 20px; 52 | height: 20px; 53 | background-color: #fff; 54 | border-radius: 10px; 55 | } 56 | .index__notice-status-border, 57 | .index__message-status-border { 58 | position: absolute; 59 | top: 50%; 60 | left: 50%; 61 | z-index: 110; 62 | width: 16px; 63 | height: 16px; 64 | margin: -8px 0 0 -8px; 65 | background-color: #f64272; 66 | border-radius: 10px; 67 | } 68 | .index__message-status { 69 | left: auto; 70 | right: 0; 71 | } 72 | .index-card { 73 | position: relative; 74 | z-index: 100; 75 | height: 400px; 76 | margin: 20px 10px 0 10px; 77 | border-radius: 8px; 78 | background-color: #fff; 79 | overflow: hidden; 80 | } 81 | .index-card__username { 82 | width: 80%; 83 | height: 120px; 84 | line-height: 120px; 85 | margin: 20px auto 0 auto; 86 | overflow: hidden; 87 | text-align: center; 88 | } 89 | .index-card__button { 90 | /* #ifndef rn */ 91 | display: block; 92 | /* #endif */ 93 | width: 300px; 94 | height: 80px; 95 | line-height: 80px; 96 | margin: 10px auto; 97 | /* #ifndef rn */ 98 | background-image: linear-gradient(-134deg, #c86dd7 0%, #3023ae 100%); 99 | /* #endif */ 100 | background-color: #6b40bd; 101 | border-color: transparent; 102 | border-radius: 60px; 103 | text-align: center; 104 | } 105 | .index-card__tips { 106 | width: 80%; 107 | height: 88px; 108 | line-height: 88px; 109 | margin: 10px auto 0 auto; 110 | overflow: hidden; 111 | text-align: center; 112 | } 113 | 114 | .index-card__username-text, 115 | .index-card__button-text, 116 | .index-card__tips-text { 117 | /* #ifndef rn */ 118 | display: inline-block; 119 | /* #endif */ 120 | font-weight: 400; 121 | color: #444; 122 | } 123 | .index-card__username-text { 124 | line-height: 60px; 125 | font-size: 42px; 126 | color: #7d4c9f; 127 | } 128 | .index-card__button-text { 129 | font-size: 30px; 130 | color: #fff; 131 | letter-spacing: 4px; 132 | } 133 | .index-card__tips-text { 134 | line-height: 44px; 135 | font-size: 28px; 136 | color: #777; 137 | } 138 | 139 | .index-card__footer { 140 | position: absolute; 141 | bottom: 0; 142 | left: 0; 143 | display: flex; 144 | justify-content: center; 145 | align-items: center; 146 | flex-direction: row; 147 | width: 100%; 148 | height: 60px; 149 | border-radius: 8px; 150 | background-color: #b39db72e; 151 | } 152 | .index-card__icon { 153 | flex: 1; 154 | display: flex; 155 | justify-content: center; 156 | align-items: center; 157 | flex-direction: row; 158 | width: 100%; 159 | height: 100%; 160 | } 161 | .index-card__icon-ok { 162 | width: 30px; 163 | height: 30px; 164 | /* #ifndef rn */ 165 | vertical-align: middle; 166 | /* #endif */ 167 | } 168 | .index-card__icon-text { 169 | padding-left: 10px; 170 | font-size: 26px; 171 | color: #7d4c9f; 172 | text-align: center; 173 | } 174 | 175 | // index-module 176 | .index-notice { 177 | width: 92%; 178 | margin: 50px auto 0 auto; 179 | overflow: hidden; 180 | } 181 | .index__maintitle { 182 | padding: 20px 10px; 183 | } 184 | .index__maintitle-text { 185 | font-size: 34px; 186 | font-weight: 400; 187 | color: #7d4c9f; 188 | } 189 | // index-swiper 190 | .index-notice__swiper { 191 | /* #ifndef rn */ 192 | display: block; 193 | /* #endif */ 194 | text-align: center; 195 | /* #endif */ 196 | height: 100%; 197 | } 198 | .index-notice__swiper-img { 199 | width: auto; 200 | height: 150px; 201 | max-width: 100%; 202 | border-radius: 10px; 203 | margin: 0 10px; 204 | } 205 | .index-guide { 206 | width: 92%; 207 | margin: 0px auto; 208 | overflow: hidden; 209 | } 210 | .index__navigator { 211 | /* #ifndef rn */ 212 | display: block; 213 | /* #endif */ 214 | width: 100%; 215 | flex: 1; 216 | } 217 | -------------------------------------------------------------------------------- /src/pages/index/message_list.jsx: -------------------------------------------------------------------------------- 1 | import Taro, { Component } from "@tarojs/taro"; 2 | import { View, Text, Image } from "@tarojs/components"; 3 | // import httpRequest from "@/src/utils/request"; 4 | // import { getGlobalData } from "@/src/utils"; 5 | import noMessage from "@/src/assets/images/no_data/message.png"; 6 | // import arrowRight from "@/src/assets/images/other/arrow_right.png"; 7 | import styles from "./message_list.module.scss"; 8 | 9 | class Message extends Component { 10 | static options = { 11 | addGlobalClass: true, // 支持组件外部样式,小程序基础库版本 2.2.3 开始支持 12 | }; 13 | constructor() { 14 | super(...arguments); 15 | this.state = { 16 | isMesRead: 0, 17 | mesNum: 0, 18 | // list: [], 19 | }; 20 | this.env = process.env.TARO_ENV; 21 | } 22 | componentDidMount() { 23 | // httpRequest.get("/api/v1/contents/1/172").then((r) => { 24 | // this.setState({ 25 | // list: r.data.value, 26 | // }); 27 | // }); 28 | } 29 | 30 | config = { 31 | navigationBarTitleText: "消息中心", 32 | }; 33 | 34 | render() { 35 | // const { list } = this.state; 36 | 37 | return ( 38 | 39 | 40 | {this.state.mesNum === 0 ? ( 41 | 42 | 43 | 44 | 45 | 46 | 暂无消息 47 | 48 | 49 | ) : ( 50 | 51 | {this.state.isMesRead === 0 && ( 52 | 53 | )} 54 | 55 | 56 | 57 | 新注册用户畅玩新注册用户畅玩新注册用户畅玩新注册用户畅玩 58 | 59 | 60 | 61 | 62 | 2019-08-01 09:30 63 | 64 | 65 | 66 | 67 | 68 | 只需三步,注册会员,即可试运营期间畅玩只需三步,注册会员,即可试运营期间畅玩只需三步,注册会员,即可试运营期间畅玩 69 | 70 | 71 | 72 | )} 73 | 74 | 75 | ); 76 | } 77 | } 78 | export default Message; 79 | -------------------------------------------------------------------------------- /src/pages/index/message_list.module.scss: -------------------------------------------------------------------------------- 1 | .message { 2 | width: 100%; 3 | min-height: 100%; 4 | } 5 | .message-item__container { 6 | position: relative; 7 | z-index: 99; 8 | width: 90%; 9 | min-height: 100%; 10 | margin: 0px auto; 11 | padding: 50px 0; 12 | } 13 | @media screen and (min-width: 30em) and (orientation: landscape) { 14 | .message-item__container { 15 | display: flex; 16 | flex-wrap: wrap; 17 | align-items: stretch; 18 | & > div { 19 | width: 48%; 20 | margin: 0 1%; 21 | } 22 | } 23 | } 24 | .message-item { 25 | position: relative; 26 | margin-bottom: 50px; 27 | background-color: #f3f3f3; 28 | padding: 30px; 29 | border-radius: 20px; 30 | } 31 | .message-item__intro-container { 32 | display: flex; 33 | flex-direction: row; 34 | } 35 | .message-item__intro { 36 | line-height: 38px; 37 | padding-left: 20px; 38 | } 39 | .message-item__thumb { 40 | margin-top: 20px; 41 | line-height: 40px; 42 | } 43 | 44 | .message-item__intro-maintitle { 45 | flex: 1; 46 | overflow: hidden; 47 | line-height: 50px; 48 | } 49 | 50 | .message-item__maintitle { 51 | color: #70449e; 52 | font-size: 34px; 53 | line-height: 50px; 54 | } 55 | .message-item__subtitle { 56 | color: #444; 57 | font-size: 30px; 58 | } 59 | .message-item__text { 60 | color: #777; 61 | font-size: 26px; 62 | line-height: 44px; 63 | } 64 | .message-item__date-text { 65 | color: #9b9b9b; 66 | font-size: 26px; 67 | line-height: 44px; 68 | } 69 | .message-item__status { 70 | position: absolute; 71 | top: 14px; 72 | left: 14px; 73 | z-index: 89; 74 | width: 20px; 75 | height: 20px; 76 | background-color: #f64272; 77 | border-radius: 10px; 78 | } 79 | -------------------------------------------------------------------------------- /src/pages/index/notice_list.jsx: -------------------------------------------------------------------------------- 1 | import Taro, { Component } from "@tarojs/taro"; 2 | import { View, Text, Image, Navigator } from "@tarojs/components"; 3 | import httpRequest from "@/src/utils/request"; 4 | import { getGlobalData } from "@/src/utils"; 5 | import arrowRight from "@/src/assets/images/other/arrow_right.png"; 6 | import styles from "./notice_list.module.scss"; 7 | 8 | class Notice extends Component { 9 | constructor() { 10 | super(...arguments); 11 | this.state = { 12 | isNoticeRead: 1, 13 | list: [], 14 | }; 15 | this.env = process.env.TARO_ENV; 16 | } 17 | componentDidMount() { 18 | httpRequest.get("/api/v1/contents/1/173").then((r) => { 19 | this.setState({ 20 | list: r.data.value, 21 | }); 22 | }); 23 | } 24 | config = { 25 | navigationBarTitleText: "公告中心", 26 | }; 27 | 28 | render() { 29 | const { list } = this.state; 30 | return ( 31 | 32 | 33 | {list.map((item) => ( 34 | 39 | 40 | {this.state.isNoticeRead === 0 && ( 41 | 42 | )} 43 | 44 | 45 | 46 | {item.title} 47 | 48 | 49 | 50 | 51 | {item.lastEditDate} 52 | 53 | 54 | 55 | 56 | 60 | 61 | 62 | 63 | 64 | 查看详情 65 | 66 | 67 | 68 | 72 | 73 | 74 | 75 | 76 | ))} 77 | 78 | 79 | ); 80 | } 81 | } 82 | export default Notice; 83 | -------------------------------------------------------------------------------- /src/pages/index/notice_list.module.scss: -------------------------------------------------------------------------------- 1 | .notice { 2 | width: 100%; 3 | min-height: 100%; 4 | } 5 | 6 | .notice-item__container { 7 | position: relative; 8 | z-index: 99; 9 | width: 90%; 10 | min-height: 100%; 11 | margin: 0px auto; 12 | padding: 50px 0; 13 | } 14 | @media screen and (min-width: 30em) and (orientation: landscape) { 15 | .notice-item__container { 16 | display: flex; 17 | flex-wrap: wrap; 18 | align-items: stretch; 19 | & > div { 20 | width: 48%; 21 | margin: 0 1%; 22 | } 23 | } 24 | } 25 | .notice-item { 26 | position: relative; 27 | margin-bottom: 50px; 28 | background-color: #f3f3f3; 29 | padding: 30px 30px 10px 30px; 30 | border-radius: 20px; 31 | } 32 | .notice-item__intro-container { 33 | // display: flex; 34 | // flex-direction: row; 35 | } 36 | .notice-item__intro { 37 | // padding-left: 20px; 38 | } 39 | .notice-item__thumb { 40 | margin-top: 20px; 41 | } 42 | 43 | .notice-item__maintitle { 44 | flex: 1; 45 | overflow: hidden; 46 | } 47 | 48 | .notice-item__maintitle-text { 49 | color: #70449e; 50 | font-size: 34px; 51 | line-height: 46px; 52 | } 53 | .notice-item__subtitle { 54 | color: #444; 55 | font-size: 30px; 56 | } 57 | .notice-item__text { 58 | color: #777; 59 | font-size: 26px; 60 | line-height: 44px; 61 | } 62 | .notice-item__link { 63 | position: relative; 64 | height: 68px; 65 | line-height: 68px; 66 | margin-top: 30px; 67 | padding-top: 10px; 68 | border: 0 dashed #9b9b9b; 69 | border-top-width: 2px; 70 | } 71 | .notice-item__link-left { 72 | position: absolute; 73 | left: 0; 74 | top: 0; 75 | z-index: 89; 76 | height: 100%; 77 | } 78 | .notice-item__link-right { 79 | position: absolute; 80 | left: auto; 81 | right: 0; 82 | top: 50%; 83 | width: 30px; 84 | height: 30px; 85 | margin-top: -15px; 86 | } 87 | .notice-item__link-img { 88 | /* #ifndef rn */ 89 | display: inherit; 90 | /* #endif */ 91 | width: 30px; 92 | height: 30px; 93 | } 94 | .notice-item__link-text { 95 | color: #777; 96 | font-size: 26px; 97 | line-height: 68px; 98 | } 99 | 100 | .notice-item__date-text { 101 | color: #9b9b9b; 102 | font-size: 26px; 103 | line-height: 44px; 104 | } 105 | .notice-item__status { 106 | position: absolute; 107 | top: 14px; 108 | left: 14px; 109 | z-index: 89; 110 | width: 20px; 111 | height: 20px; 112 | background-color: #f64272; 113 | border-radius: 10px; 114 | } 115 | .notice-item__pic { 116 | width: 100%; 117 | height: 160px; 118 | margin: 20px auto; 119 | border-radius: 10px; 120 | } 121 | .notice-item__pic-img { 122 | width: 100%; 123 | height: 100%; 124 | border-radius: 10px; 125 | } 126 | -------------------------------------------------------------------------------- /src/pages/index/recomm_list.jsx: -------------------------------------------------------------------------------- 1 | import Taro, { Component } from "@tarojs/taro"; 2 | import { View, Text, Image, Navigator } from "@tarojs/components"; 3 | import httpRequest from "@/src/utils/request"; 4 | import { getGlobalData } from "@/src/utils"; 5 | // import noMessage from "@/src/assets/images/no_data/message.png"; 6 | import arrowRight from "@/src/assets/images/other/arrow_right.png"; 7 | import styles from "./recomm_list.module.scss"; 8 | 9 | class Message extends Component { 10 | static options = { 11 | addGlobalClass: true // 支持组件外部样式,小程序基础库版本 2.2.3 开始支持 12 | }; 13 | constructor() { 14 | super(...arguments); 15 | this.state = { 16 | list: [] 17 | }; 18 | this.env = process.env.TARO_ENV; 19 | } 20 | componentDidMount() { 21 | httpRequest.get("/api/v1/contents/1/172").then(r => { 22 | this.setState({ 23 | list: r.data.value 24 | }); 25 | }); 26 | } 27 | 28 | config = { 29 | navigationBarTitleText: "官方推荐" 30 | }; 31 | 32 | render() { 33 | const { list } = this.state; 34 | 35 | return ( 36 | 37 | 38 | {list.map(item => ( 39 | 44 | 45 | {this.state.isNoticeRead === 0 && ( 46 | 47 | )} 48 | 49 | 50 | 51 | {item.title} 52 | 53 | 54 | 55 | 56 | {item.lastEditDate} 57 | 58 | 59 | 60 | 61 | 65 | 66 | 67 | 68 | 69 | 查看详情 70 | 71 | 72 | 73 | 77 | 78 | 79 | 80 | 81 | ))} 82 | 83 | 84 | ); 85 | } 86 | } 87 | export default Message; 88 | -------------------------------------------------------------------------------- /src/pages/index/recomm_list.module.scss: -------------------------------------------------------------------------------- 1 | .notice { 2 | width: 100%; 3 | min-height: 100%; 4 | } 5 | 6 | .notice-item__container { 7 | position: relative; 8 | z-index: 99; 9 | width: 90%; 10 | min-height: 100%; 11 | margin: 0px auto; 12 | padding: 50px 0; 13 | } 14 | @media screen and (min-width: 30em) and (orientation: landscape) { 15 | .notice-item__container { 16 | display: flex; 17 | flex-wrap: wrap; 18 | align-items: stretch; 19 | & > div { 20 | width: 48%; 21 | margin: 0 1%; 22 | } 23 | } 24 | } 25 | .notice-item { 26 | position: relative; 27 | margin-bottom: 50px; 28 | background-color: #f3f3f3; 29 | padding: 30px 30px 10px 30px; 30 | border-radius: 20px; 31 | } 32 | .notice-item__intro-container { 33 | // display: flex; 34 | // flex-direction: row; 35 | } 36 | .notice-item__intro { 37 | // padding-left: 20px; 38 | } 39 | .notice-item__thumb { 40 | margin-top: 20px; 41 | } 42 | 43 | .notice-item__maintitle { 44 | flex: 1; 45 | overflow: hidden; 46 | line-height: 46px; 47 | } 48 | 49 | .notice-item__maintitle-text { 50 | color: #70449e; 51 | font-size: 34px; 52 | } 53 | .notice-item__subtitle { 54 | color: #444; 55 | font-size: 30px; 56 | } 57 | .notice-item__text { 58 | color: #777; 59 | font-size: 26px; 60 | line-height: 44px; 61 | } 62 | .notice-item__link { 63 | position: relative; 64 | height: 68px; 65 | line-height: 68px; 66 | margin-top: 30px; 67 | padding-top: 10px; 68 | border: 0 dashed #9b9b9b; 69 | border-top-width: 2px; 70 | } 71 | .notice-item__link-left { 72 | position: absolute; 73 | left: 0; 74 | top: 0; 75 | z-index: 89; 76 | height: 100%; 77 | } 78 | .notice-item__link-right { 79 | position: absolute; 80 | left: auto; 81 | right: 0; 82 | top: 50%; 83 | width: 30px; 84 | height: 30px; 85 | margin-top: -15px; 86 | } 87 | .notice-item__link-img { 88 | /* #ifndef rn */ 89 | display: inherit; 90 | /* #endif */ 91 | width: 30px; 92 | height: 30px; 93 | } 94 | .notice-item__link-text { 95 | color: #777; 96 | font-size: 26px; 97 | line-height: 68px; 98 | } 99 | 100 | .notice-item__date-text { 101 | color: #9b9b9b; 102 | font-size: 26px; 103 | line-height: 44px; 104 | } 105 | .notice-item__status { 106 | position: absolute; 107 | top: 14px; 108 | left: 14px; 109 | z-index: 89; 110 | width: 20px; 111 | height: 20px; 112 | background-color: #f64272; 113 | border-radius: 10px; 114 | } 115 | .notice-item__pic { 116 | width: 100%; 117 | height: 160px; 118 | margin: 20px auto; 119 | border-radius: 10px; 120 | } 121 | .notice-item__pic-img { 122 | width: 100%; 123 | height: 100%; 124 | border-radius: 10px; 125 | } 126 | -------------------------------------------------------------------------------- /src/pages/users/help_detail.jsx: -------------------------------------------------------------------------------- 1 | import Taro, { Component } from '@tarojs/taro' 2 | import { View, RichText } from '@tarojs/components' 3 | 4 | class HelpDetail extends Component { 5 | 6 | constructor() { 7 | super(...arguments) 8 | this.state = { 9 | helpDetailNodes: [], 10 | } 11 | this.env = process.env.TARO_ENV 12 | } 13 | 14 | componentDidMount() { 15 | this.setState({ 16 | helpDetailNodes: [ 17 | { 18 | name: 'div', 19 | attrs: { class: 'article-detail__subtitle' }, 20 | children: [{ type: 'text', text: '无需帐户' }], 21 | }, 22 | { 23 | name: 'p', 24 | attrs: { class: 'article-detail__text' }, 25 | children: [ 26 | { 27 | type: 'text', 28 | text: '学生可以立即开始编写一些教程,而无需创建帐户!他们只需打开我们的应用,然后点击首页的“开始学习”按钮,即可进入可以选择要处理的课程的页面。 ', 29 | }, 30 | ], 31 | }, 32 | { 33 | name: 'div', 34 | attrs: { class: 'article-detail__subtitle' }, 35 | children: [{ type: 'text', text: '为何选择计算机科学' }], 36 | }, 37 | { 38 | name: 'p', 39 | attrs: { class: 'article-detail__text' }, 40 | children: [ 41 | { 42 | type: 'text', 43 | text: 44 | '我们相信世界各地的每个学生都应该有机会学习计算机科学。它有助于培养解决问题的技能,逻辑和创造力。通过提前入学,学生将在任何21世纪的职业道路上获得成功的基础。', 45 | }, 46 | ], 47 | }, 48 | { 49 | name: 'div', 50 | attrs: { class: 'article-detail__subtitle' }, 51 | children: [{ type: 'text', text: '我应该先开始学习哪种编码语言' }], 52 | }, 53 | { 54 | name: 'p', 55 | attrs: { class: 'article-detail__text' }, 56 | children: [ 57 | { 58 | type: 'text', 59 | text: 60 | '这是我们经常被问到的一个问题 - 而且没有一个明确的答案。这取决于你已经知道的,以及为什么你想要了解更多!如果您以前从未尝试过编码,请先使用拖放操作来学习概念。如果你之前尝试过拖放编程并想尝试基于文本的编码,那么最广泛使用的编程语言就是JavaScript。如果您想构建特定的内容,例如Android应用,iOS应用,网站或数据库,则每种内容都有特定的语言。', 61 | }, 62 | ], 63 | }, 64 | ] 65 | }) 66 | } 67 | 68 | config = { 69 | navigationBarTitleText: '帮助中心', 70 | } 71 | 72 | render() { 73 | return ( 74 | 75 | 76 | 77 | ) 78 | } 79 | } 80 | 81 | export default HelpDetail 82 | -------------------------------------------------------------------------------- /src/pages/users/help_list.jsx: -------------------------------------------------------------------------------- 1 | import Taro, { Component } from "@tarojs/taro"; 2 | import { View, Text, Navigator, Image } from "@tarojs/components"; 3 | import httpRequest from "@/src/utils/request"; 4 | import help_guide from "@/src/assets/images/help/help_guide.png"; 5 | // import help_update from "@/src/assets/images/help/help_update.png"; 6 | // import help_account from '@/src/assets/images/help/help_account.png' 7 | import styles from "./help_list.module.scss"; 8 | 9 | class Help extends Component { 10 | constructor() { 11 | super(...arguments); 12 | this.state = { 13 | list: [], 14 | }; 15 | this.env = process.env.TARO_ENV; 16 | } 17 | componentDidMount() { 18 | httpRequest.get("/api/v1/contents/1/175").then((r) => { 19 | this.setState({ 20 | list: r.data.value, 21 | }); 22 | }); 23 | } 24 | config = { 25 | navigationBarTitleText: "帮助中心", 26 | }; 27 | 28 | render() { 29 | const { list } = this.state; 30 | 31 | return ( 32 | 33 | 34 | 35 | 39 | 40 | 41 | {list.map((item) => ( 42 | 47 | 48 | 49 | {item.title} 50 | 51 | 52 | 53 | ))} 54 | 55 | 56 | {/* 57 | 58 | 59 | 63 | 64 | 65 | 69 | 70 | 71 | 我们多长时间更新一次课程 ? 72 | 73 | 74 | 75 | 79 | 80 | 81 | 如何收到课程更新通知 ? 82 | 83 | 84 | 85 | 86 | */} 87 | {/* 88 | 89 | 90 | 91 | 92 | 93 | 94 | 97 | 98 | 账号密码忘记如何找回 ? 99 | 100 | 101 | 102 | 103 | 106 | 107 | 账号有何用用处 ? 108 | 109 | 110 | 111 | 112 | 115 | 技术要求 ? 116 | 117 | 118 | 119 | */} 120 | 121 | ); 122 | } 123 | } 124 | 125 | export default Help; 126 | -------------------------------------------------------------------------------- /src/pages/users/help_list.module.scss: -------------------------------------------------------------------------------- 1 | .help { 2 | width: 100%; 3 | min-height: 100%; 4 | background-color: #f7f7f9; 5 | } 6 | .help-link__item { 7 | display: flex; 8 | justify-content: center; 9 | align-items: center; 10 | flex-direction: row; 11 | width: 100%; 12 | background-color: #fff; 13 | } 14 | .help-link__icon { 15 | flex: 1; 16 | width: 100%; 17 | } 18 | .help-link__icon-help { 19 | /* #ifndef rn */ 20 | display: block; 21 | /* #endif */ 22 | width: 140px; 23 | height: 140px; 24 | margin: 0 auto; 25 | } 26 | 27 | .help-link__ask { 28 | flex: 3; 29 | width: 100%; 30 | } 31 | 32 | .help-link__title { 33 | width: auto; 34 | padding-left: 30px; 35 | border: 2px solid #f7f7f9; 36 | /* #ifndef rn */ 37 | border-bottom: none; 38 | /* #endif */ 39 | } 40 | .help-link__title-noborder { 41 | /* #ifndef rn */ 42 | border-bottom: none; 43 | /* #endif */ 44 | } 45 | .help-link__title-text { 46 | font-size: 28px; 47 | color: #666; 48 | line-height: 120px; 49 | } 50 | .help-link__arrow { 51 | width: 50px; 52 | } 53 | .help-link__arrow--active { 54 | width: 50px; 55 | height: 50px; 56 | } 57 | .help-link__separator { 58 | height: 10px; 59 | background-color: #f7f7f9; 60 | } 61 | .help-link__subtitle { 62 | padding: 10px 20px; 63 | } 64 | .help-link__subtitle--text { 65 | font-size: 26px; 66 | color: #666; 67 | } 68 | -------------------------------------------------------------------------------- /src/pages/users/index.jsx: -------------------------------------------------------------------------------- 1 | import Taro, { Component } from '@tarojs/taro' 2 | import { View, Button, Text, Image, Navigator } from '@tarojs/components' 3 | import usersBg from '@/src/assets/images/users/users_bg.png' 4 | import arrowRight from '@/src/assets/images/other/arrow_right.png' 5 | import help from '@/src/assets/images/users/icon/help.png' 6 | import customer from '@/src/assets/images/users/icon/customer.png' 7 | import setting from '@/src/assets/images/users/icon/setting.png' 8 | import message from '@/src/assets/images/users/icon/crown.png' 9 | import notice from '@/src/assets/images/users/icon/notice.png' 10 | import praise from '@/src/assets/images/users/icon/praise.png' 11 | import avatar from '@/src/assets/images/other/avatar.png' 12 | 13 | import { showShareMenu } from '@/src/utils/index' 14 | 15 | import styles from './index.module.scss' 16 | 17 | class Users extends Component { 18 | 19 | constructor() { 20 | super(...arguments) 21 | this.env = process.env.TARO_ENV 22 | } 23 | 24 | componentDidMount() { 25 | showShareMenu() // 开启页面分享按钮 26 | } 27 | config = { 28 | navigationBarTitleText: '我的', 29 | } 30 | onShowContact() { 31 | Taro.makePhoneCall({ 32 | phoneNumber: '4008034725' 33 | }) 34 | } 35 | 36 | onShareAppMessage(res) { 37 | if (this.env === 'h5') { 38 | Taro.showModal({ 39 | title: '提示', 40 | content: '微信小程序搜索【袋小鼠爱编程】,点击【我的】-【分享给小伙伴】', 41 | showCancel: false, 42 | cancelText: '取消', 43 | cancelColor: '#7f7f7f', 44 | confirmText: '知道了', 45 | confirmColor: '#7d4c9f', 46 | success() { 47 | // if (modalRes.confirm) { 48 | // Taro.openSetting({ 49 | // success(data) { 50 | // console.log('打开微信设置授权页面成功') 51 | // }, 52 | // fail(data) { 53 | // console.log('打开微信设置授权页面失败') 54 | // }, 55 | // }) 56 | // } else if (res.cancel) { 57 | // console.log('用户点击取消授权弹窗') 58 | // } 59 | }, 60 | }) 61 | } else { 62 | if (res.from === 'button') { 63 | // 来自页面内转发按钮 64 | console.log(res.target) 65 | } 66 | let pages = Taro.getCurrentPages() 67 | let page = pages[pages.length - 1] 68 | let path = `${page.route}?id=${pages}` 69 | let imageUrl = 'https://videos.codekid.top/share_pic.jpg' // 可以是本地文件路径、代码包文件路径或者网络图片路径。支持 PNG 及 JPG 。显示图片长宽比是 5:4 70 | return { 71 | title: '欢迎来到少儿编程实验室', // 默认当前小程序名称 72 | path, 73 | imageUrl, 74 | success: function () { 75 | Taro.showToast({ 76 | title: '转发成功!', 77 | icon: 'success', 78 | }) 79 | }, 80 | fail: function () { 81 | Taro.showToast({ 82 | title: '转发失败!', 83 | icon: 'none', 84 | }) 85 | }, 86 | } 87 | } 88 | } 89 | 90 | render() { 91 | 92 | return ( 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 小朋友 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 官方推荐 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 公告中心 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 帮助中心 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 设置 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | {this.env === 'weapp' ? ( 167 | 168 | 169 | 170 | 171 | 172 | 173 | 在线客服 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | ) : this.env === 'swan' ? ( 184 | 185 | 186 | 187 | 188 | 189 | 190 | 在线客服 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | ) : (this.env === 'alipay' ? ( 201 | 202 | 203 | 204 | 205 | 206 | 207 | 客服电话 208 | 209 | 210 | 400-803-4725 211 | 212 | 213 | 214 | 215 | 216 | 217 | ) : (null) 218 | )} 219 | 220 | {this.env === 'qq' ? ( 221 | 222 | 223 | 224 | 225 | 226 | 分享给小伙伴 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | // 236 | // 237 | // 238 | // 239 | // 242 | // 分享给小伙伴 243 | // 244 | // 245 | // 246 | // 247 | // 248 | // 249 | // 250 | // 251 | ) : ( 252 | null 253 | ) 254 | 255 | } 256 | 257 | 258 | ) 259 | } 260 | } 261 | 262 | export default Users 263 | -------------------------------------------------------------------------------- /src/pages/users/index.module.scss: -------------------------------------------------------------------------------- 1 | .users { 2 | position: absolute; 3 | width: 100%; 4 | min-height: 100%; 5 | background-color: #fff; 6 | } 7 | .users__bg { 8 | width: 100%; 9 | height: 230px; 10 | } 11 | .users__avatarUrl { 12 | position: relative; 13 | z-index: 99; 14 | width: 150px; 15 | height: 150px; 16 | margin: -110px auto 0 auto; 17 | border-radius: 150px; 18 | background-color: #d8d8d8; 19 | overflow: hidden; 20 | margin: -130px auto 0 auto; 21 | border-radius: 150px; 22 | text-align: center; 23 | } 24 | .users__avatarUrl-img { 25 | width: 150px; 26 | height: 150px; 27 | } 28 | .users-card { 29 | width: 90%; 30 | margin: 20px auto 0 auto; 31 | background-color: transparent; 32 | overflow: hidden; 33 | text-align: center; 34 | } 35 | .users-card__text { 36 | width: 100%; 37 | margin: 0 auto; 38 | padding: 0; 39 | line-height: 50px; 40 | color: #ccc; 41 | } 42 | .users-card__username { 43 | width: 100%; 44 | height: 140px; 45 | margin: 0 auto; 46 | padding: 0; 47 | line-height: 140px; 48 | } 49 | .users-card__text-title { 50 | /* #ifndef rn */ 51 | display: inline-block; 52 | /* #endif */ 53 | font-weight: 400; 54 | color: #444; 55 | padding: 0 60px; 56 | line-height: 60px; 57 | font-size: 42px; 58 | color: #7d4c9f; 59 | text-align: center; 60 | } 61 | .users-link { 62 | width: 92%; 63 | margin: 0 auto 40px auto; 64 | } 65 | .users-link__item { 66 | position: relative; 67 | margin: 0 10px; 68 | overflow: hidden; 69 | height: 120px; 70 | border: 0 solid rgba(231, 231, 240, 1); 71 | border-bottom-width: 2px; 72 | } 73 | .users-link__button, 74 | .users-link__button[type="primary"] { 75 | background-color: transparent; 76 | padding: 0; 77 | font-size: 34px; 78 | color: #2a2a30; 79 | line-height: 120px; 80 | text-align: left; 81 | border-radius: 0; 82 | /* #ifndef rn */ 83 | box-shadow: 0px 0px 0px transparent !important; 84 | border: 0px solid transparent !important; 85 | /* #endif */ 86 | } 87 | .users-link__icon { 88 | position: absolute; 89 | left: 0; 90 | top: 31px; 91 | width: 60px; 92 | height: 60px; 93 | } 94 | .users-link__icon-help { 95 | width: 60px; 96 | height: 60px; 97 | } 98 | .users-link__title { 99 | width: 100%; 100 | position: absolute; 101 | left: 90px; 102 | top: 0; 103 | height: 120px; 104 | line-height: 120px; 105 | } 106 | .users-link__title-text { 107 | font-size: 34px; 108 | color: #2a2a30; 109 | line-height: 60px; 110 | } 111 | .users-link__subtitle { 112 | position: absolute; 113 | right: 90px; 114 | top: 0px; 115 | height: 120px; 116 | line-height: 120px; 117 | } 118 | .users-link__subbutton { 119 | position: absolute; 120 | right: 90px; 121 | top: 31px; 122 | } 123 | .users-link__subbutton--qq { 124 | position: absolute; 125 | right: 62px; 126 | top: 26px; 127 | } 128 | .users-link__subtitle-text { 129 | font-size: 30px; 130 | color: #ccc; 131 | line-height: 60px; 132 | } 133 | .users-link__arrow { 134 | position: absolute; 135 | right: 0; 136 | top: 36px; 137 | width: 50px; 138 | } 139 | .users-link__arrow--active { 140 | width: 50px; 141 | height: 50px; 142 | } 143 | .users-link__title--chart-text { 144 | width: 100%; 145 | font-size: 34px; 146 | color: #2a2a30; 147 | line-height: 120px; 148 | padding-right: 20px; 149 | } 150 | -------------------------------------------------------------------------------- /src/pages/users/setting.jsx: -------------------------------------------------------------------------------- 1 | import Taro, { Component } from "@tarojs/taro"; 2 | import { View, Text, Image, Navigator } from "@tarojs/components"; 3 | import httpRequest from "@/src/utils/request"; 4 | import arrowRight from "@/src/assets/images/other/arrow_right.png"; 5 | import { getSystemInfo, isEmptyObject } from "@/src/utils/index"; 6 | import styles from "./setting.module.scss"; 7 | 8 | class Setting extends Component { 9 | constructor() { 10 | super(...arguments); 11 | this.state = { 12 | // systemInfo: { 13 | // SDKVersion: "", 14 | // }, 15 | list: [], 16 | }; 17 | this.env = process.env.TARO_ENV; 18 | } 19 | componentDidMount() { 20 | httpRequest.get("/api/v1/contents/1/176").then((r) => { 21 | this.setState({ 22 | list: r.data.value, 23 | }); 24 | }); 25 | // const systemData = getSystemInfo(); // 获取设备信息 26 | // if (systemData || !isEmptyObject(systemData)) { 27 | // const { SDKVersion } = systemData; 28 | // this.setState( 29 | // { 30 | // systemInfo: { 31 | // SDKVersion, 32 | // }, 33 | // }, 34 | // () => {} 35 | // ); 36 | // } 37 | } 38 | config = { 39 | navigationBarTitleText: "设置", 40 | }; 41 | // onLogout() { 42 | // Taro.showModal({ 43 | // title: '提示', 44 | // content: '确定要退出当前账号?', 45 | // showCancel: true, 46 | // cancelText: '取消', 47 | // cancelColor: '#7f7f7f', 48 | // confirmText: '退出登录', 49 | // confirmColor: '#f43530', 50 | // success(modalRes) { 51 | // if (modalRes.confirm) { 52 | // try { 53 | // Taro.clearStorage() 54 | // jumpUrl('/pages/users/login') 55 | // } catch (e) { 56 | // console.info(e) 57 | // } 58 | // } else if (res.cancel) { 59 | // console.log('用户点击取消授权弹窗') 60 | // } 61 | // }, 62 | // }) 63 | // } 64 | 65 | render() { 66 | const { 67 | // systemInfo: { SDKVersion }, 68 | list, 69 | } = this.state; 70 | return ( 71 | 72 | 73 | {/* 74 | 75 | 76 | 修改密码 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 修改密保 88 | 89 | 90 | 91 | 92 | 93 | 94 | */} 95 | {list.map((item) => ( 96 | 101 | 102 | 103 | 104 | {item.title} 105 | 106 | 107 | 108 | 112 | 113 | 114 | 115 | ))} 116 | {/* 120 | 121 | 122 | 123 | 关于我们 124 | 125 | 126 | 127 | 128 | {SDKVersion ? "v" + SDKVersion : ""} 129 | 130 | 131 | 132 | 136 | 137 | 138 | 139 | 143 | 144 | 145 | 146 | 使用协议 147 | 148 | 149 | 150 | 151 | 155 | 156 | 157 | 158 | 162 | 163 | 164 | 165 | 隐私政策 166 | 167 | 168 | 169 | 170 | 174 | 175 | 176 | */} 177 | 178 | {/* 179 | 186 | */} 187 | 188 | ); 189 | } 190 | } 191 | 192 | export default Setting; 193 | -------------------------------------------------------------------------------- /src/pages/users/setting.module.scss: -------------------------------------------------------------------------------- 1 | .setting { 2 | position: absolute; 3 | 4 | width: 100%; 5 | min-height: 100%; 6 | background-color: #f7f7f9; 7 | } 8 | .setting-link { 9 | width: 100%; 10 | padding: 40px 0; 11 | } 12 | .setting-link__item { 13 | position: relative; 14 | overflow: hidden; 15 | width: 90%; 16 | margin: 40px auto 0 auto; 17 | height: 140px; 18 | border-radius: 16px; 19 | background-color: #fff; 20 | } 21 | .setting-link__extra { 22 | position: absolute; 23 | right: 90px; 24 | top: 0; 25 | width: 30%; 26 | text-align: right; 27 | } 28 | .setting-link__extra-text { 29 | font-size: 30px; 30 | color: #ccc; 31 | line-height: 140px; 32 | } 33 | .setting-link__extra--help { 34 | width: 60px; 35 | height: 60px; 36 | } 37 | .setting-link__title { 38 | position: absolute; 39 | left: 40px; 40 | top: 0; 41 | z-index: 99; 42 | width: 90%; 43 | height: 100%; 44 | } 45 | .setting-link__title-text { 46 | position: absolute; 47 | top: 0; 48 | font-size: 34px; 49 | color: #2a2a30; 50 | 51 | height: 140px; 52 | line-height: 140px; 53 | } 54 | .setting-link__arrow { 55 | position: absolute; 56 | right: 20px; 57 | top: 43px; 58 | width: 50px; 59 | } 60 | .setting-link__arrow--active { 61 | width: 50px; 62 | height: 50px; 63 | } 64 | .setting-link__title-chart-text { 65 | width: 100%; 66 | font-size: 34px; 67 | color: #2a2a30; 68 | line-height: 140px; 69 | padding-right: 20px; 70 | } 71 | -------------------------------------------------------------------------------- /src/pages/webview/article_detail.jsx: -------------------------------------------------------------------------------- 1 | import Taro, { Component } from "@tarojs/taro"; 2 | import { View, RichText } from "@tarojs/components"; 3 | import httpRequest from "@/src/utils/request"; 4 | 5 | class ArticleDetail extends Component { 6 | constructor() { 7 | super(...arguments); 8 | this.state = { 9 | detailString: "", 10 | }; 11 | this.env = process.env.TARO_ENV; 12 | } 13 | componentDidMount() { 14 | const { url } = this.$router.params; 15 | httpRequest.get(url).then((r) => { 16 | Taro.setNavigationBarTitle({ 17 | title: r.data.value.title || "袋小鼠爱编程", 18 | }); 19 | this.setState({ 20 | detailString: r.data.value.content, 21 | }); 22 | }); 23 | } 24 | 25 | render() { 26 | return ( 27 | 28 | 29 | 30 | ); 31 | } 32 | } 33 | 34 | export default ArticleDetail; 35 | -------------------------------------------------------------------------------- /src/pages/webview/index.jsx: -------------------------------------------------------------------------------- 1 | import Taro, { Component } from "@tarojs/taro"; 2 | import { WebView, View, RichText } from "@tarojs/components"; 3 | import { getGlobalData } from "@/src/utils"; 4 | import httpRequest from "@/src/utils/request"; 5 | 6 | const re = /^\/api\//i; // 来源没有 api 标识,则跳转 webview 7 | 8 | class WebViewIndex extends Component { 9 | constructor() { 10 | super(...arguments); 11 | this.state = { 12 | detailString: "", 13 | }; 14 | this.env = process.env.TARO_ENV; 15 | } 16 | componentWillMount() { 17 | Taro.setNavigationBarTitle({ 18 | title: this.$router.params.pageTitle || "袋小鼠爱编程", 19 | }); 20 | } 21 | componentDidMount() { 22 | const { source } = this.$router.params; 23 | if (re.test(source)) { 24 | httpRequest.get(source).then((r) => { 25 | this.setState({ 26 | detailString: r.data.value.content, 27 | }); 28 | }); 29 | } 30 | } 31 | 32 | render() { 33 | const { source } = this.$router.params; 34 | 35 | return re.test(source) ? ( 36 | 37 | 38 | 39 | ) : ( 40 | 43 | ); 44 | } 45 | } 46 | export default WebViewIndex; 47 | -------------------------------------------------------------------------------- /src/reducers/counter.js: -------------------------------------------------------------------------------- 1 | import { ADD, MINUS } from '../constants/counter' 2 | 3 | const INITIAL_STATE = { 4 | num: 0 5 | } 6 | 7 | export default function counter (state = INITIAL_STATE, action) { 8 | switch (action.type) { 9 | case ADD: 10 | return { 11 | ...state, 12 | num: state.num + 1 13 | } 14 | case MINUS: 15 | return { 16 | ...state, 17 | num: state.num - 1 18 | } 19 | default: 20 | return state 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/reducers/index.js: -------------------------------------------------------------------------------- 1 | import { combineReducers } from 'redux' 2 | import counter from './counter' 3 | 4 | export default combineReducers({ 5 | counter 6 | }) 7 | -------------------------------------------------------------------------------- /src/store/index.js: -------------------------------------------------------------------------------- 1 | import { createStore, applyMiddleware, compose } from 'redux' 2 | import thunkMiddleware from 'redux-thunk' 3 | import rootReducer from '../reducers' 4 | 5 | const composeEnhancers = 6 | typeof window === 'object' && 7 | window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ ? 8 | window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__({ 9 | // Specify extension’s options like name, actionsBlacklist, actionsCreators, serialize... 10 | }) : compose 11 | 12 | const middlewares = [ 13 | thunkMiddleware 14 | ] 15 | 16 | if (process.env.NODE_ENV === 'development' && process.env.TARO_ENV !== 'quickapp') { 17 | middlewares.push(require('redux-logger').createLogger()) 18 | } 19 | 20 | const enhancer = composeEnhancers( 21 | applyMiddleware(...middlewares), 22 | // other store enhancers if any 23 | ) 24 | 25 | export default function configStore () { 26 | const store = createStore(rootReducer, enhancer) 27 | return store 28 | } 29 | -------------------------------------------------------------------------------- /src/utils/index.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: Michael Xu 3 | * @Date: 2020-02-02 20:40:44 4 | * @LastEditTime: 2020-06-15 12:03:29 5 | * @LastEditors: Michael Xu 6 | * @Description: 7 | * @FilePath: /StudentMultiWebClient/src/utils/index.js 8 | * @Blog: https://www.michaelxu.cn/ 9 | */ 10 | 11 | import Taro from "@tarojs/taro"; 12 | 13 | const globalData = {}; 14 | 15 | function setGlobalData(key, val) { 16 | globalData[key] = val; 17 | } 18 | 19 | function getGlobalData(key) { 20 | return globalData[key]; 21 | } 22 | 23 | setGlobalData("businessDomain", "https://api.codekid.top"); 24 | 25 | function isEmptyObject(obj) { 26 | if (!obj) { 27 | return true; 28 | } 29 | for (const prop in obj) { 30 | if (obj.hasOwnProperty(prop)) { 31 | return false; 32 | } 33 | } 34 | return true; 35 | } 36 | 37 | //获取当前系统信息 38 | function getSystemInfo() { 39 | try { 40 | const systemInfo = Taro.getStorageSync("SYSTEMINFO"); 41 | if (systemInfo !== "") { 42 | return systemInfo; 43 | } 44 | } catch (err) { 45 | console.log(err); 46 | } 47 | 48 | try { 49 | const systemInfo = Taro.getSystemInfoSync(); 50 | Taro.setStorageSync("SYSTEMINFO", systemInfo); 51 | return systemInfo; 52 | } catch (err) { 53 | console.log(err); 54 | return {}; 55 | } 56 | } 57 | 58 | function showShareMenu() { 59 | if (process.env.TARO_ENV === "qq") { 60 | // eslint-disable-next-line no-undef 61 | qq.showShareMenu({ 62 | showShareItems: ["qq", "qzone", "wechatFriends", "wechatMoment"] 63 | }); 64 | } else if (process.env.TARO_ENV === "tt") { 65 | // eslint-disable-next-line no-undef 66 | tt.showShareMenu({ 67 | success() { 68 | console.log(`showShareMenu 调用成功`); 69 | }, 70 | fail() { 71 | console.log(`showShareMenu 调用失败`); 72 | } 73 | }); 74 | } 75 | } 76 | export { 77 | setGlobalData, 78 | getGlobalData, 79 | isEmptyObject, 80 | getSystemInfo, 81 | showShareMenu 82 | }; 83 | -------------------------------------------------------------------------------- /src/utils/request.js: -------------------------------------------------------------------------------- 1 | import Taro from "@tarojs/taro"; 2 | import { getGlobalData } from "@/src/utils"; 3 | 4 | // 请求拦截器 5 | // const customInterceptor = (chain) => { 6 | // const requestParams = chain.requestParams 7 | // return chain.proceed(requestParams).then(res => { 8 | // debugger 9 | // if (res.statusCode === HTTP_STATUS.NOT_FOUND) { 10 | // return Promise.reject("请求资源不存在") 11 | 12 | // } else if (res.statusCode === HTTP_STATUS.BAD_GATEWAY) { 13 | // return Promise.reject("服务端出现了问题") 14 | // } else if (res.statusCode === HTTP_STATUS.FORBIDDEN) { 15 | // // TODO 根据自身业务修改 16 | // // Taro.setStorageSync("Authorization", "") 17 | // return Promise.reject("没有权限访问"); 18 | // } else if (res.statusCode === HTTP_STATUS.AUTHENTICATE) { 19 | // // TODO 根据自身业务修改 20 | // // Taro.setStorageSync("Authorization", "") 21 | // return Promise.reject("需要鉴权") 22 | // } else if (res.statusCode === HTTP_STATUS.SUCCESS) { 23 | // return res.data 24 | // } 25 | // }) 26 | // } 27 | 28 | // const interceptors = [customInterceptor, Taro.interceptors.logInterceptor] 29 | 30 | // interceptors.forEach(i => Taro.addInterceptor(i)) 31 | 32 | // http 状态配置 33 | // const HTTP_STATUS = { 34 | // SUCCESS: 200, 35 | // CREATED: 201, 36 | // ACCEPTED: 202, 37 | // CLIENT_ERROR: 400, 38 | // AUTHENTICATE: 401, 39 | // FORBIDDEN: 403, 40 | // NOT_FOUND: 404, 41 | // SERVER_ERROR: 500, 42 | // BAD_GATEWAY: 502, 43 | // SERVICE_UNAVAILABLE: 503, 44 | // GATEWAY_TIMEOUT: 504 45 | // } 46 | 47 | const getBaseUrl = url => { 48 | // 根据请求不同返回不同的 BASE_URL 49 | let BASE_URL = ""; 50 | if (process.env.NODE_ENV === "development") { 51 | // 开发环境 52 | if (url.includes("/api/")) { 53 | BASE_URL = getGlobalData("businessDomain"); 54 | // BASE_URL = '' 55 | } else { 56 | BASE_URL = ""; 57 | } 58 | } else { 59 | // 生产环境 60 | if (url.includes("/api/")) { 61 | BASE_URL = getGlobalData("businessDomain"); 62 | } else { 63 | BASE_URL = ""; 64 | } 65 | } 66 | return BASE_URL; 67 | }; 68 | 69 | /** 70 | * Requests a URL, returning a promise. 71 | * 72 | * @param {string} url The URL we want to request 73 | * @param {object} [options] The options we want to pass to "fetch" 74 | * @return {object} An object containing either "data" or "err" 75 | */ 76 | 77 | class httpRequest { 78 | baseOptions(params, method = "GET") { 79 | let { url, data } = params; 80 | const BASE_URL = getBaseUrl(url); 81 | let contentType = "application/json"; 82 | contentType = params.contentType || contentType; 83 | const option = { 84 | url: BASE_URL + url, 85 | data: data, 86 | method: method, 87 | header: { 88 | "content-type": contentType, 89 | "X-SS-API-KEY": "7538c18a-9588-40c5-995b-b8a4adf04095" // 第三方生成 90 | // 'Authorization': Taro.getStorageSync('Authorization') 91 | } 92 | }; 93 | return Taro.request(option); 94 | } 95 | 96 | get(url, data = "") { 97 | let option = { url, data }; 98 | return this.baseOptions(option); 99 | } 100 | 101 | post(url, data, contentType) { 102 | let params = { url, data, contentType }; 103 | return this.baseOptions(params, "POST"); 104 | } 105 | 106 | put(url, data = "") { 107 | let option = { url, data }; 108 | return this.baseOptions(option, "PUT"); 109 | } 110 | 111 | delete(url, data = "") { 112 | let option = { url, data }; 113 | return this.baseOptions(option, "DELETE"); 114 | } 115 | } 116 | 117 | export default new httpRequest(); 118 | --------------------------------------------------------------------------------