Commit b98a5f82 by 王树冬

init

parents
# http://editorconfig.org
root = true
[*]
indent_style = space
indent_size = 2
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
[*.md]
trim_trailing_whitespace = false
{
"extends": ["taro"],
"rules": {
"no-unused-vars": ["error", { "varsIgnorePattern": "Taro" }],
"react/jsx-filename-extension": [1, { "extensions": [".js", ".jsx", ".tsx"] }]
},
"parser": "babel-eslint"
}
dist/
.temp/
.rn_temp/
node_modules/
module.exports = {
env: {
NODE_ENV: '"development"'
},
defineConstants: {
},
weapp: {},
h5: {}
}
const config = {
projectName: 'demo',
date: '2018-9-18',
designWidth: 750,
sourceRoot: 'src',
outputRoot: 'dist',
plugins: {
babel: {
sourceMap: true,
presets: [
'env'
],
plugins: [
'transform-class-properties',
'transform-decorators-legacy',
'transform-object-rest-spread'
]
},
typescript: {
compilerOptions: {
allowSyntheticDefaultImports: true,
baseUrl: '.',
declaration: false,
experimentalDecorators: true,
jsx: 'preserve',
jsxFactory: 'Nerv.createElement',
module: 'commonjs',
moduleResolution: 'node',
noImplicitAny: false,
noUnusedLocals: true,
outDir: './dist/',
preserveConstEnums: true,
removeComments: false,
rootDir: '.',
sourceMap: true,
strictNullChecks: true,
target: 'es6'
},
include: [
'src/**/*'
],
exclude: [
'node_modules'
],
compileOnSave: false
}
},
defineConstants: {
},
weapp: {
},
h5: {
publicPath: '/',
staticDirectory: 'static',
module: {
postcss: {
autoprefixer: {
enable: true
}
}
}
}
}
module.exports = function (merge) {
if (process.env.NODE_ENV === 'development') {
return merge({}, config, require('./dev'))
}
return merge({}, config, require('./prod'))
}
module.exports = {
env: {
NODE_ENV: '"production"'
},
defineConstants: {
},
weapp: {},
h5: {}
}
{
"name": "demo",
"version": "1.0.0",
"private": true,
"description": "demo",
"main": "index.js",
"scripts": {
"build:weapp": "taro build --type weapp",
"build:h5": "taro build --type h5",
"build:rn": "taro build --type rn",
"dev:weapp": "npm run build:weapp -- --watch",
"dev:h5": "npm run build:h5 -- --watch",
"dev:rn": "npm run build:rn -- --watch",
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "MIT",
"dependencies": {
"@tarojs/async-await": "^1.0.0-beta.29",
"@tarojs/components": "^1.0.0-beta.29",
"@tarojs/redux": "^1.0.0-beta.29",
"@tarojs/redux-h5": "^1.0.0-beta.29",
"@tarojs/router": "^1.0.0-beta.29",
"@tarojs/taro": "^1.0.0-beta.29",
"@tarojs/taro-h5": "^1.0.0-beta.29",
"@tarojs/taro-weapp": "^1.0.0-beta.29",
"nervjs": "^1.3.0",
"redux": "^4.0.0",
"redux-logger": "^3.0.6",
"redux-thunk": "^2.3.0"
},
"devDependencies": {
"@types/react": "^16.4.8",
"@types/webpack-env": "^1.13.6",
"@tarojs/plugin-babel": "^1.0.0-beta.29",
"@tarojs/plugin-csso": "^1.0.0-beta.29",
"@tarojs/plugin-stylus": "^1.0.0-beta.29",
"@tarojs/plugin-uglifyjs": "^1.0.0-beta.29",
"@tarojs/webpack-runner": "^1.0.0-beta.29",
"babel-plugin-transform-class-properties": "^6.24.1",
"babel-plugin-transform-decorators-legacy": "^1.3.4",
"babel-plugin-transform-jsx-stylesheet": "^0.6.5",
"babel-plugin-transform-object-rest-spread": "^6.26.0",
"babel-preset-env": "^1.6.1",
"babel-eslint": "^8.2.3",
"eslint": "^4.19.1",
"eslint-config-taro": "^1.0.0-beta.29",
"eslint-plugin-react": "^7.8.2",
"eslint-plugin-import": "^2.12.0",
"eslint-plugin-taro": "^1.0.0-beta.29"
}
}
{
"miniprogramRoot": "./dist",
"projectname": "demo",
"description": "demo",
"appid": "wx8566afef50e5f76b",
"setting": {
"urlCheck": false,
"es6": false,
"postcss": false,
"minified": false,
"newFeature": true
},
"compileType": "miniprogram",
"condition": {}
}
\ No newline at end of file
## 功能列表
[*] 增加createApiAction
[*] 封装api请求方式
import { bindActionCreators } from 'redux'
import Taro from '@tarojs/taro'
import {
ADD,
LIST,
MINUS
} from '../constants/counter'
import store from '../store'
import { createApiAction } from './index'
import api from '../service/api'
export const add = () => {
return {
type: ADD
}
}
export const minus = () => {
return {
type: MINUS
}
}
// 异步的action
export function asyncAdd() {
return dispatch => {
setTimeout(() => {
dispatch(add())
}, 2000)
}
}
// 异步的action
// export function list() {
// return dispatch => {
// Taro.request({
// url: 'http://api.shudong.wang/v1/article/list',
// data: {
// foo: 'foo',
// bar: 10
// },
// header: {
// 'content-type': 'application/json'
// }
// })
// // .then(res => console.log(res.data))
// }
// }
// function articleList(data) {
// return { type: LIST, payload: data }
// }
// export function list() {
// console.log('list')
// return (dispatch) => {
// // service.get('/v1/article/list')
// // .then((res) => {
// // dispatch(articleList(res.data.article))
// // })
// Taro.request({
// url: 'http://api.shudong.wang/v1/article/list',
// data: {
// foo: 'foo',
// bar: 10
// },
// header: {
// 'content-type': 'application/json'
// }
// }).then((res) => {
// dispatch(articleList(res.data.article))
// })
// }
// }
// export const list = createApiAction(LIST, params => Taro.request({
// url: 'http://api.shudong.wang/v1/article/list',
// data: params,
// header: {
// 'content-type': 'application/json'
// }
// }))
export const list = createApiAction(LIST, params => api.get('article/list', params))
export default bindActionCreators({
list,
add,
minus,
asyncAdd
}, store.dispatch)
/**
* 创建Action
*
* @export
* @param actionType Action类型
*/
export function createAction(actionType) {
return (payload) => ({
type: actionType,
payload
})
}
/**
* 创建API Action
*
* @export
* @param actionType Action类型
* @param [func] 请求API方法,返回Promise
* @returns 请求之前dispatch { type: ${actionType}_request }
* 请求成功dispatch { type: ${actionType}, payload: ${resolveData} }
* 请求失败dispatch { type: ${actionType}_failure, payload: ${rejectData} }
*/
export function createApiAction(actionType, func = () => {}) {
return (
params = {},
callback = { success: () => {}, failed: () => {} },
customActionType = actionType,
) => async (dispatch) => {
try {
dispatch({ type: `${customActionType }_request`, params });
const data = await func(params);
dispatch({ type: customActionType, params, payload: data });
callback.success && callback.success({ payload: data })
return data
} catch (e) {
dispatch({ type: `${customActionType }_failure`, params, payload: e })
callback.failed && callback.failed({ payload: e })
}
}
}
import Taro, { Component } from '@tarojs/taro'
import '@tarojs/async-await'
import { Provider } from '@tarojs/redux'
import Index from './pages/index'
import configStore from './store'
import './app.styl'
const store = configStore()
class App extends Component {
config = {
pages: [
'pages/index/index'
],
window: {
backgroundTextStyle: 'light',
navigationBarBackgroundColor: '#fff',
navigationBarTitleText: 'WeChat',
navigationBarTextStyle: 'black'
}
}
componentDidMount () {}
componentDidShow () {}
componentDidHide () {}
componentCatchError () {}
render () {
return (
<Provider store={store}>
<Index />
</Provider>
)
}
}
Taro.render(<App />, document.getElementById('app'))
export const HTTP_STATUS = {
SUCCESS: 200,
CLIENT_ERROR: 400,
AUTHENTICATE: 401,
FORBIDDEN: 403,
NOT_FOUND: 404,
SERVER_ERROR: 500,
BAD_GATEWAY: 502,
SERVICE_UNAVAILABLE: 503,
GATEWAY_TIMEOUT: 504
}
export const COMMON_STATUS = {
NOT_FOUND: -40400, // "请求资源不存在",
API_NOT_FOUND: -40401, // "请求方法不存在",
EXCEPTION: -50000, // "系统异常",
PARAM_ERROR: -40001, // "参数错误",
AUTH_FAILED: -40100, // "认证错误",
NO_PERMISION: -40302, // "没有权限",
NET_REQUEST_FAILED: -40000, // "网络请求失败",
ERROR_TENANT: -401100, // "不存在选择的公司,当租户id为空的时候",
ERROR_NO_TENANT: -401200 // "租户id错误的时候",
}
// promise status
export const SUCCESS = { success:'success'}
export const FAIL = { fail:'fail'}
export const COMPLETE = { complete:'complete'}
export const PROMISE_STATUS = {
success: 'success',
fail: 'fail',
complete: 'complete'
}
export const RESULT_STATUS = {
SUCCESS:0,
SIGNATURE_FAILED: -1200 // 签名失败
}
export const ADD = 'ADD'
export const MINUS = 'MINUS'
export const LIST = 'LIST'
<!DOCTYPE html>
<html>
<head>
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
<meta content="width=device-width,initial-scale=1,user-scalable=no" name="viewport">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-touch-fullscreen" content="yes">
<meta name="format-detection" content="telephone=no,address=no">
<meta name="apple-mobile-web-app-status-bar-style" content="white">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" >
<title>Taro</title>
<script>
!function(x){function w(){var v,u,t,tes,s=x.document,r=s.documentElement,a=r.getBoundingClientRect().width;if(!v&&!u){var n=!!x.navigator.appVersion.match(/AppleWebKit.*Mobile.*/);v=x.devicePixelRatio;tes=x.devicePixelRatio;v=n?v:1,u=1/v}if(a>=640){r.style.fontSize="40px"}else{if(a<=320){r.style.fontSize="20px"}else{r.style.fontSize=a/320*20+"px"}}}x.addEventListener("resize",function(){w()});w()}(window);
</script>
</head>
<body>
<div id="app"></div>
</body>
</html>
import Taro, { Component } from '@tarojs/taro'
import { View, Button, Text } from '@tarojs/components'
import { connect } from '@tarojs/redux'
import { add, minus, asyncAdd, list } from '../../actions/counter'
import './index.styl'
// @connect(({ counter }) => ({
// counter
// }),(dispatch) => ({
// add() {
// dispatch(add())
// },
// dec() {
// dispatch(minus())
// },
// asyncAdd() {
// dispatch(asyncAdd())
// },
// // list() {
// // dispatch(list())
// // }
// }))
@connect(
state => ({
list: state.counter.list,
}),
(dispatch) => {
console.log('dispatch', dispatch);
return {
list() {
dispatch(list())
}
}
},
)
class Index extends Component {
config = {
navigationBarTitleText: '首页'
}
constructor(props) {
super(props)
console.log('props', props);
// this.state = { date: new Date() }
// props.list()
}
componentWillReceiveProps(nextProps) {
console.log(this.props, nextProps)
}
componentWillUnmount() {
}
componentDidShow() { }
componentDidHide() { }
render() {
return (
<View className='index'>
<Button className='add_btn' onClick={this.props.add}>+</Button>
<Button className='dec_btn' onClick={this.props.dec}>-</Button>
<Button className='dec_btn' onClick={this.props.asyncAdd}>async</Button>
<Button className='dec_btn' onClick={this.props.list}>list</Button>
<View><Text>{this.props.counter.num}</Text></View>
<View><Text>Hello, World</Text></View>
<View>
{
this.props.list.map((item, index) => {
return <View key={index}>{item.title}</View>
})
}
</View>
</View >
)
}
}
export default Index
import { ADD, MINUS, LIST } from '../constants/counter'
const INITIAL_STATE = {
num: 0,
list:''
}
export default function counter (state = INITIAL_STATE, action) {
console.log('action', action)
switch (action.type) {
case ADD:
return {
...state,
num: state.num + 1
}
case MINUS:
return {
...state,
num: state.num - 1
}
case LIST:
return {
...state,
list: action.payload.data.article
}
default:
return state
}
}
import { combineReducers } from 'redux'
import counter from './counter'
export default combineReducers({
counter
})
import Taro from '@tarojs/taro'
import { HTTP_STATUS, COMMON_STATUS, RESULT_STATUS } from '../const/status.js'
// import config from '../config/index.js'
import { logError } from '../utils'
const baseURL = "http://api.shudong.wang/v1/"
// Taro.request({
// url: baseURL + '',
// data: {
// foo: 'foo',
// bar: 10
// },
// header: {
// 'content-type': 'application/json'
// }
// })
// .then(res => console.log(res.data))
const token = ''
export default {
baseOptions(params, method = 'GET') {
let { url, data } = params
// let token = getApp().globalData.token
// if (!token) login()
let contentType = 'application/x-www-form-urlencoded'
contentType = params.contentType || contentType
const option = {
isShowLoading: false,
loadingText: '正在加载',
url: baseURL + url,
data: data,
method: method,
header: { 'content-type': contentType, 'token': token },
success(res) {
return res
},
error(e) {
logError('api', '请求接口出现问题', e)
}
}
return Taro.request(option)
},
get(url, data = '') {
let option = { url, data }
return this.baseOptions(option)
},
post: function (url, data, contentType) {
let params = { url, data, contentType }
return this.baseOptions(params, 'POST')
}
}
export base = "http://api.shudong.wang/v1/"
import { createStore, applyMiddleware } from 'redux'
import thunkMiddleware from 'redux-thunk'
import { createLogger } from 'redux-logger'
import rootReducer from '../reducers'
const middlewares = [
thunkMiddleware,
createLogger()
]
export default function configStore () {
const store = createStore(rootReducer, applyMiddleware(...middlewares))
return store
}
export const promisify = (func, ctx) => {
// 返回一个新的function
return function () {
// 初始化this作用域
var ctx = ctx || this;
// 新方法返回的promise
return new Promise((resolve, reject) => {
// 调用原来的非promise方法func,绑定作用域,传参,以及callback(callback为func的最后一个参数)
func.call(ctx, ...arguments, function () {
// 将回调函数中的的第一个参数error单独取出
var args = Array.prototype.map.call(arguments, item => item);
var err = args.shift();
// 判断是否有error
if (err) {
reject(err)
} else {
// 没有error则将后续参数resolve出来
args = args.length > 1 ? args : args[0];
resolve(args);
}
});
})
};
};
export const getToken = wx.getStorageSync('token')
export const hideToast = wx.hideToast()
// 下载图片
export const downLoadImg = (imgurl, msg) => {
return new Promise((resolve, reject) => {
let that = this
// util.showToast(msg + 'download...')
wx.downloadFile({
url: imgurl,
complete: function (res) {
console.log(res)
if (res.statusCode === 200) {
resolve(res.tempFilePath)
} else {
console.log('downloadstatusCode', res)
reject(new Error(res))
}
},
fail: function (res) {
console.log('downloadFilefail', res)
}
})
})
}
export const promiseImage = (url) => {
return new Promise(function (resolve, reject) {
resolve(url)
})
}
export const report = (name, filed) => {
wx.reportAnalytics(name, filed)
}
export const isChinese = (str) => {
if (escape(str).indexOf("%u") < 0) return false
return true
}
export const handleName = (str) => {
let res = emoj2str(str)
if (isChinese(res)) {
res = res.length > 4 ? res.slice(0, 4) + '...' : res
} else {
res = res.length > 7 ? res.slice(0, 7) + '...' : res
}
return res
}
export const emoj2str = (str) => {
return unescape(escape(str).replace(/\%uD.{3}/g, ''))
}
/*获取当前页url*/
export const getCurrentPageUrl = () => {
let pages = getCurrentPages()
let currentPage = pages[pages.length - 1]
let url = currentPage.route
return url
}
export const getSysteminfo = () => {
try {
let deviceInfo = wx.getSystemInfoSync()
const device = JSON.stringify(deviceInfo)
} catch (e) {
console.error('not support getSystemInfoSync api', err.message)
}
return device
}
export const formatTime = date => {
const year = date.getFullYear()
const month = date.getMonth() + 1
const day = date.getDate()
const hour = date.getHours()
const minute = date.getMinutes()
const second = date.getSeconds()
return [year, month, day].map(formatNumber).join('/') + ' ' + [hour, minute, second].map(formatNumber).join(':')
}
export const formatNumber = n => {
n = n.toString()
return n[1] ? n : '0' + n
}
import { getCurrentPageUrl, formatTime } from './common'
// var fundebug = require('../libs/fundebug.0.8.2.min.js');
/**
*
* @param {string} name 错误名字
* @param {string} action 错误动作描述
* @param {string} info 错误信息,通常是 fail 返回的
*/
export const logError = (name, action, info) => {
if (!info) {
info = 'empty'
}
try {
let deviceInfo = wx.getSystemInfoSync()
var device = JSON.stringify(deviceInfo)
} catch (e) {
console.error('not support getSystemInfoSync api', err.message)
}
let time = formatTime(new Date())
console.error(time, name, action, info, device)
// if (typeof action !== 'object') {
// fundebug.notify(name, action, info)
// }
// fundebug.notifyError(info, { name, action, device, time })
if (typeof info === 'object') {
info = JSON.stringify(info)
}
wx.reportAnalytics('error', {
page: getCurrentPageUrl(),
device: device,
time: time,
content: info,
event: action
})
}
export const reportError = (data) => {
wx.reportAnalytics(name, filed)
}
export const promisify = (func, ctx) => {
// 返回一个新的function
return function () {
// 初始化this作用域
var ctx = ctx || this;
// 新方法返回的promise
return new Promise((resolve, reject) => {
// 调用原来的非promise方法func,绑定作用域,传参,以及callback(callback为func的最后一个参数)
func.call(ctx, ...arguments, function () {
// 将回调函数中的的第一个参数error单独取出
var args = Array.prototype.map.call(arguments, item => item);
var err = args.shift();
// 判断是否有error
if (err) {
reject(err)
} else {
// 没有error则将后续参数resolve出来
args = args.length > 1 ? args : args[0];
resolve(args);
}
});
})
};
};
export const getToken = wx.getStorageSync('token')
export const hideToast = wx.hideToast()
// 下载图片
export const downLoadImg = (imgurl, msg) => {
return new Promise((resolve, reject) => {
let that = this
// util.showToast(msg + 'download...')
wx.downloadFile({
url: imgurl,
complete: function (res) {
console.log(res)
if (res.statusCode === 200) {
resolve(res.tempFilePath)
} else {
console.log('downloadstatusCode', res)
reject(new Error(res))
}
},
fail: function (res) {
console.log('downloadFilefail', res)
}
})
})
}
export const promiseImage = (url) => {
return new Promise(function (resolve, reject) {
resolve(url)
})
}
export const report = (name, filed) => {
wx.reportAnalytics(name, filed)
}
export const isChinese = (str) => {
if (escape(str).indexOf("%u") < 0) return false
return true
}
export const handleName = (str) => {
let res = emoj2str(str)
if (isChinese(res)) {
res = res.length > 4 ? res.slice(0, 4) + '...' : res
} else {
res = res.length > 7 ? res.slice(0, 7) + '...' : res
}
return res
}
export const emoj2str = (str) => {
return unescape(escape(str).replace(/\%uD.{3}/g, ''))
}
/*获取当前页url*/
export const getCurrentPageUrl = () => {
let pages = getCurrentPages()
let currentPage = pages[pages.length - 1]
let url = currentPage.route
return url
}
export const getSysteminfo = () => {
try {
let deviceInfo = wx.getSystemInfoSync()
const device = JSON.stringify(deviceInfo)
} catch (e) {
console.error('not support getSystemInfoSync api', err.message)
}
return device
}
export const formatTime = date => {
const year = date.getFullYear()
const month = date.getMonth() + 1
const day = date.getDate()
const hour = date.getHours()
const minute = date.getMinutes()
const second = date.getSeconds()
return [year, month, day].map(formatNumber).join('/') + ' ' + [hour, minute, second].map(formatNumber).join(':')
}
export const formatNumber = n => {
n = n.toString()
return n[1] ? n : '0' + n
}
export const logError = (name, action, info) => {
if (!info) {
info = 'empty'
}
try {
let deviceInfo = wx.getSystemInfoSync()
var device = JSON.stringify(deviceInfo)
} catch (e) {
console.error('not support getSystemInfoSync api', err.message)
}
let time = formatTime(new Date())
console.error(time, name, action, info, device)
// if (typeof action !== 'object') {
// fundebug.notify(name, action, info)
// }
// fundebug.notifyError(info, { name, action, device, time })
if (typeof info === 'object') {
info = JSON.stringify(info)
}
}
This source diff could not be displayed because it is too large. You can view the blob instead.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment