lhl преди 4 години
родител
ревизия
ad0ade8bfc
променени са 17 файла, в които са добавени 3070 реда и са изтрити 55 реда
  1. 25 0
      components/wyb-drop-down/iconfont.css
  2. 414 0
      components/wyb-drop-down/wyb-drop-down.vue
  3. 48 0
      lang/en.js
  4. 24 0
      lang/es.js
  5. 21 0
      lang/i18n.js
  6. 2210 0
      lang/i18nJs.js
  7. 48 0
      lang/zh_cn.js
  8. 5 2
      main.js
  9. 25 18
      pages/index/index.vue
  10. 6 6
      pages/index/infoDetail.vue
  11. 2 2
      pages/public/login.vue
  12. 218 0
      pages/public/nav.vue
  13. 3 3
      pages/user/applyList.vue
  14. 2 2
      pages/user/promotion.vue
  15. 8 7
      pages/user/user.vue
  16. 7 2
      store/index.js
  17. 4 13
      utils/request.js

+ 25 - 0
components/wyb-drop-down/iconfont.css

@@ -0,0 +1,25 @@
+@font-face {font-family: "iconfont";
+  src: url('data:application/x-font-woff2;charset=utf-8;base64,d09GMgABAAAAAAMoAAsAAAAABxwAAALZAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHEIGVgCDHAqBYIFNATYCJAMQCwoABCAFhG0HPRs0BsgusG3YowCKZblG/A248I8FOyAe+Oye987uPHySFUCVQo0KTFJCRZnz739uc6TZ6xcSFkmmSfPs/p8faiVYyJAysa8jwJbrp83gaCY/j/s8l9O7q4ACmd/Ochtr0Z5+1AswDijQsQZt4QI6QW6pXcSBwSv/1nYCCqqqsdC7M5oKSRHpFxDmudwQkr2QKEbZvCA7MzUKh2Tkk93JOxzUvw//aBnyJDIpMnTQjLYt1H4v9UeQN/18GCcJYQJ3dgYpGiMSZs2mppCFiJ8qyI6iLfLyEn7P/b7mjxDH1smHZfQvjyCRErJIZWHQ2kun/J7jNIHfTzQJf4gVUvghxnw/0x4DfV5lXaBHlFVi7aO0/bxWdv6+cPdRmdlrbzn+qfO6PVN6994+P/v5PWXZ++LdvWUs9gsXP7QrtrfB91P9aflbn1u37JV5vmPHmbH/a+bW/pculdBKpMfTy/pJ27c1d3s3Ha40b4Xnb7c73PMn7hxVM+r+psb222nvS698xqM+qUXITmlvaakgkG5KhgsC6ePkJarZcby5/0ws1vn5QhH8iDY/1tYIZoAvBViBWAWwLpYq4ogxV3N5FYzKghIJClIX6MxR0m9XGMuAawnyyhwI5lRpkcqrTUZeY2QU0hpZed1QUCP9ZhdSyhKyEAugoe0OguIeIlHUK6SKe09G3q/IKOs/ZBUPKQoaEUotWUjdMDvda4XGBm2YcoTZFkWMuTZpUz1Gvg2MVVelBXNcrd0otGjafJjtYoSrK0Ys3fHKsg2DGSsKoa+zGwYBwaIVeWhtCrM2m0W1WbMZc3cqTKVQSOtlBRk2kA1McQRms5AIk8030qPvjyFuK2BYrTAW0nNoZc1tH7TQVHMA2dVHIMav3LLUDlexzAYDZlghIdDX8aKApghYNN/JgywbBbMOJBaqmnmNZkD1heeNIYZboCByVgxJSEMMGdlpW5fTVplG+0he5RqCAAAAAA==') format('woff2')
+}
+
+.iconfont {
+  font-family: "iconfont" !important;
+  margin-top: 5rpx;
+  font-style: normal;
+  -webkit-font-smoothing: antialiased;
+  -moz-osx-font-smoothing: grayscale;
+}
+
+.icon-selected:before {
+  content: "\e613";
+}
+
+.icon-down:before {
+  font-weight: bold;
+  content: "\e67a";
+}
+
+.icon-down-fill:before {
+  content: "\e701";
+}
+

+ 414 - 0
components/wyb-drop-down/wyb-drop-down.vue

@@ -0,0 +1,414 @@
+<template>
+	<view 
+	 class="wyb-drop-down-box"
+	 :style="{
+		 '--duration': duration + 'ms',
+		 '--autoContentTop': autoContentTop}">
+		
+		<view class="wyb-drop-down-container" @tap.stop.prevent @touchmove.stop.prevent>
+			<view 
+			 class="wyb-drop-down-header"
+			 :style="{
+				 zIndex: zIndex,
+				 backgroundColor: bgColor.header}">
+				<view 
+				 class="wyb-drop-down-header-item"
+				 v-for="(item,index) in options"
+				 :key="item.header"
+				 @tap.stop="onHeaderTap(index)"
+				 :style="{fontSize: fontSize.header + 'rpx'}">
+					<text
+					 class="wyb-drop-down-header-item-label"
+					 :style="{
+						 fontWeight: headerActiveIndex === index && dropOver && activeWeight ? 'bold' : 'normal',
+						 color: headerActiveIndex === index && dropOver ? activeColor: defaultColor}">{{item.header}}</text>
+					<text
+					 v-if="dropIcon === 'fill'"
+					 class="iconfont icon-down-fill wyb-drop-down-header-item-icon"
+					 :class="[headerActiveIndex === index && dropOver ? 'wyb-drop-down-header-item-icon-active' : '']"
+					 :style="{
+						 fontSize: fontSize.header - 5 + 'rpx',
+						 color: headerActiveIndex === index && dropOver ? activeColor: defaultColor}" />
+					<text
+					 v-if="dropIcon==='line'"
+					 class="iconfont icon-down wyb-drop-down-header-item-icon"
+					 :class="[headerActiveIndex === index && dropOver ? 'wyb-drop-down-header-item-icon-active' : '']"
+					 :style="{
+						 fontSize: fontSize.header - 5 + 'rpx',
+						 transformOrigin: '50% 45%',
+						 color: headerActiveIndex === index && dropOver ? activeColor: defaultColor}" />
+					<view class="wyb-drop-down-vline" v-if="index !== options.length - 1" />
+				</view>
+			</view>
+			
+			<scroll-view 
+			 v-if="dropDown"
+			 class="wyb-drop-down-content" 
+			 :class="[dropOver ? 'wyb-drop-down-content-active' : '']"
+			 :scroll-y="scroll"
+			 :enable-flex="true"
+			 :scroll-anchoring="true"
+			 :style="{
+				 zIndex: zIndex - 1,
+				 fontSize: fontSize.content + 'rpx',
+				 backgroundColor: bgColor.content,
+				 borderBottomLeftRadius: radius + 'px',
+				 borderBottomRightRadius: radius + 'px',
+				 minHeight: minHeight + 'rpx',
+				 height: autoHeight ? 'auto' : minHeight + 'rpx',
+				 maxHeight: autoHeight && maxHeight ? maxHeight + 'rpx' : 'auto'}">
+				 <view class="wyb-drop-down-content-box" v-for="(item,index) in options" :key="contentBoxKey(index)">
+				 	<view v-if="item['custom'] && headerActiveIndex === index && dropDown" class="wyb-drop-down-content-slot">
+						<slot></slot>
+					</view>
+					<view
+					 v-if="!item['custom'] && headerActiveIndex === index && dropDown"
+					 class="wyb-drop-down-content-item"
+					 v-for="(content,zIndex) in item['contents']"
+					 :key="content"
+					 @tap.stop="onContentItemsTap(zIndex)">
+						<text
+						 class="wyb-drop-down-content-item-label"
+						 :style="{color: contentActiveIndexList[headerActiveIndex]['index'] === zIndex && dropOver ? activeColor: defaultColor}">
+							{{content}}
+						</text>
+						<text
+						 v-if="contentActiveIndexList[headerActiveIndex]['index'] === zIndex && dropOver"
+						 :style="{color: activeColor}"
+						 class="iconfont icon-selected wyb-drop-down-content-item-icon" />
+						<view class="wyb-drop-down-line" v-if="zIndex !== options[headerActiveIndex].contents.length - 1" />
+					</view>
+				 </view>
+			</scroll-view>
+		</view>
+		
+		<view
+		 v-if="dropDown"
+		 class="wyb-drop-down-mask"
+		 :class="[dropOver ? 'wyb-drop-down-mask-active' : '']"
+		 @tap.stop="close"
+		 @touchmove.stop.prevent
+		 :style="{
+			 zIndex: zIndex - 2,
+			 height: screenHeight + 'px',
+			 backgroundColor: 'rgba(0, 0, 0, ' + maskAlpha + ')'}" />
+	</view>
+</template>
+
+<script>
+	export default {
+		data() {
+			return {
+				dropDown: false,
+				dropOver: false,
+				duration: 500,
+				contents: this.options[0].contents || [0],
+				headerActiveIndex: 0,
+				contentActiveIndexList: []
+			}
+		},
+		computed: {
+			autoContentTop() {
+				return `${44 + this.rpxToPx(100)}px`
+			},
+			screenHeight() {
+				return uni.getSystemInfoSync().screenHeight
+			},
+			screenWidth() {
+				return uni.getSystemInfoSync().screenWidth
+			},
+			contentBoxKey() {
+				return function(index) {
+					return `option${index}`
+				}
+			}
+		},
+		props: {
+			options: {
+				type: Array,
+				default() {
+					return [{
+						header: 'A',
+						contents: ['1', '2']
+					}]
+				}
+			},
+			defaultIndexList: {
+				type: Array,
+				default() {
+					return []
+				}
+			},
+			autoHeight: {
+				type: Boolean,
+				default: true
+			},
+			minHeight: {
+				type: [String, Number],
+				default: 10
+			},
+			maxHeight: {
+				type: [String, Number],
+				default: 600
+			},
+			scroll: {
+				type: Boolean,
+				default: true
+			},
+			radius: {
+				type: [String, Number],
+				default: '0'
+			},
+			activeColor: {
+				type: String,
+				default: '#2979ff'
+			},
+			activeWeight: {
+				type: Boolean,
+				default: true
+			},
+			defaultColor: {
+				type: String,
+				default: '#333'
+			},
+			bgColor: {
+				type: Object,
+				default() {
+					return {
+						header: '#fff',
+						content: '#fff'
+					}
+				}
+			},
+			dropIcon: {
+				type: String,
+				default: 'fill'
+			},
+			fontSize: {
+				type: Object,
+				default() {
+					return {
+						header: 30,
+						content: 30
+					}
+				}
+			},
+			maskAlpha: {
+				type: [String, Number],
+				default: '0.5'
+			},
+			zIndex: {
+				type: Number,
+				default: 500
+			}
+		},
+		mounted() {
+			if (this.defaultIndexList.length === 0) {
+				this.options.forEach((item, index) => {
+					if (!item.custom) {
+						this.contentActiveIndexList.push({headerIndex: index, index: 0})
+					} else {
+						this.contentActiveIndexList.push({headerIndex: index, custom: true})
+					}
+				})
+			} else {
+				let i = 0
+				this.options.forEach((item, index) => {
+					if (!item.custom) {
+						this.contentActiveIndexList.push([...this.defaultIndexList][i])
+						i++
+					} else {
+						this.contentActiveIndexList.push({headerIndex: index, custom: true})
+					}
+				})
+			}
+		},
+		methods: {
+			onHeaderTap(index) {
+				let item = this.options[index]
+				if (Object.is(this.headerActiveIndex, index) && this.dropOver) {
+					this.close()
+				} else {
+					this.headerActiveIndex = index
+					if (item.custom) {
+						this.$emit('change', {
+							headerIndex: index,
+							header: this.options[index].header
+						})
+					}
+					this.dropDown = true
+					this.$nextTick(() => {
+						this.dropOver = true
+						this.$emit('show')
+					})
+				}
+			},
+			onContentItemsTap(index) {
+				this.contentActiveIndexList[this.headerActiveIndex]['index'] = index
+				this.$forceUpdate()
+				let event = {
+					headerIndex: this.headerActiveIndex,
+					header: this.options[this.headerActiveIndex]['header'],
+					contentIndex: index,
+					content: this.options[this.headerActiveIndex]['contents'][index],
+					contentActiveIndexList: this.contentActiveIndexList
+				}
+				this.$emit('select', event)
+			},
+			close() {
+				this.dropOver = false
+				setTimeout(() => {
+					this.dropDown = false
+					this.$emit('hide')
+				}, this.duration)
+			},
+			rpxToPx(rpx) {
+				return rpx / 750 * this.screenWidth
+			}
+		}
+	}
+</script>
+
+<style>
+	@import './iconfont.css';
+	.wyb-drop-down-mask {
+		position: fixed;
+		top: 44px;
+		/* #ifndef H5 */
+		top: 0;
+		/* #endif */
+		left: 0;
+		bottom: 0;
+		right: 0;
+		opacity: 0;
+		transition: opacity var(--duration);
+		z-index: 498;
+	}
+	
+	.wyb-drop-down-mask-active {
+		opacity: 1;
+		transition: opacity var(--duration);
+	}
+	
+	.wyb-drop-down-header {
+		position: fixed;
+		top: 44px;
+		/* #ifndef H5 */
+		top: 0;
+		/* #endif */
+		left: 0;
+		right: 0;
+		display: flex;
+		flex-direction: row;
+		background-color: #fff;
+		z-index: 500;
+	}
+	
+	.wyb-drop-down-header-item {
+		flex: 1;
+		height: 100rpx;
+		font-size: 30rpx;
+		border-bottom: 1px solid #eee;
+		display: flex;
+		flex-direction: row;
+		align-items: center;
+		justify-content: center;
+		position: relative;
+	}
+	
+	.wyb-drop-down-header-item-label {
+		display: flex;
+		flex-direction: row;
+		align-items: center;
+		justify-content: flex-end;
+	}
+	
+	.wyb-drop-down-header-item-icon {
+		margin-left: 20rpx;
+		display: flex;
+		flex-direction: row;
+		align-items: center;
+		justify-content: flex-start;
+		transform-origin: 50% 40%;
+		transform: rotate(0);
+		transition: transform var(--duration);
+	}
+	
+	.wyb-drop-down-header-item-icon-active {
+		transform: rotate(180deg);
+		transition: transform var(--duration);
+	}
+	
+	.wyb-drop-down-content {
+		position: fixed;
+		top: var(--autoContentTop);
+		/* #ifndef H5 */
+		top: 100rpx;
+		/* #endif */
+		left: 0;
+		right: 0;
+		z-index: 499;
+		display: flex;
+		flex-direction: column;
+		align-items: flex-start;
+		background-color: #fff;
+		transform: translateY(-100%);
+		transition: transform var(--duration);
+	}
+	
+	.wyb-drop-down-content-active {
+		transform: translateY(0);
+		transition: transform var(--duration);
+	}
+	
+	.wyb-drop-down-content-item {
+		width: 100%;
+		height: 100rpx;
+		font-size: 30rpx;
+		display: flex;
+		flex-direction: column;
+		position: relative;
+	}
+	
+	.wyb-drop-down-content-item-label {
+		width: 90%;
+		height: 100%;
+		display: flex;
+		flex-direction: row;
+		align-items: center;
+		justify-content: flex-start;
+		padding-left: 50rpx;
+	}
+	
+	.wyb-drop-down-content-item-icon {
+		position: absolute;
+		top: 50%;
+		right: 40rpx;
+		font-size: 40rpx;
+		transform: translateY(-50%);
+	}
+	
+	.wyb-drop-down-content-box {
+		width: 100%;
+	}
+	
+	.wyb-drop-down-content-slot {
+		width: 100%;
+		height: 100%;
+	}
+	
+	.wyb-drop-down-vline {
+		width: 1px;
+		height: 40rpx;
+		background-color: #eee;
+		position: absolute;
+		right: 0;
+	}
+
+	.wyb-drop-down-line {
+		width: 100%;
+		height: 1px;
+		background-color: #eee;
+		margin-left: 50rpx;
+	}
+</style>

+ 48 - 0
lang/en.js

@@ -0,0 +1,48 @@
+module.exports = {
+	hea: {
+		cjsy: 'Primary income',
+		vipzs: 'VIP exclusive',
+		dsy: 'degree profit',
+		wyyz: 'I want help',
+		yz: 'assistance',
+		ywc: 'Completed',
+		lksj: 'upgrade now',
+		ytg: 'Passed',
+		wtg: 'Fail',
+		ren: 'Man',
+		ckxq:'View details',
+		jj: 'No',
+		ty: 'Ok',
+		ysh: 'Reviewed',
+		wsh: 'Not approved',
+		wjmm: 'Forget password',
+		logininfo:'You are not logged in. Do you want to log in now?',
+		yk: 'tourist',
+		lxkf: 'customer service',
+		fxhy: 'Share friends',
+		wdtd: 'My team',
+		wdtg: 'My promotion',
+		wdtgrs: 'My promotion number',
+		login: 'Login',
+		gwsy: 'Home page',
+		gscp: 'Company products',
+		faal: 'Project examples',
+		gywm: 'About us',
+		yyxz: 'Language',
+		ljgd: "More"
+	},
+	foo: {
+		hwsc: 'Oversea markets',
+		cplb: 'Product list',
+		faal: 'Project examples',
+		zyj: 'Aerator series',
+		gzwm: 'Follow us',
+		fdgzh: 'Futi WeChat official account',
+		fddy:'Futi Tick Tok official account',
+		zz: 'Manufacture',
+		jz: 'Value',
+		wh: 'Culture',
+		zzkhty: "Focus on customers'experience, innovation advancing technology development",
+		qywh: 'The company has a happy, dedicated and professional staff team, who inherit "perfect oneself to be excellent " team cooperation spirit, adhere to the " strict management,innovation, high quality,  market extension"operation policy, adhere to the" do exactly what customer may consider "business philosophy.We always provide high quality products, with excellent service,reasonable price and fast delivery,abide by customers\'commitment as our enterprise purpose.',
+	}
+}

+ 24 - 0
lang/es.js

@@ -0,0 +1,24 @@
+module.exports = {
+	hea: {
+		gwsy: 'Página de inicio',
+		gscp: 'Productos',
+		faal: 'Caso de solución',
+		gywm: 'Sobre nosotros',
+		yyxz: 'Language',
+		ljgd: "Aprender más"
+	},
+	foo: {
+		hwsc: 'Mercado exterior',
+		cplb: 'Lista de productos',
+		faal: 'Caso de solución',
+		zyj: 'Serie de aireadores',
+		gzwm: 'Síguenos',
+		fdgzh: 'Cuenta oficial de Fordy',
+		fddy:'Futi Tik Tok',
+		zz: 'Fabricación',
+		jz: 'Valor',
+		wh: 'Cultura',
+		zzkhty: "Centrarse en la experiencia del cliente e innovar la tecnología de guía",
+		qywh: 'La empresa cuenta con un equipo de personal contento, dedicado y profesional, y hereda el espíritu de equipo de "perfeccionar al individuo y lograr la mejor empresa". Se adhiere a la política comercial de "gestión estricta, innovación, alta calidad y expansión del mercado", con la filosofía empresarial de "lo que usted piensa es lo que hacemos". Siempre nos hemos adherido al principio corporativo de "alta calidad, excelente servicio, precio razonable, entrega rápida y cumplimiento de las promesas del cliente".',
+	}
+}

+ 21 - 0
lang/i18n.js

@@ -0,0 +1,21 @@
+import Vue from "vue";
+import VueI18n from "./i18nJs.js";
+import en from "./en";
+import es from "./es";
+import zh_cn from './zh_cn'
+
+Vue.use(VueI18n);
+
+const messages = {
+  en: en,
+  es: es,
+  zh_cn:zh_cn
+};
+
+const i18n = new VueI18n({
+  locale: "zh_cn",
+  messages
+});
+
+export default i18n;
+

+ 2210 - 0
lang/i18nJs.js

@@ -0,0 +1,2210 @@
+/*!
+ * vue-i18n v8.24.1 
+ * (c) 2021 kazuya kawaguchi
+ * Released under the MIT License.
+ */
+(function (global, factory) {
+  typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
+  typeof define === 'function' && define.amd ? define(factory) :
+  (global.VueI18n = factory());
+}(this, (function () { 'use strict';
+
+  /*  */
+
+  /**
+   * constants
+   */
+
+  var numberFormatKeys = [
+    'compactDisplay',
+    'currency',
+    'currencyDisplay',
+    'currencySign',
+    'localeMatcher',
+    'notation',
+    'numberingSystem',
+    'signDisplay',
+    'style',
+    'unit',
+    'unitDisplay',
+    'useGrouping',
+    'minimumIntegerDigits',
+    'minimumFractionDigits',
+    'maximumFractionDigits',
+    'minimumSignificantDigits',
+    'maximumSignificantDigits'
+  ];
+
+  /**
+   * utilities
+   */
+
+  function warn (msg, err) {
+    if (typeof console !== 'undefined') {
+      console.warn('[vue-i18n] ' + msg);
+      /* istanbul ignore if */
+      if (err) {
+        console.warn(err.stack);
+      }
+    }
+  }
+
+  function error (msg, err) {
+    if (typeof console !== 'undefined') {
+      console.error('[vue-i18n] ' + msg);
+      /* istanbul ignore if */
+      if (err) {
+        console.error(err.stack);
+      }
+    }
+  }
+
+  var isArray = Array.isArray;
+
+  function isObject (obj) {
+    return obj !== null && typeof obj === 'object'
+  }
+
+  function isBoolean (val) {
+    return typeof val === 'boolean'
+  }
+
+  function isString (val) {
+    return typeof val === 'string'
+  }
+
+  var toString = Object.prototype.toString;
+  var OBJECT_STRING = '[object Object]';
+  function isPlainObject (obj) {
+    return toString.call(obj) === OBJECT_STRING
+  }
+
+  function isNull (val) {
+    return val === null || val === undefined
+  }
+
+  function isFunction (val) {
+    return typeof val === 'function'
+  }
+
+  function parseArgs () {
+    var args = [], len = arguments.length;
+    while ( len-- ) args[ len ] = arguments[ len ];
+
+    var locale = null;
+    var params = null;
+    if (args.length === 1) {
+      if (isObject(args[0]) || isArray(args[0])) {
+        params = args[0];
+      } else if (typeof args[0] === 'string') {
+        locale = args[0];
+      }
+    } else if (args.length === 2) {
+      if (typeof args[0] === 'string') {
+        locale = args[0];
+      }
+      /* istanbul ignore if */
+      if (isObject(args[1]) || isArray(args[1])) {
+        params = args[1];
+      }
+    }
+
+    return { locale: locale, params: params }
+  }
+
+  function looseClone (obj) {
+    return JSON.parse(JSON.stringify(obj))
+  }
+
+  function remove (arr, item) {
+    if (arr.length) {
+      var index = arr.indexOf(item);
+      if (index > -1) {
+        return arr.splice(index, 1)
+      }
+    }
+  }
+
+  function includes (arr, item) {
+    return !!~arr.indexOf(item)
+  }
+
+  var hasOwnProperty = Object.prototype.hasOwnProperty;
+  function hasOwn (obj, key) {
+    return hasOwnProperty.call(obj, key)
+  }
+
+  function merge (target) {
+    var arguments$1 = arguments;
+
+    var output = Object(target);
+    for (var i = 1; i < arguments.length; i++) {
+      var source = arguments$1[i];
+      if (source !== undefined && source !== null) {
+        var key = (void 0);
+        for (key in source) {
+          if (hasOwn(source, key)) {
+            if (isObject(source[key])) {
+              output[key] = merge(output[key], source[key]);
+            } else {
+              output[key] = source[key];
+            }
+          }
+        }
+      }
+    }
+    return output
+  }
+
+  function looseEqual (a, b) {
+    if (a === b) { return true }
+    var isObjectA = isObject(a);
+    var isObjectB = isObject(b);
+    if (isObjectA && isObjectB) {
+      try {
+        var isArrayA = isArray(a);
+        var isArrayB = isArray(b);
+        if (isArrayA && isArrayB) {
+          return a.length === b.length && a.every(function (e, i) {
+            return looseEqual(e, b[i])
+          })
+        } else if (!isArrayA && !isArrayB) {
+          var keysA = Object.keys(a);
+          var keysB = Object.keys(b);
+          return keysA.length === keysB.length && keysA.every(function (key) {
+            return looseEqual(a[key], b[key])
+          })
+        } else {
+          /* istanbul ignore next */
+          return false
+        }
+      } catch (e) {
+        /* istanbul ignore next */
+        return false
+      }
+    } else if (!isObjectA && !isObjectB) {
+      return String(a) === String(b)
+    } else {
+      return false
+    }
+  }
+
+  /**
+   * Sanitizes html special characters from input strings. For mitigating risk of XSS attacks.
+   * @param rawText The raw input from the user that should be escaped.
+   */
+  function escapeHtml(rawText) {
+    return rawText
+      .replace(/</g, '&lt;')
+      .replace(/>/g, '&gt;')
+      .replace(/"/g, '&quot;')
+      .replace(/'/g, '&apos;')
+  }
+
+  /**
+   * Escapes html tags and special symbols from all provided params which were returned from parseArgs().params.
+   * This method performs an in-place operation on the params object.
+   *
+   * @param {any} params Parameters as provided from `parseArgs().params`.
+   *                     May be either an array of strings or a string->any map.
+   *
+   * @returns The manipulated `params` object.
+   */
+  function escapeParams(params) {
+    if(params != null) {
+      Object.keys(params).forEach(function (key) {
+        if(typeof(params[key]) == 'string') {
+          params[key] = escapeHtml(params[key]);
+        }
+      });
+    }
+    return params
+  }
+
+  /*  */
+
+  function extend (Vue) {
+    if (!Vue.prototype.hasOwnProperty('$i18n')) {
+      // $FlowFixMe
+      Object.defineProperty(Vue.prototype, '$i18n', {
+        get: function get () { return this._i18n }
+      });
+    }
+
+    Vue.prototype.$t = function (key) {
+      var values = [], len = arguments.length - 1;
+      while ( len-- > 0 ) values[ len ] = arguments[ len + 1 ];
+
+      var i18n = this.$i18n;
+      return i18n._t.apply(i18n, [ key, i18n.locale, i18n._getMessages(), this ].concat( values ))
+    };
+
+    Vue.prototype.$tc = function (key, choice) {
+      var values = [], len = arguments.length - 2;
+      while ( len-- > 0 ) values[ len ] = arguments[ len + 2 ];
+
+      var i18n = this.$i18n;
+      return i18n._tc.apply(i18n, [ key, i18n.locale, i18n._getMessages(), this, choice ].concat( values ))
+    };
+
+    Vue.prototype.$te = function (key, locale) {
+      var i18n = this.$i18n;
+      return i18n._te(key, i18n.locale, i18n._getMessages(), locale)
+    };
+
+    Vue.prototype.$d = function (value) {
+      var ref;
+
+      var args = [], len = arguments.length - 1;
+      while ( len-- > 0 ) args[ len ] = arguments[ len + 1 ];
+      return (ref = this.$i18n).d.apply(ref, [ value ].concat( args ))
+    };
+
+    Vue.prototype.$n = function (value) {
+      var ref;
+
+      var args = [], len = arguments.length - 1;
+      while ( len-- > 0 ) args[ len ] = arguments[ len + 1 ];
+      return (ref = this.$i18n).n.apply(ref, [ value ].concat( args ))
+    };
+  }
+
+  /*  */
+
+  var mixin = {
+    beforeCreate: function beforeCreate () {
+      var options = this.$options;
+      options.i18n = options.i18n || (options.__i18n ? {} : null);
+
+      if (options.i18n) {
+        if (options.i18n instanceof VueI18n) {
+          // init locale messages via custom blocks
+          if (options.__i18n) {
+            try {
+              var localeMessages = options.i18n && options.i18n.messages ? options.i18n.messages : {};
+              options.__i18n.forEach(function (resource) {
+                localeMessages = merge(localeMessages, JSON.parse(resource));
+              });
+              Object.keys(localeMessages).forEach(function (locale) {
+                options.i18n.mergeLocaleMessage(locale, localeMessages[locale]);
+              });
+            } catch (e) {
+              {
+                error("Cannot parse locale messages via custom blocks.", e);
+              }
+            }
+          }
+          this._i18n = options.i18n;
+          this._i18nWatcher = this._i18n.watchI18nData();
+        } else if (isPlainObject(options.i18n)) {
+          var rootI18n = this.$root && this.$root.$i18n && this.$root.$i18n instanceof VueI18n
+            ? this.$root.$i18n
+            : null;
+          // component local i18n
+          if (rootI18n) {
+            options.i18n.root = this.$root;
+            options.i18n.formatter = rootI18n.formatter;
+            options.i18n.fallbackLocale = rootI18n.fallbackLocale;
+            options.i18n.formatFallbackMessages = rootI18n.formatFallbackMessages;
+            options.i18n.silentTranslationWarn = rootI18n.silentTranslationWarn;
+            options.i18n.silentFallbackWarn = rootI18n.silentFallbackWarn;
+            options.i18n.pluralizationRules = rootI18n.pluralizationRules;
+            options.i18n.preserveDirectiveContent = rootI18n.preserveDirectiveContent;
+          }
+
+          // init locale messages via custom blocks
+          if (options.__i18n) {
+            try {
+              var localeMessages$1 = options.i18n && options.i18n.messages ? options.i18n.messages : {};
+              options.__i18n.forEach(function (resource) {
+                localeMessages$1 = merge(localeMessages$1, JSON.parse(resource));
+              });
+              options.i18n.messages = localeMessages$1;
+            } catch (e) {
+              {
+                warn("Cannot parse locale messages via custom blocks.", e);
+              }
+            }
+          }
+
+          var ref = options.i18n;
+          var sharedMessages = ref.sharedMessages;
+          if (sharedMessages && isPlainObject(sharedMessages)) {
+            options.i18n.messages = merge(options.i18n.messages, sharedMessages);
+          }
+
+          this._i18n = new VueI18n(options.i18n);
+          this._i18nWatcher = this._i18n.watchI18nData();
+
+          if (options.i18n.sync === undefined || !!options.i18n.sync) {
+            this._localeWatcher = this.$i18n.watchLocale();
+          }
+
+          if (rootI18n) {
+            rootI18n.onComponentInstanceCreated(this._i18n);
+          }
+        } else {
+          {
+            warn("Cannot be interpreted 'i18n' option.");
+          }
+        }
+      } else if (this.$root && this.$root.$i18n && this.$root.$i18n instanceof VueI18n) {
+        // root i18n
+        this._i18n = this.$root.$i18n;
+      } else if (options.parent && options.parent.$i18n && options.parent.$i18n instanceof VueI18n) {
+        // parent i18n
+        this._i18n = options.parent.$i18n;
+      }
+    },
+
+    beforeMount: function beforeMount () {
+      var options = this.$options;
+      options.i18n = options.i18n || (options.__i18n ? {} : null);
+
+      if (options.i18n) {
+        if (options.i18n instanceof VueI18n) {
+          // init locale messages via custom blocks
+          this._i18n.subscribeDataChanging(this);
+          this._subscribing = true;
+        } else if (isPlainObject(options.i18n)) {
+          this._i18n.subscribeDataChanging(this);
+          this._subscribing = true;
+        } else {
+          {
+            warn("Cannot be interpreted 'i18n' option.");
+          }
+        }
+      } else if (this.$root && this.$root.$i18n && this.$root.$i18n instanceof VueI18n) {
+        this._i18n.subscribeDataChanging(this);
+        this._subscribing = true;
+      } else if (options.parent && options.parent.$i18n && options.parent.$i18n instanceof VueI18n) {
+        this._i18n.subscribeDataChanging(this);
+        this._subscribing = true;
+      }
+    },
+
+    mounted: function mounted () {
+      if (this !== this.$root && this.$options.__INTLIFY_META__ && this.$el) {
+        this.$el.setAttribute('data-intlify', this.$options.__INTLIFY_META__);
+      }
+    },
+
+    beforeDestroy: function beforeDestroy () {
+      if (!this._i18n) { return }
+
+      var self = this;
+      this.$nextTick(function () {
+        if (self._subscribing) {
+          self._i18n.unsubscribeDataChanging(self);
+          delete self._subscribing;
+        }
+
+        if (self._i18nWatcher) {
+          self._i18nWatcher();
+          self._i18n.destroyVM();
+          delete self._i18nWatcher;
+        }
+
+        if (self._localeWatcher) {
+          self._localeWatcher();
+          delete self._localeWatcher;
+        }
+      });
+    }
+  };
+
+  /*  */
+
+  var interpolationComponent = {
+    name: 'i18n',
+    functional: true,
+    props: {
+      tag: {
+        type: [String, Boolean, Object],
+        default: 'span'
+      },
+      path: {
+        type: String,
+        required: true
+      },
+      locale: {
+        type: String
+      },
+      places: {
+        type: [Array, Object]
+      }
+    },
+    render: function render (h, ref) {
+      var data = ref.data;
+      var parent = ref.parent;
+      var props = ref.props;
+      var slots = ref.slots;
+
+      var $i18n = parent.$i18n;
+      if (!$i18n) {
+        {
+          warn('Cannot find VueI18n instance!');
+        }
+        return
+      }
+
+      var path = props.path;
+      var locale = props.locale;
+      var places = props.places;
+      var params = slots();
+      var children = $i18n.i(
+        path,
+        locale,
+        onlyHasDefaultPlace(params) || places
+          ? useLegacyPlaces(params.default, places)
+          : params
+      );
+
+      var tag = (!!props.tag && props.tag !== true) || props.tag === false ? props.tag : 'span';
+      return tag ? h(tag, data, children) : children
+    }
+  };
+
+  function onlyHasDefaultPlace (params) {
+    var prop;
+    for (prop in params) {
+      if (prop !== 'default') { return false }
+    }
+    return Boolean(prop)
+  }
+
+  function useLegacyPlaces (children, places) {
+    var params = places ? createParamsFromPlaces(places) : {};
+
+    if (!children) { return params }
+
+    // Filter empty text nodes
+    children = children.filter(function (child) {
+      return child.tag || child.text.trim() !== ''
+    });
+
+    var everyPlace = children.every(vnodeHasPlaceAttribute);
+    if (everyPlace) {
+      warn('`place` attribute is deprecated in next major version. Please switch to Vue slots.');
+    }
+
+    return children.reduce(
+      everyPlace ? assignChildPlace : assignChildIndex,
+      params
+    )
+  }
+
+  function createParamsFromPlaces (places) {
+    {
+      warn('`places` prop is deprecated in next major version. Please switch to Vue slots.');
+    }
+
+    return Array.isArray(places)
+      ? places.reduce(assignChildIndex, {})
+      : Object.assign({}, places)
+  }
+
+  function assignChildPlace (params, child) {
+    if (child.data && child.data.attrs && child.data.attrs.place) {
+      params[child.data.attrs.place] = child;
+    }
+    return params
+  }
+
+  function assignChildIndex (params, child, index) {
+    params[index] = child;
+    return params
+  }
+
+  function vnodeHasPlaceAttribute (vnode) {
+    return Boolean(vnode.data && vnode.data.attrs && vnode.data.attrs.place)
+  }
+
+  /*  */
+
+  var numberComponent = {
+    name: 'i18n-n',
+    functional: true,
+    props: {
+      tag: {
+        type: [String, Boolean, Object],
+        default: 'span'
+      },
+      value: {
+        type: Number,
+        required: true
+      },
+      format: {
+        type: [String, Object]
+      },
+      locale: {
+        type: String
+      }
+    },
+    render: function render (h, ref) {
+      var props = ref.props;
+      var parent = ref.parent;
+      var data = ref.data;
+
+      var i18n = parent.$i18n;
+
+      if (!i18n) {
+        {
+          warn('Cannot find VueI18n instance!');
+        }
+        return null
+      }
+
+      var key = null;
+      var options = null;
+
+      if (isString(props.format)) {
+        key = props.format;
+      } else if (isObject(props.format)) {
+        if (props.format.key) {
+          key = props.format.key;
+        }
+
+        // Filter out number format options only
+        options = Object.keys(props.format).reduce(function (acc, prop) {
+          var obj;
+
+          if (includes(numberFormatKeys, prop)) {
+            return Object.assign({}, acc, ( obj = {}, obj[prop] = props.format[prop], obj ))
+          }
+          return acc
+        }, null);
+      }
+
+      var locale = props.locale || i18n.locale;
+      var parts = i18n._ntp(props.value, locale, key, options);
+
+      var values = parts.map(function (part, index) {
+        var obj;
+
+        var slot = data.scopedSlots && data.scopedSlots[part.type];
+        return slot ? slot(( obj = {}, obj[part.type] = part.value, obj.index = index, obj.parts = parts, obj )) : part.value
+      });
+
+      var tag = (!!props.tag && props.tag !== true) || props.tag === false ? props.tag : 'span';
+      return tag
+        ? h(tag, {
+          attrs: data.attrs,
+          'class': data['class'],
+          staticClass: data.staticClass
+        }, values)
+        : values
+    }
+  };
+
+  /*  */
+
+  function bind (el, binding, vnode) {
+    if (!assert(el, vnode)) { return }
+
+    t(el, binding, vnode);
+  }
+
+  function update (el, binding, vnode, oldVNode) {
+    if (!assert(el, vnode)) { return }
+
+    var i18n = vnode.context.$i18n;
+    if (localeEqual(el, vnode) &&
+      (looseEqual(binding.value, binding.oldValue) &&
+       looseEqual(el._localeMessage, i18n.getLocaleMessage(i18n.locale)))) { return }
+
+    t(el, binding, vnode);
+  }
+
+  function unbind (el, binding, vnode, oldVNode) {
+    var vm = vnode.context;
+    if (!vm) {
+      warn('Vue instance does not exists in VNode context');
+      return
+    }
+
+    var i18n = vnode.context.$i18n || {};
+    if (!binding.modifiers.preserve && !i18n.preserveDirectiveContent) {
+      el.textContent = '';
+    }
+    el._vt = undefined;
+    delete el['_vt'];
+    el._locale = undefined;
+    delete el['_locale'];
+    el._localeMessage = undefined;
+    delete el['_localeMessage'];
+  }
+
+  function assert (el, vnode) {
+    var vm = vnode.context;
+    if (!vm) {
+      warn('Vue instance does not exists in VNode context');
+      return false
+    }
+
+    if (!vm.$i18n) {
+      warn('VueI18n instance does not exists in Vue instance');
+      return false
+    }
+
+    return true
+  }
+
+  function localeEqual (el, vnode) {
+    var vm = vnode.context;
+    return el._locale === vm.$i18n.locale
+  }
+
+  function t (el, binding, vnode) {
+    var ref$1, ref$2;
+
+    var value = binding.value;
+
+    var ref = parseValue(value);
+    var path = ref.path;
+    var locale = ref.locale;
+    var args = ref.args;
+    var choice = ref.choice;
+    if (!path && !locale && !args) {
+      warn('value type not supported');
+      return
+    }
+
+    if (!path) {
+      warn('`path` is required in v-t directive');
+      return
+    }
+
+    var vm = vnode.context;
+    if (choice != null) {
+      el._vt = el.textContent = (ref$1 = vm.$i18n).tc.apply(ref$1, [ path, choice ].concat( makeParams(locale, args) ));
+    } else {
+      el._vt = el.textContent = (ref$2 = vm.$i18n).t.apply(ref$2, [ path ].concat( makeParams(locale, args) ));
+    }
+    el._locale = vm.$i18n.locale;
+    el._localeMessage = vm.$i18n.getLocaleMessage(vm.$i18n.locale);
+  }
+
+  function parseValue (value) {
+    var path;
+    var locale;
+    var args;
+    var choice;
+
+    if (isString(value)) {
+      path = value;
+    } else if (isPlainObject(value)) {
+      path = value.path;
+      locale = value.locale;
+      args = value.args;
+      choice = value.choice;
+    }
+
+    return { path: path, locale: locale, args: args, choice: choice }
+  }
+
+  function makeParams (locale, args) {
+    var params = [];
+
+    locale && params.push(locale);
+    if (args && (Array.isArray(args) || isPlainObject(args))) {
+      params.push(args);
+    }
+
+    return params
+  }
+
+  var Vue;
+
+  function install (_Vue) {
+    /* istanbul ignore if */
+    if (install.installed && _Vue === Vue) {
+      warn('already installed.');
+      return
+    }
+    install.installed = true;
+
+    Vue = _Vue;
+
+    var version = (Vue.version && Number(Vue.version.split('.')[0])) || -1;
+    /* istanbul ignore if */
+    if (version < 2) {
+      warn(("vue-i18n (" + (install.version) + ") need to use Vue 2.0 or later (Vue: " + (Vue.version) + ")."));
+      return
+    }
+
+    extend(Vue);
+    Vue.mixin(mixin);
+    Vue.directive('t', { bind: bind, update: update, unbind: unbind });
+    Vue.component(interpolationComponent.name, interpolationComponent);
+    Vue.component(numberComponent.name, numberComponent);
+
+    // use simple mergeStrategies to prevent i18n instance lose '__proto__'
+    var strats = Vue.config.optionMergeStrategies;
+    strats.i18n = function (parentVal, childVal) {
+      return childVal === undefined
+        ? parentVal
+        : childVal
+    };
+  }
+
+  /*  */
+
+  var BaseFormatter = function BaseFormatter () {
+    this._caches = Object.create(null);
+  };
+
+  BaseFormatter.prototype.interpolate = function interpolate (message, values) {
+    if (!values) {
+      return [message]
+    }
+    var tokens = this._caches[message];
+    if (!tokens) {
+      tokens = parse(message);
+      this._caches[message] = tokens;
+    }
+    return compile(tokens, values)
+  };
+
+
+
+  var RE_TOKEN_LIST_VALUE = /^(?:\d)+/;
+  var RE_TOKEN_NAMED_VALUE = /^(?:\w)+/;
+
+  function parse (format) {
+    var tokens = [];
+    var position = 0;
+
+    var text = '';
+    while (position < format.length) {
+      var char = format[position++];
+      if (char === '{') {
+        if (text) {
+          tokens.push({ type: 'text', value: text });
+        }
+
+        text = '';
+        var sub = '';
+        char = format[position++];
+        while (char !== undefined && char !== '}') {
+          sub += char;
+          char = format[position++];
+        }
+        var isClosed = char === '}';
+
+        var type = RE_TOKEN_LIST_VALUE.test(sub)
+          ? 'list'
+          : isClosed && RE_TOKEN_NAMED_VALUE.test(sub)
+            ? 'named'
+            : 'unknown';
+        tokens.push({ value: sub, type: type });
+      } else if (char === '%') {
+        // when found rails i18n syntax, skip text capture
+        if (format[(position)] !== '{') {
+          text += char;
+        }
+      } else {
+        text += char;
+      }
+    }
+
+    text && tokens.push({ type: 'text', value: text });
+
+    return tokens
+  }
+
+  function compile (tokens, values) {
+    var compiled = [];
+    var index = 0;
+
+    var mode = Array.isArray(values)
+      ? 'list'
+      : isObject(values)
+        ? 'named'
+        : 'unknown';
+    if (mode === 'unknown') { return compiled }
+
+    while (index < tokens.length) {
+      var token = tokens[index];
+      switch (token.type) {
+        case 'text':
+          compiled.push(token.value);
+          break
+        case 'list':
+          compiled.push(values[parseInt(token.value, 10)]);
+          break
+        case 'named':
+          if (mode === 'named') {
+            compiled.push((values)[token.value]);
+          } else {
+            {
+              warn(("Type of token '" + (token.type) + "' and format of value '" + mode + "' don't match!"));
+            }
+          }
+          break
+        case 'unknown':
+          {
+            warn("Detect 'unknown' type of token!");
+          }
+          break
+      }
+      index++;
+    }
+
+    return compiled
+  }
+
+  /*  */
+
+  /**
+   *  Path parser
+   *  - Inspired:
+   *    Vue.js Path parser
+   */
+
+  // actions
+  var APPEND = 0;
+  var PUSH = 1;
+  var INC_SUB_PATH_DEPTH = 2;
+  var PUSH_SUB_PATH = 3;
+
+  // states
+  var BEFORE_PATH = 0;
+  var IN_PATH = 1;
+  var BEFORE_IDENT = 2;
+  var IN_IDENT = 3;
+  var IN_SUB_PATH = 4;
+  var IN_SINGLE_QUOTE = 5;
+  var IN_DOUBLE_QUOTE = 6;
+  var AFTER_PATH = 7;
+  var ERROR = 8;
+
+  var pathStateMachine = [];
+
+  pathStateMachine[BEFORE_PATH] = {
+    'ws': [BEFORE_PATH],
+    'ident': [IN_IDENT, APPEND],
+    '[': [IN_SUB_PATH],
+    'eof': [AFTER_PATH]
+  };
+
+  pathStateMachine[IN_PATH] = {
+    'ws': [IN_PATH],
+    '.': [BEFORE_IDENT],
+    '[': [IN_SUB_PATH],
+    'eof': [AFTER_PATH]
+  };
+
+  pathStateMachine[BEFORE_IDENT] = {
+    'ws': [BEFORE_IDENT],
+    'ident': [IN_IDENT, APPEND],
+    '0': [IN_IDENT, APPEND],
+    'number': [IN_IDENT, APPEND]
+  };
+
+  pathStateMachine[IN_IDENT] = {
+    'ident': [IN_IDENT, APPEND],
+    '0': [IN_IDENT, APPEND],
+    'number': [IN_IDENT, APPEND],
+    'ws': [IN_PATH, PUSH],
+    '.': [BEFORE_IDENT, PUSH],
+    '[': [IN_SUB_PATH, PUSH],
+    'eof': [AFTER_PATH, PUSH]
+  };
+
+  pathStateMachine[IN_SUB_PATH] = {
+    "'": [IN_SINGLE_QUOTE, APPEND],
+    '"': [IN_DOUBLE_QUOTE, APPEND],
+    '[': [IN_SUB_PATH, INC_SUB_PATH_DEPTH],
+    ']': [IN_PATH, PUSH_SUB_PATH],
+    'eof': ERROR,
+    'else': [IN_SUB_PATH, APPEND]
+  };
+
+  pathStateMachine[IN_SINGLE_QUOTE] = {
+    "'": [IN_SUB_PATH, APPEND],
+    'eof': ERROR,
+    'else': [IN_SINGLE_QUOTE, APPEND]
+  };
+
+  pathStateMachine[IN_DOUBLE_QUOTE] = {
+    '"': [IN_SUB_PATH, APPEND],
+    'eof': ERROR,
+    'else': [IN_DOUBLE_QUOTE, APPEND]
+  };
+
+  /**
+   * Check if an expression is a literal value.
+   */
+
+  var literalValueRE = /^\s?(?:true|false|-?[\d.]+|'[^']*'|"[^"]*")\s?$/;
+  function isLiteral (exp) {
+    return literalValueRE.test(exp)
+  }
+
+  /**
+   * Strip quotes from a string
+   */
+
+  function stripQuotes (str) {
+    var a = str.charCodeAt(0);
+    var b = str.charCodeAt(str.length - 1);
+    return a === b && (a === 0x22 || a === 0x27)
+      ? str.slice(1, -1)
+      : str
+  }
+
+  /**
+   * Determine the type of a character in a keypath.
+   */
+
+  function getPathCharType (ch) {
+    if (ch === undefined || ch === null) { return 'eof' }
+
+    var code = ch.charCodeAt(0);
+
+    switch (code) {
+      case 0x5B: // [
+      case 0x5D: // ]
+      case 0x2E: // .
+      case 0x22: // "
+      case 0x27: // '
+        return ch
+
+      case 0x5F: // _
+      case 0x24: // $
+      case 0x2D: // -
+        return 'ident'
+
+      case 0x09: // Tab
+      case 0x0A: // Newline
+      case 0x0D: // Return
+      case 0xA0:  // No-break space
+      case 0xFEFF:  // Byte Order Mark
+      case 0x2028:  // Line Separator
+      case 0x2029:  // Paragraph Separator
+        return 'ws'
+    }
+
+    return 'ident'
+  }
+
+  /**
+   * Format a subPath, return its plain form if it is
+   * a literal string or number. Otherwise prepend the
+   * dynamic indicator (*).
+   */
+
+  function formatSubPath (path) {
+    var trimmed = path.trim();
+    // invalid leading 0
+    if (path.charAt(0) === '0' && isNaN(path)) { return false }
+
+    return isLiteral(trimmed) ? stripQuotes(trimmed) : '*' + trimmed
+  }
+
+  /**
+   * Parse a string path into an array of segments
+   */
+
+  function parse$1 (path) {
+    var keys = [];
+    var index = -1;
+    var mode = BEFORE_PATH;
+    var subPathDepth = 0;
+    var c;
+    var key;
+    var newChar;
+    var type;
+    var transition;
+    var action;
+    var typeMap;
+    var actions = [];
+
+    actions[PUSH] = function () {
+      if (key !== undefined) {
+        keys.push(key);
+        key = undefined;
+      }
+    };
+
+    actions[APPEND] = function () {
+      if (key === undefined) {
+        key = newChar;
+      } else {
+        key += newChar;
+      }
+    };
+
+    actions[INC_SUB_PATH_DEPTH] = function () {
+      actions[APPEND]();
+      subPathDepth++;
+    };
+
+    actions[PUSH_SUB_PATH] = function () {
+      if (subPathDepth > 0) {
+        subPathDepth--;
+        mode = IN_SUB_PATH;
+        actions[APPEND]();
+      } else {
+        subPathDepth = 0;
+        if (key === undefined) { return false }
+        key = formatSubPath(key);
+        if (key === false) {
+          return false
+        } else {
+          actions[PUSH]();
+        }
+      }
+    };
+
+    function maybeUnescapeQuote () {
+      var nextChar = path[index + 1];
+      if ((mode === IN_SINGLE_QUOTE && nextChar === "'") ||
+        (mode === IN_DOUBLE_QUOTE && nextChar === '"')) {
+        index++;
+        newChar = '\\' + nextChar;
+        actions[APPEND]();
+        return true
+      }
+    }
+
+    while (mode !== null) {
+      index++;
+      c = path[index];
+
+      if (c === '\\' && maybeUnescapeQuote()) {
+        continue
+      }
+
+      type = getPathCharType(c);
+      typeMap = pathStateMachine[mode];
+      transition = typeMap[type] || typeMap['else'] || ERROR;
+
+      if (transition === ERROR) {
+        return // parse error
+      }
+
+      mode = transition[0];
+      action = actions[transition[1]];
+      if (action) {
+        newChar = transition[2];
+        newChar = newChar === undefined
+          ? c
+          : newChar;
+        if (action() === false) {
+          return
+        }
+      }
+
+      if (mode === AFTER_PATH) {
+        return keys
+      }
+    }
+  }
+
+
+
+
+
+  var I18nPath = function I18nPath () {
+    this._cache = Object.create(null);
+  };
+
+  /**
+   * External parse that check for a cache hit first
+   */
+  I18nPath.prototype.parsePath = function parsePath (path) {
+    var hit = this._cache[path];
+    if (!hit) {
+      hit = parse$1(path);
+      if (hit) {
+        this._cache[path] = hit;
+      }
+    }
+    return hit || []
+  };
+
+  /**
+   * Get path value from path string
+   */
+  I18nPath.prototype.getPathValue = function getPathValue (obj, path) {
+    if (!isObject(obj)) { return null }
+
+    var paths = this.parsePath(path);
+    if (paths.length === 0) {
+      return null
+    } else {
+      var length = paths.length;
+      var last = obj;
+      var i = 0;
+      while (i < length) {
+        var value = last[paths[i]];
+        if (value === undefined || value === null) {
+          return null
+        }
+        last = value;
+        i++;
+      }
+
+      return last
+    }
+  };
+
+  /*  */
+
+
+
+  var htmlTagMatcher = /<\/?[\w\s="/.':;#-\/]+>/;
+  var linkKeyMatcher = /(?:@(?:\.[a-z]+)?:(?:[\w\-_|.]+|\([\w\-_|.]+\)))/g;
+  var linkKeyPrefixMatcher = /^@(?:\.([a-z]+))?:/;
+  var bracketsMatcher = /[()]/g;
+  var defaultModifiers = {
+    'upper': function (str) { return str.toLocaleUpperCase(); },
+    'lower': function (str) { return str.toLocaleLowerCase(); },
+    'capitalize': function (str) { return ("" + (str.charAt(0).toLocaleUpperCase()) + (str.substr(1))); }
+  };
+
+  var defaultFormatter = new BaseFormatter();
+
+  var VueI18n = function VueI18n (options) {
+    var this$1 = this;
+    if ( options === void 0 ) options = {};
+
+    // Auto install if it is not done yet and `window` has `Vue`.
+    // To allow users to avoid auto-installation in some cases,
+    // this code should be placed here. See #290
+    /* istanbul ignore if */
+    if (!Vue && typeof window !== 'undefined' && window.Vue) {
+      install(window.Vue);
+    }
+
+    var locale = options.locale || 'en-US';
+    var fallbackLocale = options.fallbackLocale === false
+      ? false
+      : options.fallbackLocale || 'en-US';
+    var messages = options.messages || {};
+    var dateTimeFormats = options.dateTimeFormats || {};
+    var numberFormats = options.numberFormats || {};
+
+    this._vm = null;
+    this._formatter = options.formatter || defaultFormatter;
+    this._modifiers = options.modifiers || {};
+    this._missing = options.missing || null;
+    this._root = options.root || null;
+    this._sync = options.sync === undefined ? true : !!options.sync;
+    this._fallbackRoot = options.fallbackRoot === undefined
+      ? true
+      : !!options.fallbackRoot;
+    this._formatFallbackMessages = options.formatFallbackMessages === undefined
+      ? false
+      : !!options.formatFallbackMessages;
+    this._silentTranslationWarn = options.silentTranslationWarn === undefined
+      ? false
+      : options.silentTranslationWarn;
+    this._silentFallbackWarn = options.silentFallbackWarn === undefined
+      ? false
+      : !!options.silentFallbackWarn;
+    this._dateTimeFormatters = {};
+    this._numberFormatters = {};
+    this._path = new I18nPath();
+    this._dataListeners = [];
+    this._componentInstanceCreatedListener = options.componentInstanceCreatedListener || null;
+    this._preserveDirectiveContent = options.preserveDirectiveContent === undefined
+      ? false
+      : !!options.preserveDirectiveContent;
+    this.pluralizationRules = options.pluralizationRules || {};
+    this._warnHtmlInMessage = options.warnHtmlInMessage || 'off';
+    this._postTranslation = options.postTranslation || null;
+    this._escapeParameterHtml = options.escapeParameterHtml || false;
+
+    /**
+     * @param choice {number} a choice index given by the input to $tc: `$tc('path.to.rule', choiceIndex)`
+     * @param choicesLength {number} an overall amount of available choices
+     * @returns a final choice index
+    */
+    this.getChoiceIndex = function (choice, choicesLength) {
+      var thisPrototype = Object.getPrototypeOf(this$1);
+      if (thisPrototype && thisPrototype.getChoiceIndex) {
+        var prototypeGetChoiceIndex = (thisPrototype.getChoiceIndex);
+        return (prototypeGetChoiceIndex).call(this$1, choice, choicesLength)
+      }
+
+      // Default (old) getChoiceIndex implementation - english-compatible
+      var defaultImpl = function (_choice, _choicesLength) {
+        _choice = Math.abs(_choice);
+
+        if (_choicesLength === 2) {
+          return _choice
+            ? _choice > 1
+              ? 1
+              : 0
+            : 1
+        }
+
+        return _choice ? Math.min(_choice, 2) : 0
+      };
+
+      if (this$1.locale in this$1.pluralizationRules) {
+        return this$1.pluralizationRules[this$1.locale].apply(this$1, [choice, choicesLength])
+      } else {
+        return defaultImpl(choice, choicesLength)
+      }
+    };
+
+
+    this._exist = function (message, key) {
+      if (!message || !key) { return false }
+      if (!isNull(this$1._path.getPathValue(message, key))) { return true }
+      // fallback for flat key
+      if (message[key]) { return true }
+      return false
+    };
+
+    if (this._warnHtmlInMessage === 'warn' || this._warnHtmlInMessage === 'error') {
+      Object.keys(messages).forEach(function (locale) {
+        this$1._checkLocaleMessage(locale, this$1._warnHtmlInMessage, messages[locale]);
+      });
+    }
+
+    this._initVM({
+      locale: locale,
+      fallbackLocale: fallbackLocale,
+      messages: messages,
+      dateTimeFormats: dateTimeFormats,
+      numberFormats: numberFormats
+    });
+  };
+
+  var prototypeAccessors = { vm: { configurable: true },messages: { configurable: true },dateTimeFormats: { configurable: true },numberFormats: { configurable: true },availableLocales: { configurable: true },locale: { configurable: true },fallbackLocale: { configurable: true },formatFallbackMessages: { configurable: true },missing: { configurable: true },formatter: { configurable: true },silentTranslationWarn: { configurable: true },silentFallbackWarn: { configurable: true },preserveDirectiveContent: { configurable: true },warnHtmlInMessage: { configurable: true },postTranslation: { configurable: true } };
+
+  VueI18n.prototype._checkLocaleMessage = function _checkLocaleMessage (locale, level, message) {
+    var paths = [];
+
+    var fn = function (level, locale, message, paths) {
+      if (isPlainObject(message)) {
+        Object.keys(message).forEach(function (key) {
+          var val = message[key];
+          if (isPlainObject(val)) {
+            paths.push(key);
+            paths.push('.');
+            fn(level, locale, val, paths);
+            paths.pop();
+            paths.pop();
+          } else {
+            paths.push(key);
+            fn(level, locale, val, paths);
+            paths.pop();
+          }
+        });
+      } else if (isArray(message)) {
+        message.forEach(function (item, index) {
+          if (isPlainObject(item)) {
+            paths.push(("[" + index + "]"));
+            paths.push('.');
+            fn(level, locale, item, paths);
+            paths.pop();
+            paths.pop();
+          } else {
+            paths.push(("[" + index + "]"));
+            fn(level, locale, item, paths);
+            paths.pop();
+          }
+        });
+      } else if (isString(message)) {
+        var ret = htmlTagMatcher.test(message);
+        if (ret) {
+          var msg = "Detected HTML in message '" + message + "' of keypath '" + (paths.join('')) + "' at '" + locale + "'. Consider component interpolation with '<i18n>' to avoid XSS. See https://bit.ly/2ZqJzkp";
+          if (level === 'warn') {
+            warn(msg);
+          } else if (level === 'error') {
+            error(msg);
+          }
+        }
+      }
+    };
+
+    fn(level, locale, message, paths);
+  };
+
+  VueI18n.prototype._initVM = function _initVM (data) {
+    var silent = Vue.config.silent;
+    Vue.config.silent = true;
+    this._vm = new Vue({ data: data });
+    Vue.config.silent = silent;
+  };
+
+  VueI18n.prototype.destroyVM = function destroyVM () {
+    this._vm.$destroy();
+  };
+
+  VueI18n.prototype.subscribeDataChanging = function subscribeDataChanging (vm) {
+    this._dataListeners.push(vm);
+  };
+
+  VueI18n.prototype.unsubscribeDataChanging = function unsubscribeDataChanging (vm) {
+    remove(this._dataListeners, vm);
+  };
+
+  VueI18n.prototype.watchI18nData = function watchI18nData () {
+    var self = this;
+    return this._vm.$watch('$data', function () {
+      var i = self._dataListeners.length;
+      while (i--) {
+        Vue.nextTick(function () {
+          self._dataListeners[i] && self._dataListeners[i].$forceUpdate();
+        });
+      }
+    }, { deep: true })
+  };
+
+  VueI18n.prototype.watchLocale = function watchLocale () {
+    /* istanbul ignore if */
+    if (!this._sync || !this._root) { return null }
+    var target = this._vm;
+    return this._root.$i18n.vm.$watch('locale', function (val) {
+      target.$set(target, 'locale', val);
+      target.$forceUpdate();
+    }, { immediate: true })
+  };
+
+  VueI18n.prototype.onComponentInstanceCreated = function onComponentInstanceCreated (newI18n) {
+    if (this._componentInstanceCreatedListener) {
+      this._componentInstanceCreatedListener(newI18n, this);
+    }
+  };
+
+  prototypeAccessors.vm.get = function () { return this._vm };
+
+  prototypeAccessors.messages.get = function () { return looseClone(this._getMessages()) };
+  prototypeAccessors.dateTimeFormats.get = function () { return looseClone(this._getDateTimeFormats()) };
+  prototypeAccessors.numberFormats.get = function () { return looseClone(this._getNumberFormats()) };
+  prototypeAccessors.availableLocales.get = function () { return Object.keys(this.messages).sort() };
+
+  prototypeAccessors.locale.get = function () { return this._vm.locale };
+  prototypeAccessors.locale.set = function (locale) {
+    this._vm.$set(this._vm, 'locale', locale);
+  };
+
+  prototypeAccessors.fallbackLocale.get = function () { return this._vm.fallbackLocale };
+  prototypeAccessors.fallbackLocale.set = function (locale) {
+    this._localeChainCache = {};
+    this._vm.$set(this._vm, 'fallbackLocale', locale);
+  };
+
+  prototypeAccessors.formatFallbackMessages.get = function () { return this._formatFallbackMessages };
+  prototypeAccessors.formatFallbackMessages.set = function (fallback) { this._formatFallbackMessages = fallback; };
+
+  prototypeAccessors.missing.get = function () { return this._missing };
+  prototypeAccessors.missing.set = function (handler) { this._missing = handler; };
+
+  prototypeAccessors.formatter.get = function () { return this._formatter };
+  prototypeAccessors.formatter.set = function (formatter) { this._formatter = formatter; };
+
+  prototypeAccessors.silentTranslationWarn.get = function () { return this._silentTranslationWarn };
+  prototypeAccessors.silentTranslationWarn.set = function (silent) { this._silentTranslationWarn = silent; };
+
+  prototypeAccessors.silentFallbackWarn.get = function () { return this._silentFallbackWarn };
+  prototypeAccessors.silentFallbackWarn.set = function (silent) { this._silentFallbackWarn = silent; };
+
+  prototypeAccessors.preserveDirectiveContent.get = function () { return this._preserveDirectiveContent };
+  prototypeAccessors.preserveDirectiveContent.set = function (preserve) { this._preserveDirectiveContent = preserve; };
+
+  prototypeAccessors.warnHtmlInMessage.get = function () { return this._warnHtmlInMessage };
+  prototypeAccessors.warnHtmlInMessage.set = function (level) {
+      var this$1 = this;
+
+    var orgLevel = this._warnHtmlInMessage;
+    this._warnHtmlInMessage = level;
+    if (orgLevel !== level && (level === 'warn' || level === 'error')) {
+      var messages = this._getMessages();
+      Object.keys(messages).forEach(function (locale) {
+        this$1._checkLocaleMessage(locale, this$1._warnHtmlInMessage, messages[locale]);
+      });
+    }
+  };
+
+  prototypeAccessors.postTranslation.get = function () { return this._postTranslation };
+  prototypeAccessors.postTranslation.set = function (handler) { this._postTranslation = handler; };
+
+  VueI18n.prototype._getMessages = function _getMessages () { return this._vm.messages };
+  VueI18n.prototype._getDateTimeFormats = function _getDateTimeFormats () { return this._vm.dateTimeFormats };
+  VueI18n.prototype._getNumberFormats = function _getNumberFormats () { return this._vm.numberFormats };
+
+  VueI18n.prototype._warnDefault = function _warnDefault (locale, key, result, vm, values, interpolateMode) {
+    if (!isNull(result)) { return result }
+    if (this._missing) {
+      var missingRet = this._missing.apply(null, [locale, key, vm, values]);
+      if (isString(missingRet)) {
+        return missingRet
+      }
+    } else {
+      if (!this._isSilentTranslationWarn(key)) {
+        warn(
+          "Cannot translate the value of keypath '" + key + "'. " +
+          'Use the value of keypath as default.'
+        );
+      }
+    }
+
+    if (this._formatFallbackMessages) {
+      var parsedArgs = parseArgs.apply(void 0, values);
+      return this._render(key, interpolateMode, parsedArgs.params, key)
+    } else {
+      return key
+    }
+  };
+
+  VueI18n.prototype._isFallbackRoot = function _isFallbackRoot (val) {
+    return !val && !isNull(this._root) && this._fallbackRoot
+  };
+
+  VueI18n.prototype._isSilentFallbackWarn = function _isSilentFallbackWarn (key) {
+    return this._silentFallbackWarn instanceof RegExp
+      ? this._silentFallbackWarn.test(key)
+      : this._silentFallbackWarn
+  };
+
+  VueI18n.prototype._isSilentFallback = function _isSilentFallback (locale, key) {
+    return this._isSilentFallbackWarn(key) && (this._isFallbackRoot() || locale !== this.fallbackLocale)
+  };
+
+  VueI18n.prototype._isSilentTranslationWarn = function _isSilentTranslationWarn (key) {
+    return this._silentTranslationWarn instanceof RegExp
+      ? this._silentTranslationWarn.test(key)
+      : this._silentTranslationWarn
+  };
+
+  VueI18n.prototype._interpolate = function _interpolate (
+    locale,
+    message,
+    key,
+    host,
+    interpolateMode,
+    values,
+    visitedLinkStack
+  ) {
+    if (!message) { return null }
+
+    var pathRet = this._path.getPathValue(message, key);
+    if (isArray(pathRet) || isPlainObject(pathRet)) { return pathRet }
+
+    var ret;
+    if (isNull(pathRet)) {
+      /* istanbul ignore else */
+      if (isPlainObject(message)) {
+        ret = message[key];
+        if (!(isString(ret) || isFunction(ret))) {
+          if (!this._isSilentTranslationWarn(key) && !this._isSilentFallback(locale, key)) {
+            warn(("Value of key '" + key + "' is not a string or function !"));
+          }
+          return null
+        }
+      } else {
+        return null
+      }
+    } else {
+      /* istanbul ignore else */
+      if (isString(pathRet) || isFunction(pathRet)) {
+        ret = pathRet;
+      } else {
+        if (!this._isSilentTranslationWarn(key) && !this._isSilentFallback(locale, key)) {
+          warn(("Value of key '" + key + "' is not a string or function!"));
+        }
+        return null
+      }
+    }
+
+    // Check for the existence of links within the translated string
+    if (isString(ret) && (ret.indexOf('@:') >= 0 || ret.indexOf('@.') >= 0)) {
+      ret = this._link(locale, message, ret, host, 'raw', values, visitedLinkStack);
+    }
+
+    return this._render(ret, interpolateMode, values, key)
+  };
+
+  VueI18n.prototype._link = function _link (
+    locale,
+    message,
+    str,
+    host,
+    interpolateMode,
+    values,
+    visitedLinkStack
+  ) {
+    var ret = str;
+
+    // Match all the links within the local
+    // We are going to replace each of
+    // them with its translation
+    var matches = ret.match(linkKeyMatcher);
+    for (var idx in matches) {
+      // ie compatible: filter custom array
+      // prototype method
+      if (!matches.hasOwnProperty(idx)) {
+        continue
+      }
+      var link = matches[idx];
+      var linkKeyPrefixMatches = link.match(linkKeyPrefixMatcher);
+      var linkPrefix = linkKeyPrefixMatches[0];
+        var formatterName = linkKeyPrefixMatches[1];
+
+      // Remove the leading @:, @.case: and the brackets
+      var linkPlaceholder = link.replace(linkPrefix, '').replace(bracketsMatcher, '');
+
+      if (includes(visitedLinkStack, linkPlaceholder)) {
+        {
+          warn(("Circular reference found. \"" + link + "\" is already visited in the chain of " + (visitedLinkStack.reverse().join(' <- '))));
+        }
+        return ret
+      }
+      visitedLinkStack.push(linkPlaceholder);
+
+      // Translate the link
+      var translated = this._interpolate(
+        locale, message, linkPlaceholder, host,
+        interpolateMode === 'raw' ? 'string' : interpolateMode,
+        interpolateMode === 'raw' ? undefined : values,
+        visitedLinkStack
+      );
+
+      if (this._isFallbackRoot(translated)) {
+        if (!this._isSilentTranslationWarn(linkPlaceholder)) {
+          warn(("Fall back to translate the link placeholder '" + linkPlaceholder + "' with root locale."));
+        }
+        /* istanbul ignore if */
+        if (!this._root) { throw Error('unexpected error') }
+        var root = this._root.$i18n;
+        translated = root._translate(
+          root._getMessages(), root.locale, root.fallbackLocale,
+          linkPlaceholder, host, interpolateMode, values
+        );
+      }
+      translated = this._warnDefault(
+        locale, linkPlaceholder, translated, host,
+        isArray(values) ? values : [values],
+        interpolateMode
+      );
+
+      if (this._modifiers.hasOwnProperty(formatterName)) {
+        translated = this._modifiers[formatterName](translated);
+      } else if (defaultModifiers.hasOwnProperty(formatterName)) {
+        translated = defaultModifiers[formatterName](translated);
+      }
+
+      visitedLinkStack.pop();
+
+      // Replace the link with the translated
+      ret = !translated ? ret : ret.replace(link, translated);
+    }
+
+    return ret
+  };
+
+  VueI18n.prototype._createMessageContext = function _createMessageContext (values) {
+    var _list = isArray(values) ? values : [];
+    var _named = isObject(values) ? values : {};
+    var list = function (index) { return _list[index]; };
+    var named = function (key) { return _named[key]; };
+    return {
+      list: list,
+      named: named
+    }
+  };
+
+  VueI18n.prototype._render = function _render (message, interpolateMode, values, path) {
+    if (isFunction(message)) {
+      return message(this._createMessageContext(values))
+    }
+
+    var ret = this._formatter.interpolate(message, values, path);
+
+    // If the custom formatter refuses to work - apply the default one
+    if (!ret) {
+      ret = defaultFormatter.interpolate(message, values, path);
+    }
+
+    // if interpolateMode is **not** 'string' ('row'),
+    // return the compiled data (e.g. ['foo', VNode, 'bar']) with formatter
+    return interpolateMode === 'string' && !isString(ret) ? ret.join('') : ret
+  };
+
+  VueI18n.prototype._appendItemToChain = function _appendItemToChain (chain, item, blocks) {
+    var follow = false;
+    if (!includes(chain, item)) {
+      follow = true;
+      if (item) {
+        follow = item[item.length - 1] !== '!';
+        item = item.replace(/!/g, '');
+        chain.push(item);
+        if (blocks && blocks[item]) {
+          follow = blocks[item];
+        }
+      }
+    }
+    return follow
+  };
+
+  VueI18n.prototype._appendLocaleToChain = function _appendLocaleToChain (chain, locale, blocks) {
+    var follow;
+    var tokens = locale.split('-');
+    do {
+      var item = tokens.join('-');
+      follow = this._appendItemToChain(chain, item, blocks);
+      tokens.splice(-1, 1);
+    } while (tokens.length && (follow === true))
+    return follow
+  };
+
+  VueI18n.prototype._appendBlockToChain = function _appendBlockToChain (chain, block, blocks) {
+    var follow = true;
+    for (var i = 0; (i < block.length) && (isBoolean(follow)); i++) {
+      var locale = block[i];
+      if (isString(locale)) {
+        follow = this._appendLocaleToChain(chain, locale, blocks);
+      }
+    }
+    return follow
+  };
+
+  VueI18n.prototype._getLocaleChain = function _getLocaleChain (start, fallbackLocale) {
+    if (start === '') { return [] }
+
+    if (!this._localeChainCache) {
+      this._localeChainCache = {};
+    }
+
+    var chain = this._localeChainCache[start];
+    if (!chain) {
+      if (!fallbackLocale) {
+        fallbackLocale = this.fallbackLocale;
+      }
+      chain = [];
+
+      // first block defined by start
+      var block = [start];
+
+      // while any intervening block found
+      while (isArray(block)) {
+        block = this._appendBlockToChain(
+          chain,
+          block,
+          fallbackLocale
+        );
+      }
+
+      // last block defined by default
+      var defaults;
+      if (isArray(fallbackLocale)) {
+        defaults = fallbackLocale;
+      } else if (isObject(fallbackLocale)) {
+        /* $FlowFixMe */
+        if (fallbackLocale['default']) {
+          defaults = fallbackLocale['default'];
+        } else {
+          defaults = null;
+        }
+      } else {
+        defaults = fallbackLocale;
+      }
+
+      // convert defaults to array
+      if (isString(defaults)) {
+        block = [defaults];
+      } else {
+        block = defaults;
+      }
+      if (block) {
+        this._appendBlockToChain(
+          chain,
+          block,
+          null
+        );
+      }
+      this._localeChainCache[start] = chain;
+    }
+    return chain
+  };
+
+  VueI18n.prototype._translate = function _translate (
+    messages,
+    locale,
+    fallback,
+    key,
+    host,
+    interpolateMode,
+    args
+  ) {
+    var chain = this._getLocaleChain(locale, fallback);
+    var res;
+    for (var i = 0; i < chain.length; i++) {
+      var step = chain[i];
+      res =
+        this._interpolate(step, messages[step], key, host, interpolateMode, args, [key]);
+      if (!isNull(res)) {
+        if (step !== locale && "development" !== 'production' && !this._isSilentTranslationWarn(key) && !this._isSilentFallbackWarn(key)) {
+          warn(("Fall back to translate the keypath '" + key + "' with '" + step + "' locale."));
+        }
+        return res
+      }
+    }
+    return null
+  };
+
+  VueI18n.prototype._t = function _t (key, _locale, messages, host) {
+      var ref;
+
+      var values = [], len = arguments.length - 4;
+      while ( len-- > 0 ) values[ len ] = arguments[ len + 4 ];
+    if (!key) { return '' }
+
+    var parsedArgs = parseArgs.apply(void 0, values);
+    if(this._escapeParameterHtml) {
+      parsedArgs.params = escapeParams(parsedArgs.params);
+    }
+
+    var locale = parsedArgs.locale || _locale;
+
+    var ret = this._translate(
+      messages, locale, this.fallbackLocale, key,
+      host, 'string', parsedArgs.params
+    );
+    if (this._isFallbackRoot(ret)) {
+      if (!this._isSilentTranslationWarn(key) && !this._isSilentFallbackWarn(key)) {
+        warn(("Fall back to translate the keypath '" + key + "' with root locale."));
+      }
+      /* istanbul ignore if */
+      if (!this._root) { throw Error('unexpected error') }
+      return (ref = this._root).$t.apply(ref, [ key ].concat( values ))
+    } else {
+      ret = this._warnDefault(locale, key, ret, host, values, 'string');
+      if (this._postTranslation && ret !== null && ret !== undefined) {
+        ret = this._postTranslation(ret, key);
+      }
+      return ret
+    }
+  };
+
+  VueI18n.prototype.t = function t (key) {
+      var ref;
+
+      var values = [], len = arguments.length - 1;
+      while ( len-- > 0 ) values[ len ] = arguments[ len + 1 ];
+    return (ref = this)._t.apply(ref, [ key, this.locale, this._getMessages(), null ].concat( values ))
+  };
+
+  VueI18n.prototype._i = function _i (key, locale, messages, host, values) {
+    var ret =
+      this._translate(messages, locale, this.fallbackLocale, key, host, 'raw', values);
+    if (this._isFallbackRoot(ret)) {
+      if (!this._isSilentTranslationWarn(key)) {
+        warn(("Fall back to interpolate the keypath '" + key + "' with root locale."));
+      }
+      if (!this._root) { throw Error('unexpected error') }
+      return this._root.$i18n.i(key, locale, values)
+    } else {
+      return this._warnDefault(locale, key, ret, host, [values], 'raw')
+    }
+  };
+
+  VueI18n.prototype.i = function i (key, locale, values) {
+    /* istanbul ignore if */
+    if (!key) { return '' }
+
+    if (!isString(locale)) {
+      locale = this.locale;
+    }
+
+    return this._i(key, locale, this._getMessages(), null, values)
+  };
+
+  VueI18n.prototype._tc = function _tc (
+    key,
+    _locale,
+    messages,
+    host,
+    choice
+  ) {
+      var ref;
+
+      var values = [], len = arguments.length - 5;
+      while ( len-- > 0 ) values[ len ] = arguments[ len + 5 ];
+    if (!key) { return '' }
+    if (choice === undefined) {
+      choice = 1;
+    }
+
+    var predefined = { 'count': choice, 'n': choice };
+    var parsedArgs = parseArgs.apply(void 0, values);
+    parsedArgs.params = Object.assign(predefined, parsedArgs.params);
+    values = parsedArgs.locale === null ? [parsedArgs.params] : [parsedArgs.locale, parsedArgs.params];
+    return this.fetchChoice((ref = this)._t.apply(ref, [ key, _locale, messages, host ].concat( values )), choice)
+  };
+
+  VueI18n.prototype.fetchChoice = function fetchChoice (message, choice) {
+    /* istanbul ignore if */
+    if (!message || !isString(message)) { return null }
+    var choices = message.split('|');
+
+    choice = this.getChoiceIndex(choice, choices.length);
+    if (!choices[choice]) { return message }
+    return choices[choice].trim()
+  };
+
+  VueI18n.prototype.tc = function tc (key, choice) {
+      var ref;
+
+      var values = [], len = arguments.length - 2;
+      while ( len-- > 0 ) values[ len ] = arguments[ len + 2 ];
+    return (ref = this)._tc.apply(ref, [ key, this.locale, this._getMessages(), null, choice ].concat( values ))
+  };
+
+  VueI18n.prototype._te = function _te (key, locale, messages) {
+      var args = [], len = arguments.length - 3;
+      while ( len-- > 0 ) args[ len ] = arguments[ len + 3 ];
+
+    var _locale = parseArgs.apply(void 0, args).locale || locale;
+    return this._exist(messages[_locale], key)
+  };
+
+  VueI18n.prototype.te = function te (key, locale) {
+    return this._te(key, this.locale, this._getMessages(), locale)
+  };
+
+  VueI18n.prototype.getLocaleMessage = function getLocaleMessage (locale) {
+    return looseClone(this._vm.messages[locale] || {})
+  };
+
+  VueI18n.prototype.setLocaleMessage = function setLocaleMessage (locale, message) {
+    if (this._warnHtmlInMessage === 'warn' || this._warnHtmlInMessage === 'error') {
+      this._checkLocaleMessage(locale, this._warnHtmlInMessage, message);
+    }
+    this._vm.$set(this._vm.messages, locale, message);
+  };
+
+  VueI18n.prototype.mergeLocaleMessage = function mergeLocaleMessage (locale, message) {
+    if (this._warnHtmlInMessage === 'warn' || this._warnHtmlInMessage === 'error') {
+      this._checkLocaleMessage(locale, this._warnHtmlInMessage, message);
+    }
+    this._vm.$set(this._vm.messages, locale, merge(
+      typeof this._vm.messages[locale] !== 'undefined' && Object.keys(this._vm.messages[locale]).length
+        ? this._vm.messages[locale]
+        : {},
+      message
+    ));
+  };
+
+  VueI18n.prototype.getDateTimeFormat = function getDateTimeFormat (locale) {
+    return looseClone(this._vm.dateTimeFormats[locale] || {})
+  };
+
+  VueI18n.prototype.setDateTimeFormat = function setDateTimeFormat (locale, format) {
+    this._vm.$set(this._vm.dateTimeFormats, locale, format);
+    this._clearDateTimeFormat(locale, format);
+  };
+
+  VueI18n.prototype.mergeDateTimeFormat = function mergeDateTimeFormat (locale, format) {
+    this._vm.$set(this._vm.dateTimeFormats, locale, merge(this._vm.dateTimeFormats[locale] || {}, format));
+    this._clearDateTimeFormat(locale, format);
+  };
+
+  VueI18n.prototype._clearDateTimeFormat = function _clearDateTimeFormat (locale, format) {
+    for (var key in format) {
+      var id = locale + "__" + key;
+
+      if (!this._dateTimeFormatters.hasOwnProperty(id)) {
+        continue
+      }
+
+      delete this._dateTimeFormatters[id];
+    }
+  };
+
+  VueI18n.prototype._localizeDateTime = function _localizeDateTime (
+    value,
+    locale,
+    fallback,
+    dateTimeFormats,
+    key
+  ) {
+    var _locale = locale;
+    var formats = dateTimeFormats[_locale];
+
+    var chain = this._getLocaleChain(locale, fallback);
+    for (var i = 0; i < chain.length; i++) {
+      var current = _locale;
+      var step = chain[i];
+      formats = dateTimeFormats[step];
+      _locale = step;
+      // fallback locale
+      if (isNull(formats) || isNull(formats[key])) {
+        if (step !== locale && "development" !== 'production' && !this._isSilentTranslationWarn(key) && !this._isSilentFallbackWarn(key)) {
+          warn(("Fall back to '" + step + "' datetime formats from '" + current + "' datetime formats."));
+        }
+      } else {
+        break
+      }
+    }
+
+    if (isNull(formats) || isNull(formats[key])) {
+      return null
+    } else {
+      var format = formats[key];
+      var id = _locale + "__" + key;
+      var formatter = this._dateTimeFormatters[id];
+      if (!formatter) {
+        formatter = this._dateTimeFormatters[id] = new Intl.DateTimeFormat(_locale, format);
+      }
+      return formatter.format(value)
+    }
+  };
+
+  VueI18n.prototype._d = function _d (value, locale, key) {
+    /* istanbul ignore if */
+    if (!VueI18n.availabilities.dateTimeFormat) {
+      warn('Cannot format a Date value due to not supported Intl.DateTimeFormat.');
+      return ''
+    }
+
+    if (!key) {
+      return new Intl.DateTimeFormat(locale).format(value)
+    }
+
+    var ret =
+      this._localizeDateTime(value, locale, this.fallbackLocale, this._getDateTimeFormats(), key);
+    if (this._isFallbackRoot(ret)) {
+      if (!this._isSilentTranslationWarn(key) && !this._isSilentFallbackWarn(key)) {
+        warn(("Fall back to datetime localization of root: key '" + key + "'."));
+      }
+      /* istanbul ignore if */
+      if (!this._root) { throw Error('unexpected error') }
+      return this._root.$i18n.d(value, key, locale)
+    } else {
+      return ret || ''
+    }
+  };
+
+  VueI18n.prototype.d = function d (value) {
+      var args = [], len = arguments.length - 1;
+      while ( len-- > 0 ) args[ len ] = arguments[ len + 1 ];
+
+    var locale = this.locale;
+    var key = null;
+
+    if (args.length === 1) {
+      if (isString(args[0])) {
+        key = args[0];
+      } else if (isObject(args[0])) {
+        if (args[0].locale) {
+          locale = args[0].locale;
+        }
+        if (args[0].key) {
+          key = args[0].key;
+        }
+      }
+    } else if (args.length === 2) {
+      if (isString(args[0])) {
+        key = args[0];
+      }
+      if (isString(args[1])) {
+        locale = args[1];
+      }
+    }
+
+    return this._d(value, locale, key)
+  };
+
+  VueI18n.prototype.getNumberFormat = function getNumberFormat (locale) {
+    return looseClone(this._vm.numberFormats[locale] || {})
+  };
+
+  VueI18n.prototype.setNumberFormat = function setNumberFormat (locale, format) {
+    this._vm.$set(this._vm.numberFormats, locale, format);
+    this._clearNumberFormat(locale, format);
+  };
+
+  VueI18n.prototype.mergeNumberFormat = function mergeNumberFormat (locale, format) {
+    this._vm.$set(this._vm.numberFormats, locale, merge(this._vm.numberFormats[locale] || {}, format));
+    this._clearNumberFormat(locale, format);
+  };
+
+  VueI18n.prototype._clearNumberFormat = function _clearNumberFormat (locale, format) {
+    for (var key in format) {
+      var id = locale + "__" + key;
+
+      if (!this._numberFormatters.hasOwnProperty(id)) {
+        continue
+      }
+
+      delete this._numberFormatters[id];
+    }
+  };
+
+  VueI18n.prototype._getNumberFormatter = function _getNumberFormatter (
+    value,
+    locale,
+    fallback,
+    numberFormats,
+    key,
+    options
+  ) {
+    var _locale = locale;
+    var formats = numberFormats[_locale];
+
+    var chain = this._getLocaleChain(locale, fallback);
+    for (var i = 0; i < chain.length; i++) {
+      var current = _locale;
+      var step = chain[i];
+      formats = numberFormats[step];
+      _locale = step;
+      // fallback locale
+      if (isNull(formats) || isNull(formats[key])) {
+        if (step !== locale && "development" !== 'production' && !this._isSilentTranslationWarn(key) && !this._isSilentFallbackWarn(key)) {
+          warn(("Fall back to '" + step + "' number formats from '" + current + "' number formats."));
+        }
+      } else {
+        break
+      }
+    }
+
+    if (isNull(formats) || isNull(formats[key])) {
+      return null
+    } else {
+      var format = formats[key];
+
+      var formatter;
+      if (options) {
+        // If options specified - create one time number formatter
+        formatter = new Intl.NumberFormat(_locale, Object.assign({}, format, options));
+      } else {
+        var id = _locale + "__" + key;
+        formatter = this._numberFormatters[id];
+        if (!formatter) {
+          formatter = this._numberFormatters[id] = new Intl.NumberFormat(_locale, format);
+        }
+      }
+      return formatter
+    }
+  };
+
+  VueI18n.prototype._n = function _n (value, locale, key, options) {
+    /* istanbul ignore if */
+    if (!VueI18n.availabilities.numberFormat) {
+      {
+        warn('Cannot format a Number value due to not supported Intl.NumberFormat.');
+      }
+      return ''
+    }
+
+    if (!key) {
+      var nf = !options ? new Intl.NumberFormat(locale) : new Intl.NumberFormat(locale, options);
+      return nf.format(value)
+    }
+
+    var formatter = this._getNumberFormatter(value, locale, this.fallbackLocale, this._getNumberFormats(), key, options);
+    var ret = formatter && formatter.format(value);
+    if (this._isFallbackRoot(ret)) {
+      if (!this._isSilentTranslationWarn(key) && !this._isSilentFallbackWarn(key)) {
+        warn(("Fall back to number localization of root: key '" + key + "'."));
+      }
+      /* istanbul ignore if */
+      if (!this._root) { throw Error('unexpected error') }
+      return this._root.$i18n.n(value, Object.assign({}, { key: key, locale: locale }, options))
+    } else {
+      return ret || ''
+    }
+  };
+
+  VueI18n.prototype.n = function n (value) {
+      var args = [], len = arguments.length - 1;
+      while ( len-- > 0 ) args[ len ] = arguments[ len + 1 ];
+
+    var locale = this.locale;
+    var key = null;
+    var options = null;
+
+    if (args.length === 1) {
+      if (isString(args[0])) {
+        key = args[0];
+      } else if (isObject(args[0])) {
+        if (args[0].locale) {
+          locale = args[0].locale;
+        }
+        if (args[0].key) {
+          key = args[0].key;
+        }
+
+        // Filter out number format options only
+        options = Object.keys(args[0]).reduce(function (acc, key) {
+            var obj;
+
+          if (includes(numberFormatKeys, key)) {
+            return Object.assign({}, acc, ( obj = {}, obj[key] = args[0][key], obj ))
+          }
+          return acc
+        }, null);
+      }
+    } else if (args.length === 2) {
+      if (isString(args[0])) {
+        key = args[0];
+      }
+      if (isString(args[1])) {
+        locale = args[1];
+      }
+    }
+
+    return this._n(value, locale, key, options)
+  };
+
+  VueI18n.prototype._ntp = function _ntp (value, locale, key, options) {
+    /* istanbul ignore if */
+    if (!VueI18n.availabilities.numberFormat) {
+      {
+        warn('Cannot format to parts a Number value due to not supported Intl.NumberFormat.');
+      }
+      return []
+    }
+
+    if (!key) {
+      var nf = !options ? new Intl.NumberFormat(locale) : new Intl.NumberFormat(locale, options);
+      return nf.formatToParts(value)
+    }
+
+    var formatter = this._getNumberFormatter(value, locale, this.fallbackLocale, this._getNumberFormats(), key, options);
+    var ret = formatter && formatter.formatToParts(value);
+    if (this._isFallbackRoot(ret)) {
+      if (!this._isSilentTranslationWarn(key)) {
+        warn(("Fall back to format number to parts of root: key '" + key + "' ."));
+      }
+      /* istanbul ignore if */
+      if (!this._root) { throw Error('unexpected error') }
+      return this._root.$i18n._ntp(value, locale, key, options)
+    } else {
+      return ret || []
+    }
+  };
+
+  Object.defineProperties( VueI18n.prototype, prototypeAccessors );
+
+  var availabilities;
+  // $FlowFixMe
+  Object.defineProperty(VueI18n, 'availabilities', {
+    get: function get () {
+      if (!availabilities) {
+        var intlDefined = typeof Intl !== 'undefined';
+        availabilities = {
+          dateTimeFormat: intlDefined && typeof Intl.DateTimeFormat !== 'undefined',
+          numberFormat: intlDefined && typeof Intl.NumberFormat !== 'undefined'
+        };
+      }
+
+      return availabilities
+    }
+  });
+
+  VueI18n.install = install;
+  VueI18n.version = '8.24.1';
+
+  return VueI18n;
+
+})));

+ 48 - 0
lang/zh_cn.js

@@ -0,0 +1,48 @@
+module.exports =  {
+    hea:{
+		vipzs: '黑钻VIP义工专属',
+		dsy: '度收益',
+		wyyz: '我要援助',
+		yz: '援助',
+		ywc: '已完成',
+		lksj: '立即升级',
+		ytg: '已通过',
+		wtg: '未通过',
+		ren: '人',
+		ckxq:'查看详情',
+		
+		jj: '拒绝',
+		ty: '同意',
+		ysh: '已审核',
+		wsh: '未审核',
+		wjmm: '忘记密码',
+		logininfo:'您未登录,是否马上登陆?',
+		yk: '游客',
+		lxkf: '联系客服',
+		fxhy: '分享好友',
+		wdtd: '我的团队',
+		wdtg: '我的推广',
+		wdtgrs: '我的推广人数',
+		login: '登录',
+       gwsy:'官网首页',
+       gscp:'公司产品',
+       faal:'方案案例',
+       gywm:'关于我们',
+       yyxz:'Language',
+       ljgd:"了解更多"
+    },
+    foo:{
+        hwsc:'海外市场',
+      cplb:'产品列表',
+       faal:'方案案例',
+        zyj:'增氧机系列',
+        gzwm:'关注我们',
+        fdgzh:'富地公众号',
+		fddy:'富地抖音号',
+        zz:'制造',
+        jz:'价值',
+        wh:'文化',
+        zzkhty:"专注客户体验 创新引导技术",
+        qywh:'公司拥有一支乐业、敬业、专业的员工队伍,传承“完善小我成就大我”的团队协作精神,坚持“严管理”求创新、高品质、拓市场”的经营方针,秉承“您所想的就是我们所做”的经营理念我们一贯坚持高品质,优质服务合理价格,快速的交货期,信守客户承诺的企业宗旨',
+    }
+}

+ 5 - 2
main.js

@@ -1,7 +1,9 @@
 import Vue from 'vue'
 import store from './store'
 import App from './App'
-import uView from "uview-ui";
+import uView from "uview-ui";
+import i18n from "./lang/i18n";
+
 Vue.use(uView);
 /**
  *  所有测试用数据均存放于根目录json.js
@@ -41,6 +43,7 @@ Vue.prototype.$api = {msg, prePage};
 App.mpType = 'app'
 
 const app = new Vue({
-    ...App
+    ...App,
+	i18n,
 })
 app.$mount()

+ 25 - 18
pages/index/index.vue

@@ -1,5 +1,6 @@
 <template>
-	<view class="content">
+	<view class="content">
+		<base-nav ></base-nav>
 		<view class="top"><image src="../../static/img/index/index.png" mode="" class="bg"></image></view>
 		<view class="box">
 			<view v-for="(item, index) in list" :key="index">
@@ -9,7 +10,7 @@
 						<text>{{ item.money*2 }}</text>
 					</view>
-					<view class="baodan" @click="baodan(item.id)">查看详情</view>
+					<view class="baodan" @click="baodan(item.id)">{{$t('hea.ckxq')}}</view>
 				</view>
 			</view>
 		</view>
@@ -19,12 +20,16 @@
 		</view>
 	</view>
 </template>
-<script>
+<script>
+import baseNav from '@/pages/public/nav.vue';
 import { mapState, mapMutations } from 'vuex';
 import { activityList } from '@/api/active.js';
-import { saveUrl, interceptor } from '@/utils/loginUtils.js';
+import { saveUrl, interceptor } from '@/utils/loginUtils.js';
+import store from '../../store/index.js'
 export default {
-	components: {},
+	components: {
+		baseNav,
+	},
 	computed: {
 		...mapState('user', ['userInfo', 'orderInfo', 'hasLogin'])
 	},
@@ -37,20 +42,22 @@ export default {
 	onShow() {
 		if (this.hasLogin) {
 			this.loadData();
-		} else {
-			uni.showModal({
-				title: '登录',
-				content: '您未登录,是否马上登陆?',
-				success: e => {
-					if (e.confirm) {
-						saveUrl();
-						interceptor();
-					}
-				},
-				fail: e => {
-					console.log(e);
-				}
+		} else {
+			let obj = this
+			uni.showModal({
+				title: obj.$t('hea.login'),
+				content: obj.$t('hea.logininfo'),
+				success: e => {
+					if (e.confirm) {
+						saveUrl();
+						interceptor();
+					}
+				},
+				fail: e => {
+					console.log(e);
+				}
 			});
+			
 		}
 	},
 	methods: {

+ 6 - 6
pages/index/infoDetail.vue

@@ -2,7 +2,7 @@
 	<view class="center">
 		<view class="box">
 			<view class="discounts">
-				<view class="title">援助:</view>
+				<view class="title">{{$t('hea.yz')}}:</view>
 				<view class="money">
 					<text>{{ item.money * 2 || 0}}</text>
@@ -17,7 +17,7 @@
 					<view class="main-item"  v-for="(ls, index) in revenueList">
 						<view class="main-image"><image :src="image[index]" mode=""></image></view>
 						<view class="main-font">
-							<view class="textDetail-title">{{ index < 2 ? index + 1 + '度受益' : index + 1 + '度收益(黑钻VIP义工专属)' }}</view>
+							<view class="textDetail-title">{{ index < 2 ? index + 1 + $t('hea.dsy') : index + 1 + $t('hea.dsy') + '(' + $t('hea.vipzs')+ ')' }}</view>
 							<view class="textDetail-content">{{ ls }}</view>
 						</view>
 					</view>
@@ -38,10 +38,10 @@
 			</view> -->
 		</view>
 
-		<view class="baodan"  @click="baodan(id)" v-if="status == '0'">我要援助</view>
-		<view class="baodan1"  @click="baodan(id)" v-if="status == '1'&&item.income*1<item.v2_limit*1 && item.v2_layer != 0" >立即升级</view>
-		<view class="baodan"  @click="baodan(id)" v-if="status == '1'&&item.income*1>=item.v2_limit*1 && item.v2_layer != 0">立即升级</view>
-		<view class="baodan" v-if="status == '2'||(status == '1' && item.v2_layer == 0)" style="background: #020202;">已完成</view>
+		<view class="baodan"  @click="baodan(id)" v-if="status == '0'">{{$t('hea.wyyz')}}</view>
+		<view class="baodan1"  @click="baodan(id)" v-if="status == '1'&&item.income*1<item.v2_limit*1 && item.v2_layer != 0" >{{$t('hea.lksj')}}</view>
+		<view class="baodan"  @click="baodan(id)" v-if="status == '1'&&item.income*1>=item.v2_limit*1 && item.v2_layer != 0">{{$t('hea.lksj')}}</view>
+		<view class="baodan" v-if="status == '2'||(status == '1' && item.v2_layer == 0)" style="background: #020202;">{{$t('hea.ywc')}}</view>
 	</view>
 </template>
 

+ 2 - 2
pages/public/login.vue

@@ -14,12 +14,12 @@
 				<view class="login_img"><image src="../../static/icon/icon-code.png"></image></view>
 				<view class="login_name"><input class="uni-input" type="password" v-model="passward" focus placeholder="请输入密码" /></view>
 			</view>
-			<view><button type="green" class="uni-button uni-button-green" @click="toLogin">登录</button></view>
+			<view><button type="green" class="uni-button uni-button-green" @click="toLogin">{{$t('hea.login')}}</button></view>
 			<!-- <view><button type="green" class="uni-button uni-button-green uni-button-green-plain" plain="true"
 					hover-class="none" @click="register">注册</button></view> -->
 			<view class=" flex bombtn">
 				<navigator url="./forget">
-					<view class="bbtn">忘记密码</view>
+					<view class="bbtn">{{$t('hea.wjmm')}}</view>
 				</navigator>
 				<!-- <view class="jg">
 				</view>

+ 218 - 0
pages/public/nav.vue

@@ -0,0 +1,218 @@
+<template>
+	<view class="box">
+		<view class="header-box">
+			<view class="top-box">
+				<view class="box-right"><wyb-drop-down :zIndex='1' class="han-box" ref="dropDown" :options="options" @select="onItemSelect"></wyb-drop-down></view>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+import wybDropDown from '@/components/wyb-drop-down/wyb-drop-down.vue';
+// import { goodslist,allist,aboutlist, fllist } from '../../api/api.js';
+export default {
+	components: {
+		wybDropDown
+	},
+	data() {
+		return {
+			show: false,
+			options: [
+				{
+					header: 'Language',
+					contents: ['中文', 'english']
+				}
+			],
+			langlist: ['zh_cn', 'en'],
+			// 弹窗分类样式
+			itemStyle: {
+				fontSize: '36rpx',
+				fontWeight: 'bold'
+			},
+			//  弹窗标题样式
+			titleStyle: {
+				'font-size': '40rpx'
+			},
+			//弹窗当前idnex
+			swIndex: 0,
+			checkedIndex: 0, //设置当前选中的分类对象
+			popList: [
+				{
+					type: 'product',
+					title: '公司产品',
+					list: [], //保存商品列表
+					loding: false, //判断是否加载中
+					more: 'loadmore' //判断是否还可以加载数据
+				},
+				{
+					type: 'cases',
+					title: '方案案例',
+					list: [], //保存商品列表
+					loding: false, //判断是否加载中
+					more: 'loadmore' //判断是否还可以加载数据
+				},
+				{
+					type: 'about',
+					title: '关于我们',
+					list: [], //保存商品列表
+					loding: false, //判断是否加载中
+					more: 'loadmore' //判断是否还可以加载数据
+				}
+			],
+			// 自定义加载文本
+			loadText: {
+				loadmore: 'loading...',
+				loading: 'loading...',
+				nomore: 'ready'
+			}
+		};
+	},
+	created() {
+		// this.init();
+		const lang = uni.getStorageSync('lang')||0;
+		this.$store.commit('changelang', this.langlist[lang]);
+	},
+	methods: {
+		// 下拉选择语言分类
+		onItemSelect(e) {
+			const lang = this.langlist[e.contentIndex];
+			uni.setStorageSync('lang',e.contentIndex)
+			this.$store.commit('changelang', lang);
+			this.$i18n.locale = lang;
+			// 保存当前选中的对象
+			this.$emit('changeSelect', e);
+			this.$refs.dropDown.close();
+			console.log(lang);
+		},
+	}
+};
+</script>
+
+<style lang="scss">
+.alertSw {
+	height: 100vh;
+	.item {
+		padding-top: 100rpx;
+	}
+}
+/deep/ .collapseItemBox{
+	.title{
+		padding: 30rpx;
+		font-size: 32rpx;
+		font-weight: bold;
+		color: #101010;
+	}
+}
+.margin-t-40 {
+	margin-top: 40rpx;
+}
+.alertColl,
+.pop-box,
+.header-box {
+	padding: 0 30rpx;
+}
+.navtoIndex {
+	font-size: 41rpx;
+	font-weight: bold;
+	margin-bottom: 20rpx;
+	padding-left: 30rpx;
+}
+.pop-box {
+	position: relative;
+	width: 700rpx;
+	padding-right: 15rpx;
+	.box-right {
+		position: absolute;
+		top: 0;
+		left: 0;
+		width: 100%;
+		text-align: right;
+		// margin-bottom: 20rpx;
+		display: flex;
+		justify-content: space-between;
+		align-items: center;
+		z-index: 999;
+		.item {
+			padding: 30rpx;
+		}
+	}
+	.collapse-item {
+		font-weight: 500;
+		.item-box {
+			font-size: 28rpx;
+			color: #101010;
+			// margin-bottom: 15rpx;
+			line-height: 50rpx;
+		}
+	}
+}
+.header-box {
+	width: 750rpx;
+	height: 100rpx;
+	background: #fefefe;
+	display: flex;
+	align-items: center;
+	padding: 0 30rpx;
+	box-shadow: 0px 0px 20rpx 0px rgba(50, 50, 52, 0.06);
+	position: fixed;
+	top: 0;
+	left: 0;
+	z-index: 1000;
+	.box-center {
+		flex: 1;
+		text-align: center;
+		margin-left: 180rpx;
+		font-size: 34rpx;
+		font-weight: bold;
+		color: #101010;
+	}
+
+	.box-right {
+		width: 180rpx;
+		text-align: right;
+		position: relative;
+		height: calc(100% - 1px);
+		overflow: hidden;
+		/deep/ .wyb-drop-down-header {
+			position: absolute;
+			top: 0;
+			left: 0;
+			width: 100%;
+		}
+		/deep/ .wyb-drop-down-content {
+			top: 88rpx;
+		}
+	}
+	.top-box {
+		display: flex;
+		justify-content: space-between;
+		align-items: center;
+		width: 100%;
+		height: 100rpx;
+		z-index: 99999;
+		.top-left {
+			height: 100%;
+			display: flex;
+			align-items: center;
+			flex-grow: 1;
+			background-color: #e3e3e3;
+			.logo-img {
+				width: 314rpx;
+				height: 43rpx;
+			}
+		}
+		.top-right,
+		.top-left {
+			z-index: 99999;
+			background-color: #ffffff;
+		}
+		.top-right {
+			padding-left: 20rpx;
+			height: 100%;
+			display: flex;
+			align-items: center;
+		}
+	}
+}
+</style>

+ 3 - 3
pages/user/applyList.vue

@@ -20,10 +20,10 @@
 						<view class="apply-info flex">
 							<view class="img-wrap"><image :src="imgitem" mode="" class="upimg" v-for="imgitem in item.voucherimages" @click="open(imgitem)"></image></view>
 							<view class="btn-wrap flex" v-if="tabCurrentIndex == 0">
-								<view class="btn btn-reject" @click="cancelApply(item)">拒绝</view>
-								<view class="btn btn-pass" @click="passApply(item)">通过</view>
+								<view class="btn btn-reject" @click="cancelApply(item)">{{$t('hea.jj')}}</view>
+								<view class="btn btn-pass" @click="passApply(item)">{{$t('hea.ty')}}</view>
 							</view>
-							<view class="btn-wrap" v-if="tabCurrentIndex == 1">{{ item.status == 1 ? '已通过' : '未通过' }}</view>
+							<view class="btn-wrap" v-if="tabCurrentIndex == 1">{{ item.status == 1 ? $t('hea.ytg') : $t('hea.wtg') }}</view>
 						</view>
 					</view>
 					<uni-load-more :status="tabItem.loadingType"></uni-load-more>

+ 2 - 2
pages/user/promotion.vue

@@ -5,9 +5,9 @@
 			<view class="money-box">
 				<view class="money">
 					{{ all || 0 }}
-					<text></text>
+					<text>{{$t('hea.ren')}}</text>
 				</view>
-				<view class="text">我的推广人数</view>
+				<view class="text">{{$t('hea.wdtgrs')}}</view>
 			</view>
 		</view>
 		<!-- <view class="navbar flex">

+ 8 - 7
pages/user/user.vue

@@ -4,7 +4,7 @@
 			<view class="detail flex" @click="navTo('/pages/set/userinfo')">
 				<view class="portrait-box"><image class="portrait" :src="userInfo.avatar || '../../static/error/missing-face.png'"></image></view>
 				<view class="info-box">
-					<view class="username">{{ userInfo.nickname || '游客' }}</view>
+					<view class="username">{{ userInfo.nickname || $t('hea.yk') }}</view>
 					<view class="font-size-sm">{{ userInfo.mobile || '' }}</view>
 				</view>
 				<view class="vip">
@@ -19,22 +19,22 @@
 		<view class="tt">
 			<view class="tt-box" @click="navTo('/pages/user/promotion')">
 				<image src="../../static/img/tuiguang.png" class="tt-icon1" mode=""></image>
-				<view class="tt-txt">我的推广</view>
+				<view class="tt-txt">{{$t('hea.wdtg')}}</view>
 				<image src="../../static/img/jiantou.png" class="next-icon" mode=""></image>
 			</view>
 			<view class="tt-box" @click="navTo('/pages/user/team')">
 				<image src="../../static/img/team.png" class="tt-icon1" mode=""></image>
-				<view class="tt-txt">我的团队</view>
+				<view class="tt-txt">{{$t('hea.wdtd')}}</view>
 				<image src="../../static/img/jiantou.png" class="next-icon" mode=""></image>
 			</view>
 			<view class="tt-box" @click="navTo('/pages/user/shareQrCode')">
 				<image src="../../static/img/share.png" class="tt-icon1" mode=""></image>
-				<view class="tt-txt">分享好友</view>
+				<view class="tt-txt">{{$t('hea.fxhy')}}</view>
 				<image src="../../static/img/jiantou.png" class="next-icon" mode=""></image>
 			</view>
 			<view class="tt-box" @click="open()">
 				<image src="../../static/img/kefu.png" class="tt-icon1" mode=""></image>
-				<view class="tt-txt">联系客服</view>
+				<view class="tt-txt">{{$t('hea.lxkf')}}</view>
 				<image src="../../static/img/jiantou.png" class="next-icon" mode=""></image>
 			</view>
 		</view>
@@ -82,9 +82,10 @@ export default {
 		if (this.hasLogin) {
 			this.loadBaseData();
 		} else {
+			let obj = this
 			uni.showModal({
-				title: '登录',
-				content: '您未登录,是否马上登陆?',
+				title: obj.$t('hea.login'),
+				content: obj.$t('hea.logininfo'),
 				success: e => {
 					if (e.confirm) {
 						saveUrl();

+ 7 - 2
store/index.js

@@ -4,7 +4,8 @@ import user from './model/user'
 Vue.use(Vuex)
 
 const store = new Vuex.Store({
-	state: {
+	state: {
+		lang:'zh_cn',
 		// baseURL:"http://yrh.liuniu946.com",//'http://eb.shuibo.net',//请求地址配置 
 		baseURL:'http://bowin.frp.liuniu946.com',//请求地址配置 
 		urlFile:'/index',//项目部署所在文件夹
@@ -15,7 +16,11 @@ const store = new Vuex.Store({
 		weichatObj:'',//微信对象
 		// #endif
 	},
-	mutations: {
+	mutations: {
+		//切换语言
+		  changelang(state,lang){
+		      state.lang = lang
+		    },
 		//保存微信信息
 		setWeiChatInfo(state, provider) {
 			state.weichatInfo = provider;

+ 4 - 13
utils/request.js

@@ -64,25 +64,16 @@ service.interceptors.response(
 service.interceptors.request(
 	config => {
 		let token = uni.getStorageSync('token') || '';
-		let lang = ''
-		try {
-		    const systemInfo = uni.getSystemInfoSync();
-			lang = systemInfo.language || 'zh-CN'
-		} catch (e) {
-		   console.log(e)
-		   lang = 'zh-CN'
-		}
+		const langlist=['zh_cn', 'en', 'es'];
+		let lang = store.state.lang||langlist[uni.getStorageSync('lang')];
 		
-		// console.log(config);
 		if (!config.header) {
-			config.header = {
-				// "Authori-zation": 'Bearer ' + token,
+			config.header = {
 				"bowintoken": token,
 				"bowinlang": lang
 			}
 		} else {
-			// 添加key请求头
-			// config.header["Authori-zation"] = 'Bearer ' + token;
+			// 添加key请求头
 			config.header["bowintoken"] = token
 			config.header["bowinlang"] = lang
 		}