commit c7ccd6a193602b57dbfb05bf5cf4ef8c4b097d39
Author: unknown <331404948@qq.com>
Date: Fri Aug 25 11:20:05 2023 +0800
first commit
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..c3d8c3c
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,7 @@
+node_modules
+package-lock.json
+unpackage/dist
+unpackage/cache
+.hbuilderx
+unpackage
+
diff --git a/App.vue b/App.vue
new file mode 100644
index 0000000..2211627
--- /dev/null
+++ b/App.vue
@@ -0,0 +1,20 @@
+
+
+
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..e69de29
diff --git a/common/css/app.scss b/common/css/app.scss
new file mode 100644
index 0000000..fa31dcc
--- /dev/null
+++ b/common/css/app.scss
@@ -0,0 +1,139 @@
+page {
+ background-color: #fff;
+ font-size: 32rpx;
+ font-family: -apple-system-font, Helvetica Neue, Helvetica, sans-serif;
+}
+view {
+ box-sizing: border-box;
+}
+
+.oneRowText {
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+}
+.towRowText {
+ display: -webkit-box;
+ overflow: hidden;
+ white-space: normal;
+ text-overflow: ellipsis;
+ word-wrap: break-word;
+ -webkit-line-clamp: 2;
+ -webkit-box-orient: vertical
+}
+.bgLinear {
+ background: linear-gradient(180deg, #3593FB 0%, #53D3E5 100%);
+}
+.flex-b {
+ justify-content: space-between;
+ display: flex;
+ align-items: center;
+}
+.flex {
+ display: flex;
+ align-items: center;
+}
+.pageBg {
+ background: #F6F6F6;
+ color: #333;
+ font-size: 28rpx;
+ min-height: 100vh;
+}
+.pageBgImg {
+ font-size: 28rpx;;
+ color: #333;
+ background: url('http://192.168.1.20:81/zhili/image/20230824/afabc8b8a39544dc9ee4aea739b716cc.png') #F6F6F6 no-repeat;
+ background-size: 100% 324rpx;
+ min-height: 100vh;
+}
+.pad {
+ padding: 0 28rpx;
+}
+.card {
+ width: 100%;
+ background: #fff;
+ border-radius: 16rpx;
+}
+.status_bar {
+ height: var(--status-bar-height);
+ width: 100%;
+ }
+image {
+ display: block;
+ width: 100%;
+ height: 100%;
+}
+.placeholderClassFFF {
+ color: #fff !important;
+}
+.starBox {
+ display: flex;
+ .num {
+ color: $themC;
+ font-size: 24rpx;
+ }
+ }
+
+.my .u-input {
+ height: 100%;
+ }
+
+ .h1 {
+ font-size: 32rpx;
+ color: #333;
+ font-weight: 500;
+ position: relative;
+ padding: 0 0 0 32rpx;
+ &::before {
+ position: absolute;
+ content: '';
+ width: 8rpx;
+ height: 32rpx;
+ background: #1F6EFA;
+ border-radius: 4rpx;
+ top: 50%;
+ transform: translateY(-50%);
+ left: 0;
+ }
+ }
+
+ .btnBg {
+ height: 72rpx;
+ background: #1989FA;
+ border-radius: 8rpx;
+ line-height: 72rpx;
+ text-align: center;
+ font-size: 28rpx;
+ color: #fff;
+ }
+
+ .btnBorder {
+ height: 72rpx;
+ background: #DFEAF5;
+ border-radius: 8rpx;
+ line-height: 72rpx;
+ text-align: center;
+ font-size: 28rpx;
+ color:$themC;
+ border: 2rpx solid #1989FA;
+ }
+
+ /* 通用 */
+ ::-webkit-input-placeholder { color:#ADADAD; }
+ ::-moz-placeholder { color:#ADADAD; } /* firefox 19+ */
+ :-ms-input-placeholder { color:#ADADAD; } /* ie */
+ input:-moz-placeholder { color:#ADADAD; }
+
+ input::-webkit-input-placeholder { color: #CDCDCD !important; }
+ input::-moz-input-placeholder { color: #CDCDCD !important; }
+ input::-ms-input-placeholder { color: #CDCDCD !important; }
+
+ // /* webkit专用 */
+ .input1::-webkit-input-placeholder { color:#00f; }
+ // #input2::-webkit-input-placeholder { color:#090; background:lightgreen; text-transform:uppercase; }
+ // #input3::-webkit-input-placeholder { font-style:italic; text-decoration:overline; color:#999; }
+
+ // /* mozilla专用 */
+ // #input1::-moz-placeholder { color:#00f; }
+ // #input2::-moz-placeholder { color:#090; background:lightgreen; text-transform:uppercase; }
+ // #input3::-moz-placeholder { font-style:italic; text-decoration:overline; color:#999; }
diff --git a/common/js/uniExport.js b/common/js/uniExport.js
new file mode 100644
index 0000000..9f30b6a
--- /dev/null
+++ b/common/js/uniExport.js
@@ -0,0 +1,8 @@
+
+export let goPage = (url, params={}, type='navigateTo')=> {
+ uni.$u.route({
+ url,
+ params,
+ type
+ })
+ }
\ No newline at end of file
diff --git a/common/js/utils.js b/common/js/utils.js
new file mode 100644
index 0000000..17ea3fd
--- /dev/null
+++ b/common/js/utils.js
@@ -0,0 +1,96 @@
+import store from '@/store';
+
+const install = (Vue, vm) => {
+
+ // 打开地图
+ const openMap = (lat, lng) => {
+ uni.openLocation({
+ latitude: lat,
+ longitude: lng
+ })
+ }
+
+ // 距离换算
+ const distanceFn = (val) => {
+ if (val * 1 < 1000) {
+ return val + '米'
+ } else {
+ return (val / 1000).toFixed(2) + '公里'
+ }
+ }
+ // 价格计算
+ const priceTo = (price = 0) => {
+ // return (price / 100).toFixed(2)
+ return (parseInt(price * 100) / 100 / 100).toFixed(2)
+
+ }
+
+ const distanceLatLng = (lat1, lng1) => {
+ var that = this;
+ let lat2 = store.state.latLng.lat;
+ let lng2 = store.state.latLng.lng;
+ let rad1 = lat1 * Math.PI / 180.0;
+ let rad2 = lat2 * Math.PI / 180.0;
+ let a = rad1 - rad2;
+ let b = lng1 * Math.PI / 180.0 - lng2 * Math.PI / 180.0;
+ let s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2) + Math.cos(rad1) *
+ Math.cos(
+ rad2) * Math.pow(
+ Math.sin(b / 2), 2)));
+ s = s * 6378.137;
+ s = Math.round(s * 10000) / 10000;
+ s = s.toString();
+ s = s.substring(0, s.indexOf('.') + 2);
+ return s
+
+ }
+
+ const getLocation = () => {
+ return new Promise((resolve, reject) => {
+ uni.getLocation({
+ type: 'wgs84',
+ success: function(res) {
+ console.log('当前位置的经度:' + res.longitude);
+ console.log('当前位置的纬度:' + res.latitude);
+ let obj = {
+ lat: res.latitude,
+ lng: res.longitude
+ }
+ store.commit('updateLatLng', obj)
+ resolve(obj)
+ }
+ });
+ }).catch((e) => {})
+ }
+
+
+
+
+ function addZeroPrefix(number) {
+ return number < 10 ? `0${number}` : number
+ }
+
+ let getDate = (date, splitor = '-') => {
+ const year = date.getFullYear()
+ const month = date.getMonth() + 1
+ const day = date.getDate()
+ return `${year}${splitor}${addZeroPrefix(month)}${splitor}${addZeroPrefix(day)}`
+ }
+
+
+
+
+
+ vm.$u.utils = {
+ openMap,
+ getLocation,
+ priceTo,
+ distanceLatLng,
+ distanceFn,
+ getDate,
+ }
+}
+
+export default {
+ install
+}
\ No newline at end of file
diff --git a/common/sdk/qqmap-wx-jssdk.js b/common/sdk/qqmap-wx-jssdk.js
new file mode 100644
index 0000000..b114e29
--- /dev/null
+++ b/common/sdk/qqmap-wx-jssdk.js
@@ -0,0 +1,741 @@
+/**
+ * 微信小程序JavaScriptSDK
+ *
+ * @version 1.1
+ * @date 2019-01-20
+ */
+
+var ERROR_CONF = {
+ KEY_ERR: 311,
+ KEY_ERR_MSG: 'key格式错误',
+ PARAM_ERR: 310,
+ PARAM_ERR_MSG: '请求参数信息有误',
+ SYSTEM_ERR: 600,
+ SYSTEM_ERR_MSG: '系统错误',
+ WX_ERR_CODE: 1000,
+ WX_OK_CODE: 200
+};
+var BASE_URL = 'https://apis.map.qq.com/ws/';
+var URL_SEARCH = BASE_URL + 'place/v1/search';
+var URL_SUGGESTION = BASE_URL + 'place/v1/suggestion';
+var URL_GET_GEOCODER = BASE_URL + 'geocoder/v1/';
+var URL_CITY_LIST = BASE_URL + 'district/v1/list';
+var URL_AREA_LIST = BASE_URL + 'district/v1/getchildren';
+var URL_DISTANCE = BASE_URL + 'distance/v1/';
+var EARTH_RADIUS = 6378136.49;
+var Utils = {
+ /**
+ * 得到终点query字符串
+ * @param {Array|String} 检索数据
+ */
+ location2query(data) {
+ if (typeof data == 'string') {
+ return data;
+ }
+ var query = '';
+ for (var i = 0; i < data.length; i++) {
+ var d = data[i];
+ if (!!query) {
+ query += ';';
+ }
+ if (d.location) {
+ query = query + d.location.lat + ',' + d.location.lng;
+ }
+ if (d.latitude && d.longitude) {
+ query = query + d.latitude + ',' + d.longitude;
+ }
+ }
+ return query;
+ },
+
+ /**
+ * 计算角度
+ */
+ rad(d) {
+ return d * Math.PI / 180.0;
+ },
+ /**
+ * 处理终点location数组
+ * @return 返回终点数组
+ */
+ getEndLocation(location){
+ var to = location.split(';');
+ var endLocation = [];
+ for (var i = 0; i < to.length; i++) {
+ endLocation.push({
+ lat: parseFloat(to[i].split(',')[0]),
+ lng: parseFloat(to[i].split(',')[1])
+ })
+ }
+ return endLocation;
+ },
+
+ /**
+ * 计算两点间直线距离
+ * @param a 表示纬度差
+ * @param b 表示经度差
+ * @return 返回的是距离,单位m
+ */
+ getDistance(latFrom, lngFrom, latTo, lngTo) {
+ var radLatFrom = this.rad(latFrom);
+ var radLatTo = this.rad(latTo);
+ var a = radLatFrom - radLatTo;
+ var b = this.rad(lngFrom) - this.rad(lngTo);
+ var distance = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2) + Math.cos(radLatFrom) * Math.cos(radLatTo) * Math.pow(Math.sin(b / 2), 2)));
+ distance = distance * EARTH_RADIUS;
+ distance = Math.round(distance * 10000) / 10000;
+ return parseFloat(distance.toFixed(0));
+ },
+ /**
+ * 使用微信接口进行定位
+ */
+ getWXLocation(success, fail, complete) {
+ wx.getLocation({
+ type: 'gcj02',
+ success: success,
+ fail: fail,
+ complete: complete
+ });
+ },
+
+ /**
+ * 获取location参数
+ */
+ getLocationParam(location) {
+ if (typeof location == 'string') {
+ var locationArr = location.split(',');
+ if (locationArr.length === 2) {
+ location = {
+ latitude: location.split(',')[0],
+ longitude: location.split(',')[1]
+ };
+ } else {
+ location = {};
+ }
+ }
+ return location;
+ },
+
+ /**
+ * 回调函数默认处理
+ */
+ polyfillParam(param) {
+ param.success = param.success || function () { };
+ param.fail = param.fail || function () { };
+ param.complete = param.complete || function () { };
+ },
+
+ /**
+ * 验证param对应的key值是否为空
+ *
+ * @param {Object} param 接口参数
+ * @param {String} key 对应参数的key
+ */
+ checkParamKeyEmpty(param, key) {
+ if (!param[key]) {
+ var errconf = this.buildErrorConfig(ERROR_CONF.PARAM_ERR, ERROR_CONF.PARAM_ERR_MSG + key +'参数格式有误');
+ param.fail(errconf);
+ param.complete(errconf);
+ return true;
+ }
+ return false;
+ },
+
+ /**
+ * 验证参数中是否存在检索词keyword
+ *
+ * @param {Object} param 接口参数
+ */
+ checkKeyword(param){
+ return !this.checkParamKeyEmpty(param, 'keyword');
+ },
+
+ /**
+ * 验证location值
+ *
+ * @param {Object} param 接口参数
+ */
+ checkLocation(param) {
+ var location = this.getLocationParam(param.location);
+ if (!location || !location.latitude || !location.longitude) {
+ var errconf = this.buildErrorConfig(ERROR_CONF.PARAM_ERR, ERROR_CONF.PARAM_ERR_MSG + ' location参数格式有误');
+ param.fail(errconf);
+ param.complete(errconf);
+ return false;
+ }
+ return true;
+ },
+
+ /**
+ * 构造错误数据结构
+ * @param {Number} errCode 错误码
+ * @param {Number} errMsg 错误描述
+ */
+ buildErrorConfig(errCode, errMsg) {
+ return {
+ status: errCode,
+ message: errMsg
+ };
+ },
+
+ /**
+ *
+ * 数据处理函数
+ * 根据传入参数不同处理不同数据
+ * @param {String} feature 功能名称
+ * search 地点搜索
+ * suggest关键词提示
+ * reverseGeocoder逆地址解析
+ * geocoder地址解析
+ * getCityList获取城市列表:父集
+ * getDistrictByCityId获取区县列表:子集
+ * calculateDistance距离计算
+ * @param {Object} param 接口参数
+ * @param {Object} data 数据
+ */
+ handleData(param,data,feature){
+ if (feature === 'search') {
+ var searchResult = data.data;
+ var searchSimplify = [];
+ for (var i = 0; i < searchResult.length; i++) {
+ searchSimplify.push({
+ id: searchResult[i].id || null,
+ title: searchResult[i].title || null,
+ latitude: searchResult[i].location && searchResult[i].location.lat || null,
+ longitude: searchResult[i].location && searchResult[i].location.lng || null,
+ address: searchResult[i].address || null,
+ category: searchResult[i].category || null,
+ tel: searchResult[i].tel || null,
+ adcode: searchResult[i].ad_info && searchResult[i].ad_info.adcode || null,
+ city: searchResult[i].ad_info && searchResult[i].ad_info.city || null,
+ district: searchResult[i].ad_info && searchResult[i].ad_info.district || null,
+ province: searchResult[i].ad_info && searchResult[i].ad_info.province || null
+ })
+ }
+ param.success(data, {
+ searchResult: searchResult,
+ searchSimplify: searchSimplify
+ })
+ } else if (feature === 'suggest') {
+ var suggestResult = data.data;
+ var suggestSimplify = [];
+ for (var i = 0; i < suggestResult.length; i++) {
+ suggestSimplify.push({
+ adcode: suggestResult[i].adcode || null,
+ address: suggestResult[i].address || null,
+ category: suggestResult[i].category || null,
+ city: suggestResult[i].city || null,
+ district: suggestResult[i].district || null,
+ id: suggestResult[i].id || null,
+ latitude: suggestResult[i].location && suggestResult[i].location.lat || null,
+ longitude: suggestResult[i].location && suggestResult[i].location.lng || null,
+ province: suggestResult[i].province || null,
+ title: suggestResult[i].title || null,
+ type: suggestResult[i].type || null
+ })
+ }
+ param.success(data, {
+ suggestResult: suggestResult,
+ suggestSimplify: suggestSimplify
+ })
+ } else if (feature === 'reverseGeocoder') {
+ var reverseGeocoderResult = data.result;
+ var reverseGeocoderSimplify = {
+ address: reverseGeocoderResult.address || null,
+ latitude: reverseGeocoderResult.location && reverseGeocoderResult.location.lat || null,
+ longitude: reverseGeocoderResult.location && reverseGeocoderResult.location.lng || null,
+ adcode: reverseGeocoderResult.ad_info && reverseGeocoderResult.ad_info.adcode || null,
+ city: reverseGeocoderResult.address_component && reverseGeocoderResult.address_component.city || null,
+ district: reverseGeocoderResult.address_component && reverseGeocoderResult.address_component.district || null,
+ nation: reverseGeocoderResult.address_component && reverseGeocoderResult.address_component.nation || null,
+ province: reverseGeocoderResult.address_component && reverseGeocoderResult.address_component.province || null,
+ street: reverseGeocoderResult.address_component && reverseGeocoderResult.address_component.street || null,
+ street_number: reverseGeocoderResult.address_component && reverseGeocoderResult.address_component.street_number || null,
+ recommend: reverseGeocoderResult.formatted_addresses && reverseGeocoderResult.formatted_addresses.recommend || null,
+ rough: reverseGeocoderResult.formatted_addresses && reverseGeocoderResult.formatted_addresses.rough || null
+ };
+ if (reverseGeocoderResult.pois) {//判断是否返回周边poi
+ var pois = reverseGeocoderResult.pois;
+ var poisSimplify = [];
+ for (var i = 0;i < pois.length;i++) {
+ poisSimplify.push({
+ id: pois[i].id || null,
+ title: pois[i].title || null,
+ latitude: pois[i].location && pois[i].location.lat || null,
+ longitude: pois[i].location && pois[i].location.lng || null,
+ address: pois[i].address || null,
+ category: pois[i].category || null,
+ adcode: pois[i].ad_info && pois[i].ad_info.adcode || null,
+ city: pois[i].ad_info && pois[i].ad_info.city || null,
+ district: pois[i].ad_info && pois[i].ad_info.district || null,
+ province: pois[i].ad_info && pois[i].ad_info.province || null
+ })
+ }
+ param.success(data,{
+ reverseGeocoderResult: reverseGeocoderResult,
+ reverseGeocoderSimplify: reverseGeocoderSimplify,
+ pois: pois,
+ poisSimplify: poisSimplify
+ })
+ } else {
+ param.success(data, {
+ reverseGeocoderResult: reverseGeocoderResult,
+ reverseGeocoderSimplify: reverseGeocoderSimplify
+ })
+ }
+ } else if (feature === 'geocoder') {
+ var geocoderResult = data.result;
+ var geocoderSimplify = {
+ title: geocoderResult.title || null,
+ latitude: geocoderResult.location && geocoderResult.location.lat || null,
+ longitude: geocoderResult.location && geocoderResult.location.lng || null,
+ adcode: geocoderResult.ad_info && geocoderResult.ad_info.adcode || null,
+ province: geocoderResult.address_components && geocoderResult.address_components.province || null,
+ city: geocoderResult.address_components && geocoderResult.address_components.city || null,
+ district: geocoderResult.address_components && geocoderResult.address_components.district || null,
+ street: geocoderResult.address_components && geocoderResult.address_components.street || null,
+ street_number: geocoderResult.address_components && geocoderResult.address_components.street_number || null,
+ level: geocoderResult.level || null
+ };
+ param.success(data,{
+ geocoderResult: geocoderResult,
+ geocoderSimplify: geocoderSimplify
+ });
+ } else if (feature === 'getCityList') {
+ var provinceResult = data.result[0];
+ var cityResult = data.result[1];
+ var districtResult = data.result[2];
+ param.success(data,{
+ provinceResult: provinceResult,
+ cityResult: cityResult,
+ districtResult: districtResult
+ });
+ } else if (feature === 'getDistrictByCityId') {
+ var districtByCity = data.result[0];
+ param.success(data, districtByCity);
+ } else if (feature === 'calculateDistance') {
+ var calculateDistanceResult = data.result.elements;
+ var distance = [];
+ for (var i = 0; i < calculateDistanceResult.length; i++){
+ distance.push(calculateDistanceResult[i].distance);
+ }
+ param.success(data, {
+ calculateDistanceResult: calculateDistanceResult,
+ distance: distance
+ });
+ } else {
+ param.success(data);
+ }
+ },
+
+ /**
+ * 构造微信请求参数,公共属性处理
+ *
+ * @param {Object} param 接口参数
+ * @param {Object} param 配置项
+ * @param {String} feature 方法名
+ */
+ buildWxRequestConfig(param, options, feature) {
+ var that = this;
+ options.header = { "content-type": "application/json" };
+ options.method = 'GET';
+ options.success = function (res) {
+ var data = res.data;
+ if (data.status === 0) {
+ that.handleData(param, data, feature);
+ } else {
+ param.fail(data);
+ }
+ };
+ options.fail = function (res) {
+ res.statusCode = ERROR_CONF.WX_ERR_CODE;
+ param.fail(that.buildErrorConfig(ERROR_CONF.WX_ERR_CODE, res.errMsg));
+ };
+ options.complete = function (res) {
+ var statusCode = +res.statusCode;
+ switch(statusCode) {
+ case ERROR_CONF.WX_ERR_CODE: {
+ param.complete(that.buildErrorConfig(ERROR_CONF.WX_ERR_CODE, res.errMsg));
+ break;
+ }
+ case ERROR_CONF.WX_OK_CODE: {
+ var data = res.data;
+ if (data.status === 0) {
+ param.complete(data);
+ } else {
+ param.complete(that.buildErrorConfig(data.status, data.message));
+ }
+ break;
+ }
+ default:{
+ param.complete(that.buildErrorConfig(ERROR_CONF.SYSTEM_ERR, ERROR_CONF.SYSTEM_ERR_MSG));
+ }
+
+ }
+ };
+ return options;
+ },
+
+ /**
+ * 处理用户参数是否传入坐标进行不同的处理
+ */
+ locationProcess(param, locationsuccess, locationfail, locationcomplete) {
+ var that = this;
+ locationfail = locationfail || function (res) {
+ res.statusCode = ERROR_CONF.WX_ERR_CODE;
+ param.fail(that.buildErrorConfig(ERROR_CONF.WX_ERR_CODE, res.errMsg));
+ };
+ locationcomplete = locationcomplete || function (res) {
+ if (res.statusCode == ERROR_CONF.WX_ERR_CODE) {
+ param.complete(that.buildErrorConfig(ERROR_CONF.WX_ERR_CODE, res.errMsg));
+ }
+ };
+ if (!param.location) {
+ that.getWXLocation(locationsuccess, locationfail, locationcomplete);
+ } else if (that.checkLocation(param)) {
+ var location = Utils.getLocationParam(param.location);
+ locationsuccess(location);
+ }
+ }
+};
+
+
+class QQMapWX {
+
+ /**
+ * 构造函数
+ *
+ * @param {Object} options 接口参数,key 为必选参数
+ */
+ constructor(options) {
+ if (!options.key) {
+ throw Error('key值不能为空');
+ }
+ this.key = options.key;
+ };
+
+ /**
+ * POI周边检索
+ *
+ * @param {Object} options 接口参数对象
+ *
+ * 参数对象结构可以参考
+ * @see http://lbs.qq.com/webservice_v1/guide-search.html
+ */
+ search(options) {
+ var that = this;
+ options = options || {};
+
+ Utils.polyfillParam(options);
+
+ if (!Utils.checkKeyword(options)) {
+ return;
+ }
+
+ var requestParam = {
+ keyword: options.keyword,
+ orderby: options.orderby || '_distance',
+ page_size: options.page_size || 10,
+ page_index: options.page_index || 1,
+ output: 'json',
+ key: that.key
+ };
+
+ if (options.address_format) {
+ requestParam.address_format = options.address_format;
+ }
+
+ if (options.filter) {
+ requestParam.filter = options.filter;
+ }
+
+ var distance = options.distance || "1000";
+ var auto_extend = options.auto_extend || 1;
+ var region = null;
+ var rectangle = null;
+
+ //判断城市限定参数
+ if (options.region) {
+ region = options.region;
+ }
+
+ //矩形限定坐标(暂时只支持字符串格式)
+ if (options.rectangle) {
+ rectangle = options.rectangle;
+ }
+
+ var locationsuccess = function (result) {
+ if (region && !rectangle) {
+ //城市限定参数拼接
+ requestParam.boundary = "region(" + region + "," + auto_extend + "," + result.latitude + "," + result.longitude + ")";
+ } else if (rectangle && !region) {
+ //矩形搜索
+ requestParam.boundary = "rectangle(" + rectangle + ")";
+ } else {
+ requestParam.boundary = "nearby(" + result.latitude + "," + result.longitude + "," + distance + "," + auto_extend + ")";
+ }
+ wx.request(Utils.buildWxRequestConfig(options, {
+ url: URL_SEARCH,
+ data: requestParam
+ }, 'search'));
+ };
+ Utils.locationProcess(options, locationsuccess);
+ };
+
+ /**
+ * sug模糊检索
+ *
+ * @param {Object} options 接口参数对象
+ *
+ * 参数对象结构可以参考
+ * http://lbs.qq.com/webservice_v1/guide-suggestion.html
+ */
+ getSuggestion(options) {
+ var that = this;
+ options = options || {};
+ Utils.polyfillParam(options);
+
+ if (!Utils.checkKeyword(options)) {
+ return;
+ }
+
+ var requestParam = {
+ keyword: options.keyword,
+ region: options.region || '全国',
+ region_fix: options.region_fix || 0,
+ policy: options.policy || 0,
+ page_size: options.page_size || 10,//控制显示条数
+ page_index: options.page_index || 1,//控制页数
+ get_subpois : options.get_subpois || 0,//返回子地点
+ output: 'json',
+ key: that.key
+ };
+ //长地址
+ if (options.address_format) {
+ requestParam.address_format = options.address_format;
+ }
+ //过滤
+ if (options.filter) {
+ requestParam.filter = options.filter;
+ }
+ //排序
+ if (options.location) {
+ var locationsuccess = function (result) {
+ requestParam.location = result.latitude + ',' + result.longitude;
+ wx.request(Utils.buildWxRequestConfig(options, {
+ url: URL_SUGGESTION,
+ data: requestParam
+ }, "suggest"));
+ };
+ Utils.locationProcess(options, locationsuccess);
+ } else {
+ wx.request(Utils.buildWxRequestConfig(options, {
+ url: URL_SUGGESTION,
+ data: requestParam
+ }, "suggest"));
+ }
+ };
+
+ /**
+ * 逆地址解析
+ *
+ * @param {Object} options 接口参数对象
+ *
+ * 请求参数结构可以参考
+ * http://lbs.qq.com/webservice_v1/guide-gcoder.html
+ */
+ reverseGeocoder(options) {
+ var that = this;
+ options = options || {};
+ Utils.polyfillParam(options);
+ var requestParam = {
+ coord_type: options.coord_type || 5,
+ get_poi: options.get_poi || 0,
+ output: 'json',
+ key: that.key
+ };
+ if (options.poi_options) {
+ requestParam.poi_options = options.poi_options
+ }
+
+ var locationsuccess = function (result) {
+ requestParam.location = result.latitude + ',' + result.longitude;
+ wx.request(Utils.buildWxRequestConfig(options, {
+ url: URL_GET_GEOCODER,
+ data: requestParam
+ }, 'reverseGeocoder'));
+ };
+ Utils.locationProcess(options, locationsuccess);
+ };
+
+ /**
+ * 地址解析
+ *
+ * @param {Object} options 接口参数对象
+ *
+ * 请求参数结构可以参考
+ * http://lbs.qq.com/webservice_v1/guide-geocoder.html
+ */
+ geocoder(options) {
+ var that = this;
+ options = options || {};
+ Utils.polyfillParam(options);
+
+ if (Utils.checkParamKeyEmpty(options, 'address')) {
+ return;
+ }
+
+ var requestParam = {
+ address: options.address,
+ output: 'json',
+ key: that.key
+ };
+
+ //城市限定
+ if (options.region) {
+ requestParam.region = options.region;
+ }
+
+ wx.request(Utils.buildWxRequestConfig(options, {
+ url: URL_GET_GEOCODER,
+ data: requestParam
+ },'geocoder'));
+ };
+
+
+ /**
+ * 获取城市列表
+ *
+ * @param {Object} options 接口参数对象
+ *
+ * 请求参数结构可以参考
+ * http://lbs.qq.com/webservice_v1/guide-region.html
+ */
+ getCityList(options) {
+ var that = this;
+ options = options || {};
+ Utils.polyfillParam(options);
+ var requestParam = {
+ output: 'json',
+ key: that.key
+ };
+
+ wx.request(Utils.buildWxRequestConfig(options, {
+ url: URL_CITY_LIST,
+ data: requestParam
+ },'getCityList'));
+ };
+
+ /**
+ * 获取对应城市ID的区县列表
+ *
+ * @param {Object} options 接口参数对象
+ *
+ * 请求参数结构可以参考
+ * http://lbs.qq.com/webservice_v1/guide-region.html
+ */
+ getDistrictByCityId(options) {
+ var that = this;
+ options = options || {};
+ Utils.polyfillParam(options);
+
+ if (Utils.checkParamKeyEmpty(options, 'id')) {
+ return;
+ }
+
+ var requestParam = {
+ id: options.id || '',
+ output: 'json',
+ key: that.key
+ };
+
+ wx.request(Utils.buildWxRequestConfig(options, {
+ url: URL_AREA_LIST,
+ data: requestParam
+ },'getDistrictByCityId'));
+ };
+
+ /**
+ * 用于单起点到多终点的路线距离(非直线距离)计算:
+ * 支持两种距离计算方式:步行和驾车。
+ * 起点到终点最大限制直线距离10公里。
+ *
+ * 新增直线距离计算。
+ *
+ * @param {Object} options 接口参数对象
+ *
+ * 请求参数结构可以参考
+ * http://lbs.qq.com/webservice_v1/guide-distance.html
+ */
+ calculateDistance(options) {
+ var that = this;
+ options = options || {};
+ Utils.polyfillParam(options);
+
+ if (Utils.checkParamKeyEmpty(options, 'to')) {
+ return;
+ }
+
+ var requestParam = {
+ mode: options.mode || 'walking',
+ to: Utils.location2query(options.to),
+ output: 'json',
+ key: that.key
+ };
+
+ if (options.from) {
+ options.location = options.from;
+ }
+
+ //计算直线距离
+ if(requestParam.mode == 'straight'){
+ var locationsuccess = function (result) {
+ var locationTo = Utils.getEndLocation(requestParam.to);//处理终点坐标
+ var data = {
+ message:"query ok",
+ result:{
+ elements:[]
+ },
+ status:0
+ };
+ for (var i = 0; i < locationTo.length; i++) {
+ data.result.elements.push({//将坐标存入
+ distance: Utils.getDistance(result.latitude, result.longitude, locationTo[i].lat, locationTo[i].lng),
+ duration:0,
+ from:{
+ lat: result.latitude,
+ lng:result.longitude
+ },
+ to:{
+ lat: locationTo[i].lat,
+ lng: locationTo[i].lng
+ }
+ });
+ }
+ var calculateResult = data.result.elements;
+ var distanceResult = [];
+ for (var i = 0; i < calculateResult.length; i++) {
+ distanceResult.push(calculateResult[i].distance);
+ }
+ return options.success(data,{
+ calculateResult: calculateResult,
+ distanceResult: distanceResult
+ });
+ };
+
+ Utils.locationProcess(options, locationsuccess);
+ } else {
+ var locationsuccess = function (result) {
+ requestParam.from = result.latitude + ',' + result.longitude;
+ wx.request(Utils.buildWxRequestConfig(options, {
+ url: URL_DISTANCE,
+ data: requestParam
+ },'calculateDistance'));
+ };
+
+ Utils.locationProcess(options, locationsuccess);
+ }
+ }
+};
+
+module.exports = QQMapWX;
\ No newline at end of file
diff --git a/common/sdk/qqmap-wx-jssdk.min.js b/common/sdk/qqmap-wx-jssdk.min.js
new file mode 100644
index 0000000..b8fbad4
--- /dev/null
+++ b/common/sdk/qqmap-wx-jssdk.min.js
@@ -0,0 +1,3 @@
+var ERROR_CONF={KEY_ERR:311,KEY_ERR_MSG:'key格式错误',PARAM_ERR:310,PARAM_ERR_MSG:'请求参数信息有误',SYSTEM_ERR:600,SYSTEM_ERR_MSG:'系统错误',WX_ERR_CODE:1000,WX_OK_CODE:200};var BASE_URL='https://apis.map.qq.com/ws/';var URL_SEARCH=BASE_URL+'place/v1/search';var URL_SUGGESTION=BASE_URL+'place/v1/suggestion';var URL_GET_GEOCODER=BASE_URL+'geocoder/v1/';var URL_CITY_LIST=BASE_URL+'district/v1/list';var URL_AREA_LIST=BASE_URL+'district/v1/getchildren';var URL_DISTANCE=BASE_URL+'distance/v1/';var EARTH_RADIUS=6378136.49;var Utils={location2query(data){if(typeof data=='string'){return data}var query='';for(var i=0;i
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/components/UserTab/UserTab.vue b/components/UserTab/UserTab.vue
new file mode 100644
index 0000000..5de086a
--- /dev/null
+++ b/components/UserTab/UserTab.vue
@@ -0,0 +1,117 @@
+
+
+
+
+ {{item.text}}
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/components/cancelReservation/cancelReservation.vue b/components/cancelReservation/cancelReservation.vue
new file mode 100644
index 0000000..c769b6e
--- /dev/null
+++ b/components/cancelReservation/cancelReservation.vue
@@ -0,0 +1,65 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/components/commentItem/commentItem.vue b/components/commentItem/commentItem.vue
new file mode 100644
index 0000000..23f7f6c
--- /dev/null
+++ b/components/commentItem/commentItem.vue
@@ -0,0 +1,59 @@
+
+
+
+ 匿名用户
+ 2023/08/08
+
+
+
+ 4.9分
+
+ 教学质量高,技术好,超有耐心,有责任心,学车就找这个驾校,教练都超好,满意满意满意
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/components/moreRight/moreRight.vue b/components/moreRight/moreRight.vue
new file mode 100644
index 0000000..f3c0d3a
--- /dev/null
+++ b/components/moreRight/moreRight.vue
@@ -0,0 +1,24 @@
+
+
+ {{text}}
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/components/pozCard/pozCard.vue b/components/pozCard/pozCard.vue
new file mode 100644
index 0000000..834cb0f
--- /dev/null
+++ b/components/pozCard/pozCard.vue
@@ -0,0 +1,59 @@
+
+
+
+
+ 江西省江西市江西区某某镇尚坤丁兰国际1190号820
+ 距您100km
+
+
+
+
+
+ 地图导航
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/components/privacyPopup/privacyPopup.vue b/components/privacyPopup/privacyPopup.vue
new file mode 100644
index 0000000..fefd57e
--- /dev/null
+++ b/components/privacyPopup/privacyPopup.vue
@@ -0,0 +1,78 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/components/privacyRadion/privacyRadion.vue b/components/privacyRadion/privacyRadion.vue
new file mode 100644
index 0000000..dd065f0
--- /dev/null
+++ b/components/privacyRadion/privacyRadion.vue
@@ -0,0 +1,35 @@
+
+
+
+
+
+
+ 《用户协议》和 《隐私协议》
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/components/searchRow/searchRow.vue b/components/searchRow/searchRow.vue
new file mode 100644
index 0000000..782ae74
--- /dev/null
+++ b/components/searchRow/searchRow.vue
@@ -0,0 +1,51 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/components/topNavbar/topNavbar.vue b/components/topNavbar/topNavbar.vue
new file mode 100644
index 0000000..ca3dcef
--- /dev/null
+++ b/components/topNavbar/topNavbar.vue
@@ -0,0 +1,27 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/config/api.js b/config/api.js
new file mode 100644
index 0000000..e1cc984
--- /dev/null
+++ b/config/api.js
@@ -0,0 +1,10 @@
+
+
+const http = uni.$u.http
+
+// 隐私政策
+export const getAgreement = (params, config = {}) => http.post('/util/manage/getAgreement.do', params, config)
+// 验证码登录
+export const loginSMS = (data) => http.post('/account/manage/login.do', data)
+// 登录发验证码
+export const getLoginCode = (data) => http.post('/util/manage/getLoginRegistCode.do', data)
diff --git a/config/request.js b/config/request.js
new file mode 100644
index 0000000..9e7c0a2
--- /dev/null
+++ b/config/request.js
@@ -0,0 +1,52 @@
+
+// 此vm参数为页面的实例,可以通过它引用vuex中的变量
+module.exports = (vm) => {
+ // 初始化请求配置
+ uni.$u.http.setConfig((config) => {
+ /* config 为默认全局配置*/
+ config.baseURL = 'http://121.41.97.244:8090'; /* 根域名 */
+ config.header['content-type'] = 'application/x-www-form-urlencoded; charset=UTF-8'
+ return config
+ })
+
+ // 请求拦截
+ uni.$u.http.interceptors.request.use((config) => { // 可使用async await 做异步操作
+ // 初始化请求拦截器时,会执行此方法,此时data为undefined,赋予默认{}
+ config.data = config.data || {}
+ // 根据custom参数中配置的是否需要token,添加对应的请求头
+ if(config?.custom?.auth) {
+ // 可以在此通过vm引用vuex中的变量,具体值在vm.$store.state中
+ config.header.token = vm.$store.state.userInfo.token
+ }
+ return config
+ }, config => { // 可使用async await 做异步操作
+ return Promise.reject(config)
+ })
+
+ // 响应拦截
+ uni.$u.http.interceptors.response.use((response) => { /* 对响应成功做点什么 可使用async await 做异步操作*/
+ const data = response.data
+ console.log('response')
+ console.log(data)
+ // 自定义参数
+ const custom = response.config?.custom
+ if (data.code !== 0) {
+ // 如果没有显式定义custom的toast参数为false的话,默认对报错进行toast弹出提示
+ if (custom.toast !== false) {
+ uni.$u.toast(data.message)
+ }
+
+ // 如果需要catch返回,则进行reject
+ if (custom?.catch) {
+ return Promise.reject(data)
+ } else {
+ // 否则返回一个pending中的promise,请求不会进入catch中
+ return new Promise(() => { })
+ }
+ }
+ return data === undefined ? {} : data
+ }, (response) => {
+ // 对响应错误做点什么 (statusCode !== 200)
+ return Promise.reject(response)
+ })
+}
\ No newline at end of file
diff --git a/index.html b/index.html
new file mode 100644
index 0000000..c3ff205
--- /dev/null
+++ b/index.html
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/main.js b/main.js
new file mode 100644
index 0000000..6a6f945
--- /dev/null
+++ b/main.js
@@ -0,0 +1,35 @@
+import App from './App'
+import Vue from 'vue'
+import store from './store';
+
+import { goPage } from './common/js/uniExport.js'
+Vue.prototype.$goPage = goPage;
+
+import './uni.promisify.adaptor'
+Vue.config.productionTip = false
+App.mpType = 'app'
+
+// main.js,注意要在use方法之后执行
+import uView from '@/uni_modules/uview-ui'
+Vue.use(uView)
+
+import tabBar from "components/UserTab/UserTab.vue"
+Vue.component('tabBar',tabBar)
+
+const app = new Vue({
+ ...App,
+ store
+})
+
+require('./config/request.js')(app)
+
+
+import utils from "@/common/js/utils.js"
+console.log(utils)
+// 自定义工具
+
+Vue.use(utils,app)
+
+app.$mount()
+
+
diff --git a/manifest.json b/manifest.json
new file mode 100644
index 0000000..72ac63f
--- /dev/null
+++ b/manifest.json
@@ -0,0 +1,100 @@
+{
+ "name" : "recruitStudent",
+ "appid" : "__UNI__BD23957",
+ "description" : "",
+ "versionName" : "1.0.0",
+ "versionCode" : "100",
+ "transformPx" : false,
+ /* 5+App特有相关 */
+ "app-plus" : {
+ "usingComponents" : true,
+ "nvueStyleCompiler" : "uni-app",
+ "compilerVersion" : 3,
+ "splashscreen" : {
+ "alwaysShowBeforeRender" : true,
+ "waiting" : true,
+ "autoclose" : true,
+ "delay" : 0
+ },
+ /* 模块配置 */
+ "modules" : {},
+ /* 应用发布信息 */
+ "distribute" : {
+ /* android打包配置 */
+ "android" : {
+ "permissions" : [
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ ""
+ ]
+ },
+ /* ios打包配置 */
+ "ios" : {},
+ /* SDK配置 */
+ "sdkConfigs" : {}
+ }
+ },
+ /* 快应用特有相关 */
+ "quickapp" : {},
+ /* 小程序特有相关 */
+ "mp-weixin" : {
+ "appid" : "wx2d71605af3b620e6",
+ "setting" : {
+ "urlCheck" : false,
+ "es6" : true
+ },
+ "usingComponents" : true,
+ "permission" : {
+ "scope.userLocation" : {
+ "desc" : "查询用户地理位置,推荐本地驾校,提高用户服务"
+ }
+ }
+ },
+ "mp-alipay" : {
+ "usingComponents" : true
+ },
+ "mp-baidu" : {
+ "usingComponents" : true
+ },
+ "mp-toutiao" : {
+ "usingComponents" : true
+ },
+ "uniStatistics" : {
+ "enable" : false
+ },
+ "vueVersion" : "2",
+ "h5" : {
+ "devServer" : {
+ "port" : 8000,
+ "disableHostCheck" : true,
+ "proxy" : {
+ "/api" : {
+ "target" : "http://121.41.97.244:8090",
+ "changeOrigin" : true,
+ "secure" : true,
+ "pathRewrite" : {
+ //使用代理; 告诉他你这个连接要用代理
+ "^/api" : ""
+ }
+ }
+ },
+ "https" : false
+ },
+ "router" : {
+ "mode" : "hash",
+ "base" : "/h5"
+ }
+ }
+}
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..6b8150f
--- /dev/null
+++ b/package.json
@@ -0,0 +1,15 @@
+{
+ "name": "recruitStudent",
+ "version": "1.0.0",
+ "description": "",
+ "main": "main.js",
+ "scripts": {
+ "test": "echo \"Error: no test specified\" && exit 1"
+ },
+ "keywords": [],
+ "author": "",
+ "license": "ISC",
+ "dependencies": {
+ "uview-ui": "^2.0.36"
+ }
+}
diff --git a/pages.json b/pages.json
new file mode 100644
index 0000000..f50713e
--- /dev/null
+++ b/pages.json
@@ -0,0 +1,153 @@
+{
+ "pages": [
+ {
+ "path": "pages/tabbar/statistics/index",
+ "style": {
+ "navigationBarTitleText": "首页",
+ "navigationStyle": "custom",
+ "enablePullDownRefresh": true,
+ "backgroundTextStyle": "dark"
+ }
+ },
+ {
+ "path": "pages/tabbar/examSimulation/index",
+ "style": {
+ "navigationBarTitleText": "考场模拟",
+ "navigationStyle": "custom",
+ "enablePullDownRefresh": true,
+ "backgroundTextStyle": "dark"
+ }
+ },
+ {
+ "path": "pages/tabbar/operateTrain/index",
+ "style": {
+ "navigationBarTitleText": "实操训练",
+ "navigationStyle": "custom",
+ "enablePullDownRefresh": true,
+ "backgroundTextStyle": "dark"
+ }
+ },
+
+ {
+ "path": "pages/tabbar/mine/index",
+ "style": {
+ "navigationBarTitleText": "我的",
+ "navigationStyle": "custom",
+ "enablePullDownRefresh": true,
+ "backgroundTextStyle": "dark"
+ }
+ }
+ ],
+ "subPackages": [
+ {
+ "root": "pages/userCenter",
+ "pages": [
+ {
+ "path": "login/login",
+ "style": {
+ "navigationBarTitleText": "登录",
+ "navigationStyle": "custom",
+ "enablePullDownRefresh": false,
+ "backgroundTextStyle": "dark"
+ }
+ },
+ {
+ "path": "login/loginByPhone",
+ "style": {
+ "navigationBarTitleText": "手机号登录",
+ "navigationStyle": "custom",
+ "enablePullDownRefresh": false,
+ "backgroundTextStyle": "dark"
+ }
+ }
+ ]
+ },
+ {
+ "root": "pages/indexEntry",
+ "pages": [
+ {
+ "path": "settlement/settlement",
+ "style": {
+ "navigationBarTitleText": "",
+ "navigationStyle": "custom",
+ "enablePullDownRefresh": false,
+ "backgroundTextStyle": "dark"
+ }
+ },
+ {
+ "path": "settlement/detail/detail",
+ "style": {
+ "navigationBarTitleText": "",
+ "navigationStyle": "custom",
+ "enablePullDownRefresh": false,
+ "backgroundTextStyle": "dark"
+ }
+ }
+ ]
+ },
+ {
+ "root": "pages/other",
+ "pages": [
+ {
+ "path": "webView/webView",
+ "style": {
+ "navigationBarTitleText": "",
+ "navigationStyle": "custom",
+ "enablePullDownRefresh": false,
+ "backgroundTextStyle": "dark"
+ }
+ }
+ ]
+ }
+ ],
+ "globalStyle": {
+ "navigationBarTextStyle": "black",
+ "navigationBarTitleText": "学车小程序",
+ "navigationBarBackgroundColor": "#F8F8F8",
+ "backgroundColor": "#F8F8F8"
+ },
+ "uniIdRouter": {},
+ "tabBar": {
+ "color": "#999999",
+ "selectedColor": "#218DFF",
+ "backgroundColor": "#FFFFFF",
+ "list": [{
+ "pagePath": "pages/tabbar/statistics/index",
+ "text": "首页",
+ "iconPath": "static/images/tabbar/tj.png",
+ "selectedIconPath": "static/images/tabbar/tjActive.png"
+ },
+ {
+ "pagePath": "pages/tabbar/examSimulation/index",
+ "text": "考场模拟",
+ "iconPath": "static/images/tabbar/kc.png",
+ "selectedIconPath": "static/images/tabbar/kcActive.png"
+ },
+ {
+ "pagePath": "pages/tabbar/operateTrain/index",
+ "text": "实操训练",
+ "iconPath": "static/images/tabbar/sc.png",
+ "selectedIconPath": "static/images/tabbar/scActive.png"
+ },
+ {
+ "pagePath": "pages/tabbar/mine/index",
+ "text": "我的",
+ "iconPath": "static/images/tabbar/wd.png",
+ "selectedIconPath": "static/images/tabbar/wdActive.png"
+ }
+ ]
+ },
+ "easycom": {
+ "^u-(.*)": "@/uni_modules/uview-ui/components/u-$1/u-$1.vue"
+ },
+ "condition" : { //模式配置,仅开发期间生效
+ "current": 0, //当前激活的模式(list 的索引项)
+ "list": [
+ {
+ "name": "", //模式名称
+ "path": "", //启动页面,必选
+ "query": "" //启动参数,在页面的onLoad函数里面得到
+ }
+ ]
+ }
+}
diff --git a/pages/indexEntry/settlement/detail/detail.vue b/pages/indexEntry/settlement/detail/detail.vue
new file mode 100644
index 0000000..4b3303f
--- /dev/null
+++ b/pages/indexEntry/settlement/detail/detail.vue
@@ -0,0 +1,120 @@
+
+
+
+
+
+
+ 张三三
+ 第二阶段
+
+ +
+ ¥12256.33
+
+
+
+ 学员确认
+
+
+
+ 2023/08/08 10:55:21
+
+
+ 教练确认
+
+
+
+ 2023/08/08 10:55:21
+
+
+ 驾校确认
+
+
+
+ 2023/08/08 10:55:21
+
+
+
+
+ 学员手机号
+ 182671031657
+
+
+ 到账时间
+ 2023/08/08 10:55:21
+
+
+ 返款类型
+ 三方确认
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/indexEntry/settlement/settlement.vue b/pages/indexEntry/settlement/settlement.vue
new file mode 100644
index 0000000..492abb4
--- /dev/null
+++ b/pages/indexEntry/settlement/settlement.vue
@@ -0,0 +1,264 @@
+
+
+
+
+
+
+
+
+
+ {{ item.text }}
+
+
+
+
+
+
+ {{ selectDate }}
+
+
+
+
+ 结算金额共计
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/other/webView/webView.vue b/pages/other/webView/webView.vue
new file mode 100644
index 0000000..61d9919
--- /dev/null
+++ b/pages/other/webView/webView.vue
@@ -0,0 +1,27 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/pages/tabbar/examSimulation/index.vue b/pages/tabbar/examSimulation/index.vue
new file mode 100644
index 0000000..c7a7b86
--- /dev/null
+++ b/pages/tabbar/examSimulation/index.vue
@@ -0,0 +1,30 @@
+
+
+ 考场模拟
+
+
+
+
+
+
+
diff --git a/pages/tabbar/mine/index.vue b/pages/tabbar/mine/index.vue
new file mode 100644
index 0000000..05d501f
--- /dev/null
+++ b/pages/tabbar/mine/index.vue
@@ -0,0 +1,31 @@
+
+
+ 我的
+
+
+
+
+
+
+
diff --git a/pages/tabbar/operateTrain/index.vue b/pages/tabbar/operateTrain/index.vue
new file mode 100644
index 0000000..67ba00f
--- /dev/null
+++ b/pages/tabbar/operateTrain/index.vue
@@ -0,0 +1,31 @@
+
+
+ 实操训练
+
+
+
+
+
+
+
diff --git a/pages/tabbar/statistics/comp/stage.vue b/pages/tabbar/statistics/comp/stage.vue
new file mode 100644
index 0000000..e778894
--- /dev/null
+++ b/pages/tabbar/statistics/comp/stage.vue
@@ -0,0 +1,51 @@
+
+
+
+ 张三三
+ +¥1,130.86
+
+
+ 第一阶段
+ 2023/08/08 10:55:21
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/tabbar/statistics/index.vue b/pages/tabbar/statistics/index.vue
new file mode 100644
index 0000000..dfb13df
--- /dev/null
+++ b/pages/tabbar/statistics/index.vue
@@ -0,0 +1,205 @@
+
+
+
+ Hi,大乔教练
+
+
+
+
+ 翔力驾校
+ 合作教练
+
+
+
+ 今日已结算金额
+ ¥36333.66
+
+ 截止:2023/08/08 11:00:00
+
+ 刷新
+
+
+
+
+
+
+
+ 结算统计
+
+ 按日
+ 按月
+ 按年
+ 自定义日期
+
+
+
+ 图表到时候一起调
+
+
+
+ 结算明细
+
+
+
+
+
+
+
+ 查看更多
+
+
+
+
+
+
+
diff --git a/pages/userCenter/login/login.vue b/pages/userCenter/login/login.vue
new file mode 100644
index 0000000..ea765d1
--- /dev/null
+++ b/pages/userCenter/login/login.vue
@@ -0,0 +1,71 @@
+
+
+ 登录方式
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/userCenter/login/loginByPhone.vue b/pages/userCenter/login/loginByPhone.vue
new file mode 100644
index 0000000..b700bce
--- /dev/null
+++ b/pages/userCenter/login/loginByPhone.vue
@@ -0,0 +1,187 @@
+
+
+
+
+
+
+
+ 短信验证码登录
+
+
+
+ +
+ 86
+
+
+
+
+
+
+
+
+
+
+
+
+ {{codeText}}
+
+ 登 录
+
+
+
+
+
+ 《用户协议》和 《隐私协议》
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/project.config.json b/project.config.json
new file mode 100644
index 0000000..fa74469
--- /dev/null
+++ b/project.config.json
@@ -0,0 +1,28 @@
+{
+ "appid": "wx0820ae1a0b635ae2",
+ "compileType": "miniprogram",
+ "libVersion": "2.32.2",
+ "packOptions": {
+ "ignore": [],
+ "include": []
+ },
+ "setting": {
+ "coverView": true,
+ "es6": true,
+ "postcss": true,
+ "minified": true,
+ "enhance": true,
+ "showShadowRootInWxmlPanel": true,
+ "packNpmRelationList": [],
+ "babelSetting": {
+ "ignore": [],
+ "disablePlugins": [],
+ "outputPath": ""
+ }
+ },
+ "condition": {},
+ "editorSetting": {
+ "tabIndent": "insertSpaces",
+ "tabSize": 2
+ }
+}
\ No newline at end of file
diff --git a/project.private.config.json b/project.private.config.json
new file mode 100644
index 0000000..c4be9c3
--- /dev/null
+++ b/project.private.config.json
@@ -0,0 +1,7 @@
+{
+ "description": "项目私有配置文件。此文件中的内容将覆盖 project.config.json 中的相同字段。项目的改动优先同步到此文件中。详见文档:https://developers.weixin.qq.com/miniprogram/dev/devtools/projectconfig.html",
+ "projectname": "recruitStudent",
+ "setting": {
+ "compileHotReLoad": true
+ }
+}
\ No newline at end of file
diff --git a/site.config.js b/site.config.js
new file mode 100644
index 0000000..e2bc6da
--- /dev/null
+++ b/site.config.js
@@ -0,0 +1,12 @@
+const VUE_APP_PLATFORM = process.env.VUE_APP_PLATFORM;
+module.exports = {
+ APP_API: VUE_APP_PLATFORM === 'h5' ? 'http://121.41.97.244:8090' : '',
+ APP_HOST: VUE_APP_PLATFORM === 'h5' ? '' : 'https://www.jaxc.cn/api',
+ TEMP_HOST: VUE_APP_PLATFORM === 'h5' ? '' : 'http://121.41.97.244:8090 https://www.jaxc.cn/api',
+ ADD_API: VUE_APP_PLATFORM === 'h5' ? '/addApi': 'http://121.41.97.244:48084', //http://121.41.97.244:48084
+ APP_NAME: '',
+ VERSION: '1.0.0',
+ gaodeMapUrl: 'https://webapi.amap.com/maps?v=1.4.15&key=4545202996c625152b7f2c1aa0ffb8ea&plugin=AMap.DistrictSearch,AMap.CustomLayer,AMap.MarkerClusterer',
+ locationIcon: 'http://3dtest.hzhuishi.cn/images/location.png',
+ AThreeFace : true, //是否启用人脸识别
+};
diff --git a/static/images/bigImg/indexTopBanner.png b/static/images/bigImg/indexTopBanner.png
new file mode 100644
index 0000000..fa29ac7
Binary files /dev/null and b/static/images/bigImg/indexTopBanner.png differ
diff --git a/static/images/bigImg/topPageBg.png b/static/images/bigImg/topPageBg.png
new file mode 100644
index 0000000..b722040
Binary files /dev/null and b/static/images/bigImg/topPageBg.png differ
diff --git a/static/images/index/ic_jiaxiao.png b/static/images/index/ic_jiaxiao.png
new file mode 100644
index 0000000..51fa9e0
Binary files /dev/null and b/static/images/index/ic_jiaxiao.png differ
diff --git a/static/images/index/ic_shuaxin.png b/static/images/index/ic_shuaxin.png
new file mode 100644
index 0000000..2f8d3a4
Binary files /dev/null and b/static/images/index/ic_shuaxin.png differ
diff --git a/static/images/index/radio_cli.png b/static/images/index/radio_cli.png
new file mode 100644
index 0000000..6fc8118
Binary files /dev/null and b/static/images/index/radio_cli.png differ
diff --git a/static/images/index/radio_nor.png b/static/images/index/radio_nor.png
new file mode 100644
index 0000000..e935b17
Binary files /dev/null and b/static/images/index/radio_nor.png differ
diff --git a/static/images/index/searchIcon.png b/static/images/index/searchIcon.png
new file mode 100644
index 0000000..9337fb1
Binary files /dev/null and b/static/images/index/searchIcon.png differ
diff --git a/static/images/index/searchIconHui.png b/static/images/index/searchIconHui.png
new file mode 100644
index 0000000..159a4c7
Binary files /dev/null and b/static/images/index/searchIconHui.png differ
diff --git a/static/images/logo.png b/static/images/logo.png
new file mode 100644
index 0000000..415dc98
Binary files /dev/null and b/static/images/logo.png differ
diff --git a/static/images/tabbar/btn_xueche_cli.png b/static/images/tabbar/btn_xueche_cli.png
new file mode 100644
index 0000000..566ec2d
Binary files /dev/null and b/static/images/tabbar/btn_xueche_cli.png differ
diff --git a/static/images/tabbar/btn_xueche_nor.png b/static/images/tabbar/btn_xueche_nor.png
new file mode 100644
index 0000000..5c29319
Binary files /dev/null and b/static/images/tabbar/btn_xueche_nor.png differ
diff --git a/static/images/tabbar/kc.png b/static/images/tabbar/kc.png
new file mode 100644
index 0000000..4f6a817
Binary files /dev/null and b/static/images/tabbar/kc.png differ
diff --git a/static/images/tabbar/kcActive.png b/static/images/tabbar/kcActive.png
new file mode 100644
index 0000000..ba0cf25
Binary files /dev/null and b/static/images/tabbar/kcActive.png differ
diff --git a/static/images/tabbar/sc.png b/static/images/tabbar/sc.png
new file mode 100644
index 0000000..9c48191
Binary files /dev/null and b/static/images/tabbar/sc.png differ
diff --git a/static/images/tabbar/scActive.png b/static/images/tabbar/scActive.png
new file mode 100644
index 0000000..5e98f5e
Binary files /dev/null and b/static/images/tabbar/scActive.png differ
diff --git a/static/images/tabbar/sy.png b/static/images/tabbar/sy.png
new file mode 100644
index 0000000..7e7561b
Binary files /dev/null and b/static/images/tabbar/sy.png differ
diff --git a/static/images/tabbar/syActive.png b/static/images/tabbar/syActive.png
new file mode 100644
index 0000000..417e492
Binary files /dev/null and b/static/images/tabbar/syActive.png differ
diff --git a/static/images/tabbar/tj.png b/static/images/tabbar/tj.png
new file mode 100644
index 0000000..036469e
Binary files /dev/null and b/static/images/tabbar/tj.png differ
diff --git a/static/images/tabbar/tjActive.png b/static/images/tabbar/tjActive.png
new file mode 100644
index 0000000..dd9729a
Binary files /dev/null and b/static/images/tabbar/tjActive.png differ
diff --git a/static/images/tabbar/tk.png b/static/images/tabbar/tk.png
new file mode 100644
index 0000000..5d35ee7
Binary files /dev/null and b/static/images/tabbar/tk.png differ
diff --git a/static/images/tabbar/tkActive.png b/static/images/tabbar/tkActive.png
new file mode 100644
index 0000000..8a93d5b
Binary files /dev/null and b/static/images/tabbar/tkActive.png differ
diff --git a/static/images/tabbar/wd.png b/static/images/tabbar/wd.png
new file mode 100644
index 0000000..23fae10
Binary files /dev/null and b/static/images/tabbar/wd.png differ
diff --git a/static/images/tabbar/wdActive.png b/static/images/tabbar/wdActive.png
new file mode 100644
index 0000000..869e7eb
Binary files /dev/null and b/static/images/tabbar/wdActive.png differ
diff --git a/static/images/tabbar/xy.png b/static/images/tabbar/xy.png
new file mode 100644
index 0000000..1a0b9d9
Binary files /dev/null and b/static/images/tabbar/xy.png differ
diff --git a/static/images/tabbar/xyActive.png b/static/images/tabbar/xyActive.png
new file mode 100644
index 0000000..0e3ba9d
Binary files /dev/null and b/static/images/tabbar/xyActive.png differ
diff --git a/static/images/tabbar/zx.png b/static/images/tabbar/zx.png
new file mode 100644
index 0000000..3b10903
Binary files /dev/null and b/static/images/tabbar/zx.png differ
diff --git a/static/images/tabbar/zxActive.png b/static/images/tabbar/zxActive.png
new file mode 100644
index 0000000..b266dd6
Binary files /dev/null and b/static/images/tabbar/zxActive.png differ
diff --git a/static/images/userCenter/loginTopBg.png b/static/images/userCenter/loginTopBg.png
new file mode 100644
index 0000000..1086c92
Binary files /dev/null and b/static/images/userCenter/loginTopBg.png differ
diff --git a/static/images/userCenter/title_1.png b/static/images/userCenter/title_1.png
new file mode 100644
index 0000000..4e43a56
Binary files /dev/null and b/static/images/userCenter/title_1.png differ
diff --git a/static/images/登录流程切图/__MACOSX/登录流程切图/._.DS_Store b/static/images/登录流程切图/__MACOSX/登录流程切图/._.DS_Store
new file mode 100644
index 0000000..a5b28df
Binary files /dev/null and b/static/images/登录流程切图/__MACOSX/登录流程切图/._.DS_Store differ
diff --git a/static/images/登录流程切图/__MACOSX/登录流程切图/._btn_1.png b/static/images/登录流程切图/__MACOSX/登录流程切图/._btn_1.png
new file mode 100644
index 0000000..9d0ad85
Binary files /dev/null and b/static/images/登录流程切图/__MACOSX/登录流程切图/._btn_1.png differ
diff --git a/static/images/登录流程切图/登录流程切图/.DS_Store b/static/images/登录流程切图/登录流程切图/.DS_Store
new file mode 100644
index 0000000..49f0b45
Binary files /dev/null and b/static/images/登录流程切图/登录流程切图/.DS_Store differ
diff --git a/static/images/登录流程切图/登录流程切图/bg_1.png b/static/images/登录流程切图/登录流程切图/bg_1.png
new file mode 100644
index 0000000..1086c92
Binary files /dev/null and b/static/images/登录流程切图/登录流程切图/bg_1.png differ
diff --git a/static/images/登录流程切图/登录流程切图/btn_1.png b/static/images/登录流程切图/登录流程切图/btn_1.png
new file mode 100644
index 0000000..fdbfd5d
Binary files /dev/null and b/static/images/登录流程切图/登录流程切图/btn_1.png differ
diff --git a/static/images/登录流程切图/登录流程切图/btn_2.png b/static/images/登录流程切图/登录流程切图/btn_2.png
new file mode 100644
index 0000000..d5c36ea
Binary files /dev/null and b/static/images/登录流程切图/登录流程切图/btn_2.png differ
diff --git a/static/images/登录流程切图/登录流程切图/title_1.png b/static/images/登录流程切图/登录流程切图/title_1.png
new file mode 100644
index 0000000..4e43a56
Binary files /dev/null and b/static/images/登录流程切图/登录流程切图/title_1.png differ
diff --git a/static/logo.png b/static/logo.png
new file mode 100644
index 0000000..b5771e2
Binary files /dev/null and b/static/logo.png differ
diff --git a/store/getters.js b/store/getters.js
new file mode 100644
index 0000000..5310063
--- /dev/null
+++ b/store/getters.js
@@ -0,0 +1,21 @@
+// export default {
+// userInfo: state => state.user.userInfo,
+// pushMessage: state => state.push.pushMessage,
+// currentAdd: state=>{
+// };
+
+export default {
+ pushMessage: state => state.push.pushMessage,
+ getCurrentAdd: function (state) {
+ //返回一个函数用于接收
+ return function (id) {
+ let add = state.add.addList.find(item => item.id == id)
+ if(add) {
+ return add
+ }else {
+ return {}
+ }
+ }
+ }
+};
+
diff --git a/store/index.js b/store/index.js
new file mode 100644
index 0000000..061f5dc
--- /dev/null
+++ b/store/index.js
@@ -0,0 +1,90 @@
+import Vue from 'vue';
+import Vuex from 'vuex';
+import add from './modules/add';
+import user from './modules/user';
+import getters from './getters';
+
+Vue.use(Vuex);
+
+const store = new Vuex.Store({
+ state: {
+ currentSchool: '',
+ userInfo: {},
+ latLng: {},
+
+ classChooseItem: {},
+ pdfUrl: '',
+ webViewUrl: '',
+ havePay: 0, //tabbar 页面是否显示报错小图标
+ currentMyMsg: {},
+ billPrice: 0, //开发票的id
+ TrainingOrderId: '', //退款流程里的驾校id
+ bankInfo: {
+ realName: uni.getStorageSync('userInfo').realName,
+ phoneCode: ''
+ },
+ chooseCoachItem: {
+ coachId: ''
+ }, //报名时选择的教练
+ realAuthsuccee: false,
+
+ },
+ getters,
+ mutations: {
+ // 选择学校
+ upDateTrainingSchoolId(state, currentSchool) {
+ state.currentSchool = currentSchool
+ },
+ // webViewUrl
+ updateWebVeiwUrl(state, url) {
+ state.webViewUrl = url
+ },
+ // 更新用户信息
+ upDateUserInfo(state, userInfo) {
+ state.userInfo = userInfo
+ },
+ updatePushMyMsg(state, item) {
+ state.currentMyMsg = item
+ },
+ upDateBillPrice(state, billPrice) {
+ state.billPrice = billPrice
+ },
+ upDateTrainingOrderId(state, trainingOrderId) {
+ state.trainingOrderId = trainingOrderId
+ },
+ // tabbar 页面是否显示报错小图标
+ updateHavePay(state, havePay) {
+ state.havePay = havePay
+ },
+ // 报名时选择教练
+ upDateCoachItem(state, item) {
+ state.chooseCoachItem = item
+ },
+ // 申请退款时的银行卡信息
+ upDateBankInfo(state, obj) {
+ for (let k in obj) {
+ if (state.bankInfo[k]) {
+ state.bankInfo[k] = obj[k]
+ } else {
+ uni.$set(state.bankInfo, k, obj[k])
+ }
+ }
+ },
+ // 更新经纬度
+ updateLatLng(state, item) {
+ state.latLng = item
+ },
+
+
+ },
+ actions: {
+
+
+ },
+ modules: {
+ add,
+ user,
+ },
+});
+
+export default store;
\ No newline at end of file
diff --git a/store/modules/add.js b/store/modules/add.js
new file mode 100644
index 0000000..d5e9a65
--- /dev/null
+++ b/store/modules/add.js
@@ -0,0 +1,91 @@
+
+// import addApi from '@/api/add.js'; // 引入
+
+const add = {
+ state: {
+ addList: []
+ },
+ mutations: {
+ // 更新广告列表
+ upDateAddList(state, list) {
+ state.addList = list
+ },
+
+ // 更新当前广告点击量
+ upDateViews(state, id) {
+ let add = state.addList.find(item=>item.id==id)
+ add.clicks ++
+ },
+
+
+
+
+ },
+ actions: {
+ // 点击广告
+ async addClick({commit, dispatch}, curAdd) {
+ // await dispatch('updateStatistics')
+ curAdd.clicks ++
+ if(!curAdd.adBannerDO.jumpUrl) {
+ return false
+ }
+
+ commit('updateWebVeiwUrl', curAdd.adBannerDO.jumpUrl)
+ uni.navigateTo({
+ url:'/pages/commeWebView/addWebView'
+ })
+ },
+ // 获取当前广告
+ getCurrentAdd({state},id) {
+ console.log(id)
+ console.log(state.addList)
+ let curAdd = state.addList.find(item=>item.id==id)
+ if(curAdd) {
+ curAdd.views ++
+ return curAdd
+ }else {
+ return {}
+ }
+ },
+ // // 广告
+ // async addPageFn({commit,state, dispatch}) {
+ // await dispatch('updateStatistics')
+ // let obj = {
+ // pageNo: 1,
+ // pageSize: 30,
+ // adClient: 1
+ // }
+ // const [err, res] = await addApi.addPage(obj)
+ // let list = res.data.records.map(item=>{
+ // item.views = 0
+ // item.clicks = 0
+ // return item
+ // })
+ // commit('upDateAddList', list)
+ // console.log('广告列表')
+ // console.log(list)
+
+ // },
+ // 更新广告点击量
+ async updateStatistics({ dispatch,state, commit }) {
+ let statistics = state.addList.filter(item=>item.views)
+ console.log('调用更新广告接口')
+ if(statistics.length) {
+ let stcsList = statistics.map(add=>{
+ let obj = {
+ "adPositionId": add.id,
+ "adId": add.adId,
+ "views": add.views,
+ "clicks": add.clicks
+ }
+ return obj
+ })
+ const [err, res] = await addApi.batchUpdate(stcsList)
+ console.log('更新广告点击量请求结果')
+ console.log(res)
+ }
+ }
+ }
+}
+
+ export default add
\ No newline at end of file
diff --git a/store/modules/user.js b/store/modules/user.js
new file mode 100644
index 0000000..5af0505
--- /dev/null
+++ b/store/modules/user.js
@@ -0,0 +1,31 @@
+
+import addApi from '../../common/sdk/qqmap-wx-jssdk.min.js'; // 引入
+
+const user = {
+ state: {
+ addList: []
+ },
+ mutations: {
+ // 更新广告列表
+ upDateAddList(state, list) {
+ state.addList = list
+ },
+ },
+ actions: {
+ // 点击广告
+ async addClick({commit, dispatch}, curAdd) {
+ // await dispatch('updateStatistics')
+ curAdd.clicks ++
+ if(!curAdd.adBannerDO.jumpUrl) {
+ return false
+ }
+
+ commit('updateWebVeiwUrl', curAdd.adBannerDO.jumpUrl)
+ uni.navigateTo({
+ url:'/pages/commeWebView/addWebView'
+ })
+ },
+ }
+}
+
+ export default user
\ No newline at end of file
diff --git a/uni.promisify.adaptor.js b/uni.promisify.adaptor.js
new file mode 100644
index 0000000..47fbce1
--- /dev/null
+++ b/uni.promisify.adaptor.js
@@ -0,0 +1,10 @@
+uni.addInterceptor({
+ returnValue (res) {
+ if (!(!!res && (typeof res === "object" || typeof res === "function") && typeof res.then === "function")) {
+ return res;
+ }
+ return new Promise((resolve, reject) => {
+ res.then((res) => res[0] ? reject(res[0]) : resolve(res[1]));
+ });
+ },
+});
\ No newline at end of file
diff --git a/uni.scss b/uni.scss
new file mode 100644
index 0000000..8738726
--- /dev/null
+++ b/uni.scss
@@ -0,0 +1,80 @@
+/**
+ * 这里是uni-app内置的常用样式变量
+ *
+ * uni-app 官方扩展插件及插件市场(https://ext.dcloud.net.cn)上很多三方插件均使用了这些样式变量
+ * 如果你是插件开发者,建议你使用scss预处理,并在插件代码中直接使用这些变量(无需 import 这个文件),方便用户通过搭积木的方式开发整体风格一致的App
+ *
+ */
+
+/**
+ * 如果你是App开发者(插件使用者),你可以通过修改这些变量来定制自己的插件主题,实现自定义主题功能
+ *
+ * 如果你的项目同样使用了scss预处理,你也可以直接在你的 scss 代码中使用如下变量,同时无需 import 这个文件
+ */
+
+/* 颜色变量 */
+@import '@/uni_modules/uview-ui/theme.scss';
+
+/* 行为相关颜色 */
+$uni-color-primary: #007aff;
+$uni-color-success: #4cd964;
+$uni-color-warning: #f0ad4e;
+$uni-color-error: #dd524d;
+
+/* 文字基本颜色 */
+$uni-text-color:#333;//基本色
+$uni-text-color-inverse:#fff;//反色
+$uni-text-color-grey:#999;//辅助灰色,如加载更多的提示信息
+$uni-text-color-placeholder: #808080;
+$uni-text-color-disable:#c0c0c0;
+
+/* 背景颜色 */
+$uni-bg-color:#ffffff;
+$uni-bg-color-grey:#f8f8f8;
+$uni-bg-color-hover:#f1f1f1;//点击状态颜色
+$uni-bg-color-mask:rgba(0, 0, 0, 0.4);//遮罩颜色
+
+/* 边框颜色 */
+$uni-border-color:#c8c7cc;
+
+/* 尺寸变量 */
+
+/* 文字尺寸 */
+$uni-font-size-sm:12px;
+$uni-font-size-base:14px;
+$uni-font-size-lg:16;
+
+/* 图片尺寸 */
+$uni-img-size-sm:20px;
+$uni-img-size-base:26px;
+$uni-img-size-lg:40px;
+
+/* Border Radius */
+$uni-border-radius-sm: 2px;
+$uni-border-radius-base: 3px;
+$uni-border-radius-lg: 6px;
+$uni-border-radius-circle: 50%;
+
+/* 水平间距 */
+$uni-spacing-row-sm: 5px;
+$uni-spacing-row-base: 10px;
+$uni-spacing-row-lg: 15px;
+
+/* 垂直间距 */
+$uni-spacing-col-sm: 4px;
+$uni-spacing-col-base: 8px;
+$uni-spacing-col-lg: 12px;
+
+/* 透明度 */
+$uni-opacity-disabled: 0.3; // 组件禁用态的透明度
+
+/* 文章场景相关 */
+$uni-color-title: #2C405A; // 文章标题颜色
+$uni-font-size-title:20px;
+$uni-color-subtitle: #555555; // 二级标题颜色
+$uni-font-size-subtitle:26px;
+$uni-color-paragraph: #3F536E; // 文章段落颜色
+$uni-font-size-paragraph:15px;
+
+// 自已定义的
+$themC: #1989FA,
diff --git a/uni_modules/uni-config-center/changelog.md b/uni_modules/uni-config-center/changelog.md
new file mode 100644
index 0000000..57dbcb5
--- /dev/null
+++ b/uni_modules/uni-config-center/changelog.md
@@ -0,0 +1,6 @@
+## 0.0.3(2022-11-11)
+- 修复 config 方法获取根节点为数组格式配置时错误的转化为了对象的Bug
+## 0.0.2(2021-04-16)
+- 修改插件package信息
+## 0.0.1(2021-03-15)
+- 初始化项目
diff --git a/uni_modules/uni-config-center/package.json b/uni_modules/uni-config-center/package.json
new file mode 100644
index 0000000..bace866
--- /dev/null
+++ b/uni_modules/uni-config-center/package.json
@@ -0,0 +1,81 @@
+{
+ "id": "uni-config-center",
+ "displayName": "uni-config-center",
+ "version": "0.0.3",
+ "description": "uniCloud 配置中心",
+ "keywords": [
+ "配置",
+ "配置中心"
+],
+ "repository": "",
+ "engines": {
+ "HBuilderX": "^3.1.0"
+ },
+"dcloudext": {
+ "sale": {
+ "regular": {
+ "price": "0.00"
+ },
+ "sourcecode": {
+ "price": "0.00"
+ }
+ },
+ "contact": {
+ "qq": ""
+ },
+ "declaration": {
+ "ads": "无",
+ "data": "无",
+ "permissions": "无"
+ },
+ "npmurl": "",
+ "type": "unicloud-template-function"
+ },
+ "directories": {
+ "example": "../../../scripts/dist"
+ },
+ "uni_modules": {
+ "dependencies": [],
+ "encrypt": [],
+ "platforms": {
+ "cloud": {
+ "tcb": "y",
+ "aliyun": "y"
+ },
+ "client": {
+ "App": {
+ "app-vue": "u",
+ "app-nvue": "u"
+ },
+ "H5-mobile": {
+ "Safari": "u",
+ "Android Browser": "u",
+ "微信浏览器(Android)": "u",
+ "QQ浏览器(Android)": "u"
+ },
+ "H5-pc": {
+ "Chrome": "u",
+ "IE": "u",
+ "Edge": "u",
+ "Firefox": "u",
+ "Safari": "u"
+ },
+ "小程序": {
+ "微信": "u",
+ "阿里": "u",
+ "百度": "u",
+ "字节跳动": "u",
+ "QQ": "u"
+ },
+ "快应用": {
+ "华为": "u",
+ "联盟": "u"
+ },
+ "Vue": {
+ "vue2": "y",
+ "vue3": "u"
+ }
+ }
+ }
+ }
+}
diff --git a/uni_modules/uni-config-center/readme.md b/uni_modules/uni-config-center/readme.md
new file mode 100644
index 0000000..03f7fc2
--- /dev/null
+++ b/uni_modules/uni-config-center/readme.md
@@ -0,0 +1,93 @@
+# 为什么使用uni-config-center
+
+实际开发中很多插件需要配置文件才可以正常运行,如果每个插件都单独进行配置的话就会产生下面这样的目录结构
+
+```bash
+cloudfunctions
+└─────common 公共模块
+ ├─plugin-a // 插件A对应的目录
+ │ ├─index.js
+ │ ├─config.json // plugin-a对应的配置文件
+ │ └─other-file.cert // plugin-a依赖的其他文件
+ └─plugin-b // plugin-b对应的目录
+ ├─index.js
+ └─config.json // plugin-b对应的配置文件
+```
+
+假设插件作者要发布一个项目模板,里面使用了很多需要配置的插件,无论是作者发布还是用户使用都是一个大麻烦。
+
+uni-config-center就是用了统一管理这些配置文件的,使用uni-config-center后的目录结构如下
+
+```bash
+cloudfunctions
+└─────common 公共模块
+ ├─plugin-a // 插件A对应的目录
+ │ └─index.js
+ ├─plugin-b // plugin-b对应的目录
+ │ └─index.js
+ └─uni-config-center
+ ├─index.js // config-center入口文件
+ ├─plugin-a
+ │ ├─config.json // plugin-a对应的配置文件
+ │ └─other-file.cert // plugin-a依赖的其他文件
+ └─plugin-b
+ └─config.json // plugin-b对应的配置文件
+```
+
+使用uni-config-center后的优势
+
+- 配置文件统一管理,分离插件主体和配置信息,更新插件更方便
+- 支持对config.json设置schema,插件使用者在HBuilderX内编写config.json文件时会有更好的提示(后续HBuilderX会提供支持)
+
+# 用法
+
+在要使用uni-config-center的公共模块或云函数内引入uni-config-center依赖,请参考:[使用公共模块](https://uniapp.dcloud.net.cn/uniCloud/cf-common)
+
+```js
+const createConfig = require('uni-config-center')
+
+const uniIdConfig = createConfig({
+ pluginId: 'uni-id', // 插件id
+ defaultConfig: { // 默认配置
+ tokenExpiresIn: 7200,
+ tokenExpiresThreshold: 600,
+ },
+ customMerge: function(defaultConfig, userConfig) { // 自定义默认配置和用户配置的合并规则,不设置的情况侠会对默认配置和用户配置进行深度合并
+ // defaudltConfig 默认配置
+ // userConfig 用户配置
+ return Object.assign(defaultConfig, userConfig)
+ }
+})
+
+
+// 以如下配置为例
+// {
+// "tokenExpiresIn": 7200,
+// "passwordErrorLimit": 6,
+// "bindTokenToDevice": false,
+// "passwordErrorRetryTime": 3600,
+// "app-plus": {
+// "tokenExpiresIn": 2592000
+// },
+// "service": {
+// "sms": {
+// "codeExpiresIn": 300
+// }
+// }
+// }
+
+// 获取配置
+uniIdConfig.config() // 获取全部配置,注意:uni-config-center内不存在对应插件目录时会返回空对象
+uniIdConfig.config('tokenExpiresIn') // 指定键值获取配置,返回:7200
+uniIdConfig.config('service.sms.codeExpiresIn') // 指定键值获取配置,返回:300
+uniIdConfig.config('tokenExpiresThreshold', 600) // 指定键值获取配置,如果不存在则取传入的默认值,返回:600
+
+// 获取文件绝对路径
+uniIdConfig.resolve('custom-token.js') // 获取uni-config-center/uni-id/custom-token.js文件的路径
+
+// 引用文件(require)
+uniIDConfig.requireFile('custom-token.js') // 使用require方式引用uni-config-center/uni-id/custom-token.js文件。文件不存在时返回undefined,文件内有其他错误导致require失败时会抛出错误。
+
+// 判断是否包含某文件
+uniIDConfig.hasFile('custom-token.js') // 配置目录是否包含某文件,true: 文件存在,false: 文件不存在
+```
\ No newline at end of file
diff --git a/uni_modules/uni-config-center/uniCloud/cloudfunctions/common/uni-config-center/index.js b/uni_modules/uni-config-center/uniCloud/cloudfunctions/common/uni-config-center/index.js
new file mode 100644
index 0000000..00ba62f
--- /dev/null
+++ b/uni_modules/uni-config-center/uniCloud/cloudfunctions/common/uni-config-center/index.js
@@ -0,0 +1 @@
+"use strict";var t=require("fs"),r=require("path");function e(t){return t&&"object"==typeof t&&"default"in t?t:{default:t}}var n=e(t),o=e(r),i="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{};var u=function(t){var r={exports:{}};return t(r,r.exports),r.exports}((function(t,r){var e="__lodash_hash_undefined__",n=9007199254740991,o="[object Arguments]",u="[object Function]",c="[object Object]",a=/^\[object .+?Constructor\]$/,f=/^(?:0|[1-9]\d*)$/,s={};s["[object Float32Array]"]=s["[object Float64Array]"]=s["[object Int8Array]"]=s["[object Int16Array]"]=s["[object Int32Array]"]=s["[object Uint8Array]"]=s["[object Uint8ClampedArray]"]=s["[object Uint16Array]"]=s["[object Uint32Array]"]=!0,s[o]=s["[object Array]"]=s["[object ArrayBuffer]"]=s["[object Boolean]"]=s["[object DataView]"]=s["[object Date]"]=s["[object Error]"]=s[u]=s["[object Map]"]=s["[object Number]"]=s[c]=s["[object RegExp]"]=s["[object Set]"]=s["[object String]"]=s["[object WeakMap]"]=!1;var l="object"==typeof i&&i&&i.Object===Object&&i,h="object"==typeof self&&self&&self.Object===Object&&self,p=l||h||Function("return this")(),_=r&&!r.nodeType&&r,v=_&&t&&!t.nodeType&&t,d=v&&v.exports===_,y=d&&l.process,g=function(){try{var t=v&&v.require&&v.require("util").types;return t||y&&y.binding&&y.binding("util")}catch(t){}}(),b=g&&g.isTypedArray;function j(t,r,e){switch(e.length){case 0:return t.call(r);case 1:return t.call(r,e[0]);case 2:return t.call(r,e[0],e[1]);case 3:return t.call(r,e[0],e[1],e[2])}return t.apply(r,e)}var w,O,m,A=Array.prototype,z=Function.prototype,M=Object.prototype,x=p["__core-js_shared__"],C=z.toString,F=M.hasOwnProperty,U=(w=/[^.]+$/.exec(x&&x.keys&&x.keys.IE_PROTO||""))?"Symbol(src)_1."+w:"",S=M.toString,I=C.call(Object),P=RegExp("^"+C.call(F).replace(/[\\^$.*+?()[\]{}|]/g,"\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g,"$1.*?")+"$"),T=d?p.Buffer:void 0,q=p.Symbol,E=p.Uint8Array,$=T?T.allocUnsafe:void 0,D=(O=Object.getPrototypeOf,m=Object,function(t){return O(m(t))}),k=Object.create,B=M.propertyIsEnumerable,N=A.splice,L=q?q.toStringTag:void 0,R=function(){try{var t=vt(Object,"defineProperty");return t({},"",{}),t}catch(t){}}(),G=T?T.isBuffer:void 0,V=Math.max,W=Date.now,H=vt(p,"Map"),J=vt(Object,"create"),K=function(){function t(){}return function(r){if(!xt(r))return{};if(k)return k(r);t.prototype=r;var e=new t;return t.prototype=void 0,e}}();function Q(t){var r=-1,e=null==t?0:t.length;for(this.clear();++r-1},X.prototype.set=function(t,r){var e=this.__data__,n=nt(e,t);return n<0?(++this.size,e.push([t,r])):e[n][1]=r,this},Y.prototype.clear=function(){this.size=0,this.__data__={hash:new Q,map:new(H||X),string:new Q}},Y.prototype.delete=function(t){var r=_t(this,t).delete(t);return this.size-=r?1:0,r},Y.prototype.get=function(t){return _t(this,t).get(t)},Y.prototype.has=function(t){return _t(this,t).has(t)},Y.prototype.set=function(t,r){var e=_t(this,t),n=e.size;return e.set(t,r),this.size+=e.size==n?0:1,this},Z.prototype.clear=function(){this.__data__=new X,this.size=0},Z.prototype.delete=function(t){var r=this.__data__,e=r.delete(t);return this.size=r.size,e},Z.prototype.get=function(t){return this.__data__.get(t)},Z.prototype.has=function(t){return this.__data__.has(t)},Z.prototype.set=function(t,r){var e=this.__data__;if(e instanceof X){var n=e.__data__;if(!H||n.length<199)return n.push([t,r]),this.size=++e.size,this;e=this.__data__=new Y(n)}return e.set(t,r),this.size=e.size,this};var it,ut=function(t,r,e){for(var n=-1,o=Object(t),i=e(t),u=i.length;u--;){var c=i[it?u:++n];if(!1===r(o[c],c,o))break}return t};function ct(t){return null==t?void 0===t?"[object Undefined]":"[object Null]":L&&L in Object(t)?function(t){var r=F.call(t,L),e=t[L];try{t[L]=void 0;var n=!0}catch(t){}var o=S.call(t);n&&(r?t[L]=e:delete t[L]);return o}(t):function(t){return S.call(t)}(t)}function at(t){return Ct(t)&&ct(t)==o}function ft(t){return!(!xt(t)||function(t){return!!U&&U in t}(t))&&(zt(t)?P:a).test(function(t){if(null!=t){try{return C.call(t)}catch(t){}try{return t+""}catch(t){}}return""}(t))}function st(t){if(!xt(t))return function(t){var r=[];if(null!=t)for(var e in Object(t))r.push(e);return r}(t);var r=yt(t),e=[];for(var n in t)("constructor"!=n||!r&&F.call(t,n))&&e.push(n);return e}function lt(t,r,e,n,o){t!==r&&ut(r,(function(i,u){if(o||(o=new Z),xt(i))!function(t,r,e,n,o,i,u){var a=gt(t,e),f=gt(r,e),s=u.get(f);if(s)return void rt(t,e,s);var l=i?i(a,f,e+"",t,r,u):void 0,h=void 0===l;if(h){var p=Ot(f),_=!p&&At(f),v=!p&&!_&&Ft(f);l=f,p||_||v?Ot(a)?l=a:Ct(j=a)&&mt(j)?l=function(t,r){var e=-1,n=t.length;r||(r=Array(n));for(;++e-1&&t%1==0&&t0){if(++r>=800)return arguments[0]}else r=0;return t.apply(void 0,arguments)}}(pt);function jt(t,r){return t===r||t!=t&&r!=r}var wt=at(function(){return arguments}())?at:function(t){return Ct(t)&&F.call(t,"callee")&&!B.call(t,"callee")},Ot=Array.isArray;function mt(t){return null!=t&&Mt(t.length)&&!zt(t)}var At=G||function(){return!1};function zt(t){if(!xt(t))return!1;var r=ct(t);return r==u||"[object GeneratorFunction]"==r||"[object AsyncFunction]"==r||"[object Proxy]"==r}function Mt(t){return"number"==typeof t&&t>-1&&t%1==0&&t<=n}function xt(t){var r=typeof t;return null!=t&&("object"==r||"function"==r)}function Ct(t){return null!=t&&"object"==typeof t}var Ft=b?function(t){return function(r){return t(r)}}(b):function(t){return Ct(t)&&Mt(t.length)&&!!s[ct(t)]};function Ut(t){return mt(t)?tt(t,!0):st(t)}var St,It=(St=function(t,r,e){lt(t,r,e)},ht((function(t,r){var e=-1,n=r.length,o=n>1?r[n-1]:void 0,i=n>2?r[2]:void 0;for(o=St.length>3&&"function"==typeof o?(n--,o):void 0,i&&function(t,r,e){if(!xt(e))return!1;var n=typeof r;return!!("number"==n?mt(e)&&dt(r,e.length):"string"==n&&r in e)&&jt(e[r],t)}(r[0],r[1],i)&&(o=n<3?void 0:o,n=1),t=Object(t);++ec.call(t,r);class f{constructor({pluginId:t,defaultConfig:r={},customMerge:e,root:n}){this.pluginId=t,this.defaultConfig=r,this.pluginConfigPath=o.default.resolve(n||__dirname,t),this.customMerge=e,this._config=void 0}resolve(t){return o.default.resolve(this.pluginConfigPath,t)}hasFile(t){return n.default.existsSync(this.resolve(t))}requireFile(t){try{return require(this.resolve(t))}catch(t){if("MODULE_NOT_FOUND"===t.code)return;throw t}}_getUserConfig(){return this.requireFile("config.json")}config(t,r){if(!this._config){const t=this._getUserConfig();this._config=Array.isArray(t)?t:(this.customMerge||u)(this.defaultConfig,t)}let e=this._config;return t?function(t,r,e){if("number"==typeof r)return t[r];if("symbol"==typeof r)return a(t,r)?t[r]:e;const n="string"!=typeof(o=r)?o:o.split(".").reduce(((t,r)=>(r.split(/\[([^}]+)\]/g).forEach((r=>r&&t.push(r))),t)),[]);var o;let i=t;for(let t=0;t {
+ return (item.dcloudAppid === appid)
+ })
+ }
+ return this._uniIdConfig
+ }
+}
+
+class AppConfig extends ConfigBase {
+
+ constructor() {
+ super()
+ }
+
+ get(appid, platform) {
+ if (!this.isSupport(platform)) {
+ return null
+ }
+
+ let appConfig = this.getAppConfig(appid)
+ if (!appConfig) {
+ return null
+ }
+
+ return this.getOauthConfig(appConfig, platform)
+ }
+
+ isSupport(platformName) {
+ return (Support_Platforms.indexOf(platformName) >= 0)
+ }
+
+ getOauthConfig(appConfig, platformName) {
+ let treePath = OauthConfig[platformName]
+ let node = this.findNode(appConfig, treePath)
+ if (node && node.appid && node.appsecret) {
+ return {
+ appid: node.appid,
+ secret: node.appsecret
+ }
+ }
+ return null
+ }
+
+ findNode(treeNode, arrayPath) {
+ let node = treeNode
+ for (let treePath of arrayPath) {
+ for (let name of treePath) {
+ const currentNode = node[name]
+ if (currentNode) {
+ node = currentNode
+ } else {
+ node = null
+ break
+ }
+ }
+ if (node === null) {
+ node = treeNode
+ } else {
+ break
+ }
+ }
+ return node
+ }
+}
+
+
+module.exports = {
+ AppConfig
+};
\ No newline at end of file
diff --git a/uni_modules/uni-open-bridge-common/uniCloud/cloudfunctions/common/uni-open-bridge-common/consts.js b/uni_modules/uni-open-bridge-common/uniCloud/cloudfunctions/common/uni-open-bridge-common/consts.js
new file mode 100644
index 0000000..4c666e9
--- /dev/null
+++ b/uni_modules/uni-open-bridge-common/uniCloud/cloudfunctions/common/uni-open-bridge-common/consts.js
@@ -0,0 +1,30 @@
+'use strict';
+
+const TAG = "UNI_OPEN_BRIDGE"
+
+const HTTP_STATUS = {
+ SUCCESS: 200
+}
+
+const ProviderType = {
+ WEIXIN_MP: 'weixin-mp',
+ WEIXIN_H5: 'weixin-h5',
+ WEIXIN_APP: 'weixin-app',
+ WEIXIN_WEB: 'weixin-web',
+ QQ_MP: 'qq-mp',
+ QQ_APP: 'qq-app'
+}
+
+// old
+const PlatformType = ProviderType
+
+const ErrorCodeType = {
+ SYSTEM_ERROR: TAG + "_SYSTEM_ERROR"
+}
+
+module.exports = {
+ HTTP_STATUS,
+ ProviderType,
+ PlatformType,
+ ErrorCodeType
+}
diff --git a/uni_modules/uni-open-bridge-common/uniCloud/cloudfunctions/common/uni-open-bridge-common/index.js b/uni_modules/uni-open-bridge-common/uniCloud/cloudfunctions/common/uni-open-bridge-common/index.js
new file mode 100644
index 0000000..fc23cd9
--- /dev/null
+++ b/uni_modules/uni-open-bridge-common/uniCloud/cloudfunctions/common/uni-open-bridge-common/index.js
@@ -0,0 +1,317 @@
+'use strict';
+
+const {
+ PlatformType,
+ ProviderType,
+ ErrorCodeType
+} = require('./consts.js')
+
+const {
+ AppConfig
+} = require('./config.js')
+
+const {
+ Storage
+} = require('./storage.js')
+
+const {
+ BridgeError
+} = require('./bridge-error.js')
+
+const {
+ WeixinServer
+} = require('./weixin-server.js')
+
+const appConfig = new AppConfig()
+
+class AccessToken extends Storage {
+
+ constructor() {
+ super('access-token', ['provider', 'appid'])
+ }
+
+ async update(key) {
+ super.update(key)
+
+ const result = await this.getByWeixinServer(key)
+
+ return this.set(key, result.value, result.duration)
+ }
+
+ async fallback(key) {
+ return this.getByWeixinServer(key)
+ }
+
+ async getByWeixinServer(key) {
+ const oauthConfig = appConfig.get(key.dcloudAppid, key.provider)
+ let methodName
+ if (key.provider === ProviderType.WEIXIN_MP) {
+ methodName = 'GetMPAccessTokenData'
+ } else if (key.provider === ProviderType.WEIXIN_H5) {
+ methodName = 'GetH5AccessTokenData'
+ } else {
+ throw new BridgeError(ErrorCodeType.SYSTEM_ERROR, "provider invalid")
+ }
+
+ const responseData = await WeixinServer[methodName](oauthConfig)
+
+ const duration = responseData.expires_in || (60 * 60 * 2)
+ delete responseData.expires_in
+
+ return {
+ value: responseData,
+ duration
+ }
+ }
+}
+
+class UserAccessToken extends Storage {
+
+ constructor() {
+ super('user-access-token', ['provider', 'appid', 'openid'])
+ }
+}
+
+class SessionKey extends Storage {
+
+ constructor() {
+ super('session-key', ['provider', 'appid', 'openid'])
+ }
+}
+
+class Encryptkey extends Storage {
+
+ constructor() {
+ super('encrypt-key', ['provider', 'appid', 'openid'])
+ }
+
+ async update(key) {
+ super.update(key)
+
+ const result = await this.getByWeixinServer(key)
+
+ return this.set(key, result.value, result.duration)
+ }
+
+ getKeyString(key) {
+ return `${super.getKeyString(key)}-${key.version}`
+ }
+
+ getExpiresIn(value) {
+ if (value <= 0) {
+ return 60
+ }
+ return value
+ }
+
+ async fallback(key) {
+ return this.getByWeixinServer(key)
+ }
+
+ async getByWeixinServer(key) {
+ const accessToken = await Factory.Get(AccessToken, key)
+ const userSession = await Factory.Get(SessionKey, key)
+
+ const responseData = await WeixinServer.GetUserEncryptKeyData({
+ openid: key.openid,
+ access_token: accessToken.access_token,
+ session_key: userSession.session_key
+ })
+
+ const keyInfo = responseData.key_info_list.find((item) => {
+ return item.version === key.version
+ })
+
+ if (!keyInfo) {
+ throw new BridgeError(ErrorCodeType.SYSTEM_ERROR, 'key version invalid')
+ }
+
+ const value = {
+ encrypt_key: keyInfo.encrypt_key,
+ iv: keyInfo.iv
+ }
+
+ return {
+ value,
+ duration: keyInfo.expire_in
+ }
+ }
+}
+
+class Ticket extends Storage {
+
+ constructor() {
+ super('ticket', ['provider', 'appid'])
+ }
+
+ async update(key) {
+ super.update(key)
+
+ const result = await this.getByWeixinServer(key)
+
+ return this.set(key, result.value, result.duration)
+ }
+
+ async fallback(key) {
+ return this.getByWeixinServer(key)
+ }
+
+ async getByWeixinServer(key) {
+ const accessToken = await Factory.Get(AccessToken, {
+ dcloudAppid: key.dcloudAppid,
+ provider: ProviderType.WEIXIN_H5
+ })
+
+ const responseData = await WeixinServer.GetH5TicketData(accessToken)
+
+ const duration = responseData.expires_in || (60 * 60 * 2)
+ delete responseData.expires_in
+ delete responseData.errcode
+ delete responseData.errmsg
+
+ return {
+ value: responseData,
+ duration
+ }
+ }
+}
+
+
+const Factory = {
+
+ async Get(T, key, fallback) {
+ Factory.FixOldKey(key)
+ return Factory.MakeUnique(T).get(key, fallback)
+ },
+
+ async Set(T, key, value, expiresIn) {
+ Factory.FixOldKey(key)
+ return Factory.MakeUnique(T).set(key, value, expiresIn)
+ },
+
+ async Remove(T, key) {
+ Factory.FixOldKey(key)
+ return Factory.MakeUnique(T).remove(key)
+ },
+
+ async Update(T, key) {
+ Factory.FixOldKey(key)
+ return Factory.MakeUnique(T).update(key)
+ },
+
+ FixOldKey(key) {
+ if (!key.provider) {
+ key.provider = key.platform
+ }
+
+ const configData = appConfig.get(key.dcloudAppid, key.provider)
+ if (!configData) {
+ throw new BridgeError(ErrorCodeType.SYSTEM_ERROR, 'appid or provider invalid')
+ }
+ key.appid = configData.appid
+ },
+
+ MakeUnique(T) {
+ return new T()
+ }
+}
+
+
+// exports
+
+async function getAccessToken(key, fallback) {
+ return Factory.Get(AccessToken, key, fallback)
+}
+
+async function setAccessToken(key, value, expiresIn) {
+ return Factory.Set(AccessToken, key, value, expiresIn)
+}
+
+async function removeAccessToken(key) {
+ return Factory.Remove(AccessToken, key)
+}
+
+async function updateAccessToken(key) {
+ return Factory.Update(AccessToken, key)
+}
+
+async function getUserAccessToken(key, fallback) {
+ return Factory.Get(UserAccessToken, key, fallback)
+}
+
+async function setUserAccessToken(key, value, expiresIn) {
+ return Factory.Set(UserAccessToken, key, value, expiresIn)
+}
+
+async function removeUserAccessToken(key) {
+ return Factory.Remove(UserAccessToken, key)
+}
+
+async function getSessionKey(key, fallback) {
+ return Factory.Get(SessionKey, key, fallback)
+}
+
+async function setSessionKey(key, value, expiresIn) {
+ return Factory.Set(SessionKey, key, value, expiresIn)
+}
+
+async function removeSessionKey(key) {
+ return Factory.Remove(SessionKey, key)
+}
+
+async function getEncryptKey(key, fallback) {
+ return Factory.Get(Encryptkey, key, fallback)
+}
+
+async function setEncryptKey(key, value, expiresIn) {
+ return Factory.Set(Encryptkey, key, value, expiresIn)
+}
+
+async function removeEncryptKey(key) {
+ return Factory.Remove(Encryptkey, key)
+}
+
+async function updateEncryptKey(key) {
+ return Factory.Update(Encryptkey, key)
+}
+
+async function getTicket(key, fallback) {
+ return Factory.Get(Ticket, key, fallback)
+}
+
+async function setTicket(key, value, expiresIn) {
+ return Factory.Set(Ticket, key, value, expiresIn)
+}
+
+async function removeTicket(key) {
+ return Factory.Remove(Ticket, key)
+}
+
+async function updateTicket(key) {
+ return Factory.Update(Ticket, key)
+}
+
+module.exports = {
+ getAccessToken,
+ setAccessToken,
+ removeAccessToken,
+ updateAccessToken,
+ getUserAccessToken,
+ setUserAccessToken,
+ removeUserAccessToken,
+ getSessionKey,
+ setSessionKey,
+ removeSessionKey,
+ getEncryptKey,
+ setEncryptKey,
+ removeEncryptKey,
+ updateEncryptKey,
+ getTicket,
+ setTicket,
+ removeTicket,
+ updateTicket,
+ ProviderType,
+ PlatformType,
+ WeixinServer,
+ ErrorCodeType
+}
diff --git a/uni_modules/uni-open-bridge-common/uniCloud/cloudfunctions/common/uni-open-bridge-common/package.json b/uni_modules/uni-open-bridge-common/uniCloud/cloudfunctions/common/uni-open-bridge-common/package.json
new file mode 100644
index 0000000..a017b49
--- /dev/null
+++ b/uni_modules/uni-open-bridge-common/uniCloud/cloudfunctions/common/uni-open-bridge-common/package.json
@@ -0,0 +1,15 @@
+{
+ "name": "uni-open-bridge-common",
+ "version": "1.0.0",
+ "description": "",
+ "main": "index.js",
+ "scripts": {
+ "test": "echo \"Error: no test specified\" && exit 1"
+ },
+ "keywords": [],
+ "author": "",
+ "license": "ISC",
+ "dependencies": {
+ "uni-config-center": "file:../../../../../uni-config-center/uniCloud/cloudfunctions/common/uni-config-center"
+ }
+}
\ No newline at end of file
diff --git a/uni_modules/uni-open-bridge-common/uniCloud/cloudfunctions/common/uni-open-bridge-common/storage.js b/uni_modules/uni-open-bridge-common/uniCloud/cloudfunctions/common/uni-open-bridge-common/storage.js
new file mode 100644
index 0000000..bfb13a1
--- /dev/null
+++ b/uni_modules/uni-open-bridge-common/uniCloud/cloudfunctions/common/uni-open-bridge-common/storage.js
@@ -0,0 +1,111 @@
+'use strict';
+
+const {
+ Validator
+} = require('./validator.js')
+
+const {
+ CacheKeyCascade
+} = require('./uni-cloud-cache.js')
+
+const {
+ BridgeError
+} = require('./bridge-error.js')
+
+class Storage {
+
+ constructor(type, keys) {
+ this._type = type || null
+ this._keys = keys || []
+ }
+
+ async get(key, fallback) {
+ this.validateKey(key)
+ const result = await this.create(key, fallback).get()
+ return result.value
+ }
+
+ async set(key, value, expiresIn) {
+ this.validateKey(key)
+ this.validateValue(value)
+ const expires_in = this.getExpiresIn(expiresIn)
+ if (expires_in !== 0) {
+ await this.create(key).set(this.getValue(value), expires_in)
+ }
+ }
+
+ async remove(key) {
+ this.validateKey(key)
+ await this.create(key).remove()
+ }
+
+ // virtual
+ async update(key) {
+ this.validateKey(key)
+ }
+
+ async ttl(key) {
+ this.validateKey(key)
+ // 后续考虑支持
+ }
+
+ async fallback(key) {}
+
+ getKeyString(key) {
+ const keyArray = [Storage.Prefix]
+ this._keys.forEach((name) => {
+ keyArray.push(key[name])
+ })
+ keyArray.push(this._type)
+ return keyArray.join(':')
+ }
+
+ getValue(value) {
+ return value
+ }
+
+ getExpiresIn(value) {
+ if (value !== undefined) {
+ return value
+ }
+ return -1
+ }
+
+ validateKey(key) {
+ Validator.Key(this._keys, key)
+ }
+
+ validateValue(value) {
+ Validator.Value(value)
+ }
+
+ create(key, fallback) {
+ const keyString = this.getKeyString(key)
+ const options = {
+ layers: [{
+ type: 'database',
+ key: keyString
+ }, {
+ type: 'redis',
+ key: keyString
+ }]
+ }
+
+ const _this = this
+ return new CacheKeyCascade({
+ ...options,
+ fallback: async function() {
+ if (fallback) {
+ return fallback(key)
+ } else if (_this.fallback) {
+ return _this.fallback(key)
+ }
+ }
+ })
+ }
+}
+Storage.Prefix = "uni-id"
+
+module.exports = {
+ Storage
+};
diff --git a/uni_modules/uni-open-bridge-common/uniCloud/cloudfunctions/common/uni-open-bridge-common/uni-cloud-cache.js b/uni_modules/uni-open-bridge-common/uniCloud/cloudfunctions/common/uni-open-bridge-common/uni-cloud-cache.js
new file mode 100644
index 0000000..2e4286b
--- /dev/null
+++ b/uni_modules/uni-open-bridge-common/uniCloud/cloudfunctions/common/uni-open-bridge-common/uni-cloud-cache.js
@@ -0,0 +1,324 @@
+const db = uniCloud.database()
+
+function getType(value) {
+ return Object.prototype.toString.call(value).slice(8, -1).toLowerCase()
+}
+
+const validator = {
+ key: function(value) {
+ const err = new Error('Invalid key')
+ if (typeof value !== 'string') {
+ throw err
+ }
+ const valueTrim = value.trim()
+ if (!valueTrim || valueTrim !== value) {
+ throw err
+ }
+ },
+ value: function(value) {
+ // 仅作简单校验
+ const type = getType(value)
+ const validValueType = ['null', 'number', 'string', 'array', 'object']
+ if (validValueType.indexOf(type) === -1) {
+ throw new Error('Invalid value type')
+ }
+ },
+ duration: function(value) {
+ const err = new Error('Invalid duration')
+ if (value === undefined) {
+ return
+ }
+ if (typeof value !== 'number' || value === 0) {
+ throw err
+ }
+ }
+}
+
+/**
+ * 入库时 expired 为过期时间对应的时间戳,永不过期用-1表示
+ * 返回结果时 与redis对齐,-1表示永不过期,-2表示已过期或不存在
+ */
+class DatabaseCache {
+ constructor({
+ collection = 'opendb-open-data'
+ } = {}) {
+ this.type = 'db'
+ this.collection = db.collection(collection)
+ }
+
+ _serializeValue(value) {
+ return value === undefined ? null : JSON.stringify(value)
+ }
+
+ _deserializeValue(value) {
+ return value ? JSON.parse(value) : value
+ }
+
+ async set(key, value, duration) {
+ validator.key(key)
+ validator.value(value)
+ validator.duration(duration)
+ value = this._serializeValue(value)
+ await this.collection.doc(key).set({
+ value,
+ expired: duration && duration !== -1 ? Date.now() + (duration * 1000) : -1
+ })
+ }
+
+ async _getWithDuration(key) {
+ const getKeyRes = await this.collection.doc(key).get()
+ const record = getKeyRes.data[0]
+ if (!record) {
+ return {
+ value: null,
+ duration: -2
+ }
+ }
+ const value = this._deserializeValue(record.value)
+ const expired = record.expired
+ if (expired === -1) {
+ return {
+ value,
+ duration: -1
+ }
+ }
+ const duration = expired - Date.now()
+ if (duration <= 0) {
+ await this.remove(key)
+ return {
+ value: null,
+ duration: -2
+ }
+ }
+ return {
+ value,
+ duration: Math.floor(duration / 1000)
+ }
+ }
+
+ async get(key, {
+ withDuration = true
+ } = {}) {
+ const result = await this._getWithDuration(key)
+ if (!withDuration) {
+ delete result.duration
+ }
+ return result
+ }
+
+ async remove(key) {
+ await this.collection.doc(key).remove()
+ }
+}
+
+class RedisCache {
+ constructor() {
+ this.type = 'redis'
+ this.redis = uniCloud.redis()
+ }
+
+ _serializeValue(value) {
+ return value === undefined ? null : JSON.stringify(value)
+ }
+
+ _deserializeValue(value) {
+ return value ? JSON.parse(value) : value
+ }
+
+ async set(key, value, duration) {
+ validator.key(key)
+ validator.value(value)
+ validator.duration(duration)
+ value = this._serializeValue(value)
+ if (!duration || duration === -1) {
+ await this.redis.set(key, value)
+ } else {
+ await this.redis.set(key, value, 'EX', duration)
+ }
+ }
+
+ async get(key, {
+ withDuration = false
+ } = {}) {
+ let value = await this.redis.get(key)
+ value = this._deserializeValue(value)
+ if (!withDuration) {
+ return {
+ value
+ }
+ }
+ const durationSecond = await this.redis.ttl(key)
+ let duration
+ switch (durationSecond) {
+ case -1:
+ duration = -1
+ break
+ case -2:
+ duration = -2
+ break
+ default:
+ duration = durationSecond
+ break
+ }
+ return {
+ value,
+ duration
+ }
+ }
+
+ async remove(key) {
+ await this.redis.del(key)
+ }
+}
+
+class Cache {
+ constructor({
+ type,
+ collection
+ } = {}) {
+ if (type === 'database') {
+ return new DatabaseCache({
+ collection
+ })
+ } else if (type === 'redis') {
+ return new RedisCache()
+ } else {
+ throw new Error('Invalid cache type')
+ }
+ }
+}
+
+class CacheKey {
+ constructor({
+ type,
+ collection,
+ cache,
+ key,
+ fallback
+ } = {}) {
+ this.cache = cache || new Cache({
+ type,
+ collection
+ })
+ this.key = key
+ this.fallback = fallback
+ }
+
+ async set(value, duration) {
+ await this.cache.set(this.key, value, duration)
+ }
+
+ async setWithSync(value, duration, syncMethod) {
+ await Promise.all([
+ this.set(this.key, value, duration),
+ syncMethod(value, duration)
+ ])
+ }
+
+ async get() {
+ let {
+ value,
+ duration
+ } = await this.cache.get(this.key)
+ if (value !== null && value !== undefined) {
+ return {
+ value,
+ duration
+ }
+ }
+ if (!this.fallback) {
+ return {
+ value: null,
+ duration: -2
+ }
+ }
+ const fallbackResult = await this.fallback()
+ value = fallbackResult.value
+ duration = fallbackResult.duration
+ if (value !== null && duration !== undefined) {
+ await this.cache.set(this.key, value, duration)
+ }
+ return {
+ value,
+ duration
+ }
+ }
+
+ async remove() {
+ await this.cache.remove(this.key)
+ }
+}
+
+class CacheKeyCascade {
+ constructor({
+ layers, // [{cache, type, collection, key}] 从低级到高级排序,[DbCacheKey, RedisCacheKey]
+ fallback
+ } = {}) {
+ this.layers = layers
+ this.cacheLayers = []
+ let lastCacheKey
+ for (let i = 0; i < layers.length; i++) {
+ const {
+ type,
+ cache,
+ collection,
+ key
+ } = layers[i]
+ const lastCacheKeyTemp = lastCacheKey
+ try {
+ const currentCacheKey = new CacheKey({
+ type,
+ collection,
+ cache,
+ key,
+ fallback: i === 0 ? fallback : function() {
+ return lastCacheKeyTemp.get()
+ }
+ })
+ this.cacheLayers.push(currentCacheKey)
+ lastCacheKey = currentCacheKey
+ } catch (e) {}
+ }
+ this.highLevelCache = lastCacheKey
+ }
+
+ async set(value, duration) {
+ return Promise.all(
+ this.cacheLayers.map(item => {
+ return item.set(value, duration)
+ })
+ )
+ }
+
+ async setWithSync(value, duration, syncMethod) {
+ const setPromise = this.cacheLayers.map(item => {
+ return item.set(value, duration)
+ })
+ return Promise.all(
+ [
+ ...setPromise,
+ syncMethod(value, duration)
+ ]
+ )
+ }
+
+ async get() {
+ return this.highLevelCache.get()
+ }
+
+ async remove() {
+ await Promise.all(
+ this.cacheLayers.map(cacheKeyItem => {
+ return cacheKeyItem.remove()
+ })
+ )
+ }
+}
+
+module.exports = {
+ Cache,
+ DatabaseCache,
+ RedisCache,
+ CacheKey,
+ CacheKeyCascade
+}
diff --git a/uni_modules/uni-open-bridge-common/uniCloud/cloudfunctions/common/uni-open-bridge-common/validator.js b/uni_modules/uni-open-bridge-common/uniCloud/cloudfunctions/common/uni-open-bridge-common/validator.js
new file mode 100644
index 0000000..47a455b
--- /dev/null
+++ b/uni_modules/uni-open-bridge-common/uniCloud/cloudfunctions/common/uni-open-bridge-common/validator.js
@@ -0,0 +1,31 @@
+const Validator = {
+
+ Key(keyArray, parameters) {
+ for (let i = 0; i < keyArray.length; i++) {
+ const keyName = keyArray[i]
+ if (typeof parameters[keyName] !== 'string') {
+ Validator.ThrowNewError(`Invalid ${keyName}`)
+ }
+ if (parameters[keyName].length < 1) {
+ Validator.ThrowNewError(`Invalid ${keyName}`)
+ }
+ }
+ },
+
+ Value(value) {
+ if (value === undefined) {
+ Validator.ThrowNewError('Invalid Value')
+ }
+ if (typeof value !== 'object') {
+ Validator.ThrowNewError('Invalid Value Type')
+ }
+ },
+
+ ThrowNewError(message) {
+ throw new Error(message)
+ }
+}
+
+module.exports = {
+ Validator
+}
diff --git a/uni_modules/uni-open-bridge-common/uniCloud/cloudfunctions/common/uni-open-bridge-common/weixin-server.js b/uni_modules/uni-open-bridge-common/uniCloud/cloudfunctions/common/uni-open-bridge-common/weixin-server.js
new file mode 100644
index 0000000..ef476f1
--- /dev/null
+++ b/uni_modules/uni-open-bridge-common/uniCloud/cloudfunctions/common/uni-open-bridge-common/weixin-server.js
@@ -0,0 +1,203 @@
+'use strict';
+
+const crypto = require('crypto')
+
+const {
+ HTTP_STATUS
+} = require('./consts.js')
+
+const {
+ BridgeError
+} = require('./bridge-error.js')
+
+class WeixinServer {
+
+ constructor(options = {}) {
+ this._appid = options.appid
+ this._secret = options.secret
+ }
+
+ getAccessToken() {
+ return uniCloud.httpclient.request(WeixinServer.AccessToken_Url, {
+ dataType: 'json',
+ method: 'POST',
+ contentType: 'json',
+ data: {
+ appid: this._appid,
+ secret: this._secret,
+ grant_type: "client_credential"
+ }
+ })
+ }
+
+ // 使用客户端获取的 code 从微信服务器换取 openid,code 仅可使用一次
+ codeToSession(code) {
+ return uniCloud.httpclient.request(WeixinServer.Code2Session_Url, {
+ dataType: 'json',
+ data: {
+ appid: this._appid,
+ secret: this._secret,
+ js_code: code,
+ grant_type: 'authorization_code'
+ }
+ })
+ }
+
+ getUserEncryptKey({
+ access_token,
+ openid,
+ session_key
+ }) {
+ console.log(access_token, openid, session_key);
+ const signature = crypto.createHmac('sha256', session_key).update('').digest('hex')
+ return uniCloud.httpclient.request(WeixinServer.User_Encrypt_Key_Url, {
+ dataType: 'json',
+ method: 'POST',
+ dataAsQueryString: true,
+ data: {
+ access_token,
+ openid: openid,
+ signature: signature,
+ sig_method: 'hmac_sha256'
+ }
+ })
+ }
+
+ getH5AccessToken() {
+ return uniCloud.httpclient.request(WeixinServer.AccessToken_H5_Url, {
+ dataType: 'json',
+ method: 'GET',
+ data: {
+ appid: this._appid,
+ secret: this._secret,
+ grant_type: "client_credential"
+ }
+ })
+ }
+
+ getH5Ticket(access_token) {
+ return uniCloud.httpclient.request(WeixinServer.Ticket_Url, {
+ dataType: 'json',
+ dataAsQueryString: true,
+ method: 'POST',
+ data: {
+ access_token
+ }
+ })
+ }
+
+ getH5AccessTokenForEip() {
+ return uniCloud.httpProxyForEip.postForm(WeixinServer.AccessToken_H5_Url, {
+ appid: this._appid,
+ secret: this._secret,
+ grant_type: "client_credential"
+ }, {
+ dataType: 'json'
+ })
+ }
+
+ getH5TicketForEip(access_token) {
+ return uniCloud.httpProxyForEip.postForm(WeixinServer.Ticket_Url, {
+ access_token
+ }, {
+ dataType: 'json',
+ dataAsQueryString: true
+ })
+ }
+}
+
+WeixinServer.AccessToken_Url = 'https://api.weixin.qq.com/cgi-bin/stable_token'
+WeixinServer.Code2Session_Url = 'https://api.weixin.qq.com/sns/jscode2session'
+WeixinServer.User_Encrypt_Key_Url = 'https://api.weixin.qq.com/wxa/business/getuserencryptkey'
+WeixinServer.AccessToken_H5_Url = 'https://api.weixin.qq.com/cgi-bin/token'
+WeixinServer.Ticket_Url = 'https://api.weixin.qq.com/cgi-bin/ticket/getticket?type=jsapi'
+
+WeixinServer.GetMPAccessToken = function(options) {
+ return new WeixinServer(options).getAccessToken()
+}
+
+WeixinServer.GetCodeToSession = function(options) {
+ return new WeixinServer(options).codeToSession(options.code)
+}
+
+WeixinServer.GetUserEncryptKey = function(options) {
+ return new WeixinServer(options).getUserEncryptKey(options)
+}
+
+WeixinServer.GetH5AccessToken = function(options) {
+ return new WeixinServer(options).getH5AccessToken()
+}
+
+WeixinServer.GetH5Ticket = function(options) {
+ return new WeixinServer(options).getH5Ticket(options.access_token)
+}
+
+////////////////////////////////////////////////////////////////
+
+function isAliyun() {
+ return (uniCloud.getCloudInfos()[0].provider === 'aliyun')
+}
+
+WeixinServer.GetResponseData = function(response) {
+ console.log("WeixinServer::response", response)
+
+ if (!(response.status === HTTP_STATUS.SUCCESS || response.statusCodeValue === HTTP_STATUS.SUCCESS)) {
+ throw new BridgeError(response.status || response.statusCodeValue, response.status || response.statusCodeValue)
+ }
+
+ const responseData = response.data || response.body
+
+ if (responseData.errcode !== undefined && responseData.errcode !== 0) {
+ throw new BridgeError(responseData.errcode, responseData.errmsg)
+ }
+
+ return responseData
+}
+
+WeixinServer.GetMPAccessTokenData = async function(options) {
+ const response = await new WeixinServer(options).getAccessToken()
+ return WeixinServer.GetResponseData(response)
+}
+
+WeixinServer.GetCodeToSessionData = async function(options) {
+ const response = await new WeixinServer(options).codeToSession(options.code)
+ return WeixinServer.GetResponseData(response)
+}
+
+WeixinServer.GetUserEncryptKeyData = async function(options) {
+ const response = await new WeixinServer(options).getUserEncryptKey(options)
+ return WeixinServer.GetResponseData(response)
+}
+
+WeixinServer.GetH5AccessTokenData = async function(options) {
+ const ws = new WeixinServer(options)
+ let response
+ if (isAliyun()) {
+ response = await ws.getH5AccessTokenForEip()
+ if (typeof response === 'string') {
+ response = JSON.parse(response)
+ }
+ } else {
+ response = await ws.getH5AccessToken()
+ }
+ return WeixinServer.GetResponseData(response)
+}
+
+WeixinServer.GetH5TicketData = async function(options) {
+ const ws = new WeixinServer(options)
+ let response
+ if (isAliyun()) {
+ response = await ws.getH5TicketForEip(options.access_token)
+ if (typeof response === 'string') {
+ response = JSON.parse(response)
+ }
+ } else {
+ response = await ws.getH5Ticket(options.access_token)
+ }
+ return WeixinServer.GetResponseData(response)
+}
+
+
+module.exports = {
+ WeixinServer
+}
diff --git a/uni_modules/uni-open-bridge-common/uniCloud/database/opendb-open-data.schema.json b/uni_modules/uni-open-bridge-common/uniCloud/database/opendb-open-data.schema.json
new file mode 100644
index 0000000..bc25098
--- /dev/null
+++ b/uni_modules/uni-open-bridge-common/uniCloud/database/opendb-open-data.schema.json
@@ -0,0 +1,19 @@
+// 文档教程: https://uniapp.dcloud.net.cn/uniCloud/schema
+{
+ "bsonType": "object",
+ "required": ["_id", "value"],
+ "properties": {
+ "_id": {
+ "bsonType": "string",
+ "description": "key,格式:uni-id:[provider]:[appid]:[openid]:[access-token|user-access-token|session-key|encrypt-key-version|ticket]"
+ },
+ "value": {
+ "bsonType": "object",
+ "description": "字段_id对应的值"
+ },
+ "expired": {
+ "bsonType": "date",
+ "description": "过期时间"
+ }
+ }
+}
diff --git a/uni_modules/uni-scss/changelog.md b/uni_modules/uni-scss/changelog.md
new file mode 100644
index 0000000..b863bb0
--- /dev/null
+++ b/uni_modules/uni-scss/changelog.md
@@ -0,0 +1,8 @@
+## 1.0.3(2022-01-21)
+- 优化 组件示例
+## 1.0.2(2021-11-22)
+- 修复 / 符号在 vue 不同版本兼容问题引起的报错问题
+## 1.0.1(2021-11-22)
+- 修复 vue3中scss语法兼容问题
+## 1.0.0(2021-11-18)
+- init
diff --git a/uni_modules/uni-scss/index.scss b/uni_modules/uni-scss/index.scss
new file mode 100644
index 0000000..1744a5f
--- /dev/null
+++ b/uni_modules/uni-scss/index.scss
@@ -0,0 +1 @@
+@import './styles/index.scss';
diff --git a/uni_modules/uni-scss/package.json b/uni_modules/uni-scss/package.json
new file mode 100644
index 0000000..7cc0ccb
--- /dev/null
+++ b/uni_modules/uni-scss/package.json
@@ -0,0 +1,82 @@
+{
+ "id": "uni-scss",
+ "displayName": "uni-scss 辅助样式",
+ "version": "1.0.3",
+ "description": "uni-sass是uni-ui提供的一套全局样式 ,通过一些简单的类名和sass变量,实现简单的页面布局操作,比如颜色、边距、圆角等。",
+ "keywords": [
+ "uni-scss",
+ "uni-ui",
+ "辅助样式"
+],
+ "repository": "https://github.com/dcloudio/uni-ui",
+ "engines": {
+ "HBuilderX": "^3.1.0"
+ },
+ "dcloudext": {
+ "category": [
+ "JS SDK",
+ "通用 SDK"
+ ],
+ "sale": {
+ "regular": {
+ "price": "0.00"
+ },
+ "sourcecode": {
+ "price": "0.00"
+ }
+ },
+ "contact": {
+ "qq": ""
+ },
+ "declaration": {
+ "ads": "无",
+ "data": "无",
+ "permissions": "无"
+ },
+ "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui"
+ },
+ "uni_modules": {
+ "dependencies": [],
+ "encrypt": [],
+ "platforms": {
+ "cloud": {
+ "tcb": "y",
+ "aliyun": "y"
+ },
+ "client": {
+ "App": {
+ "app-vue": "y",
+ "app-nvue": "u"
+ },
+ "H5-mobile": {
+ "Safari": "y",
+ "Android Browser": "y",
+ "微信浏览器(Android)": "y",
+ "QQ浏览器(Android)": "y"
+ },
+ "H5-pc": {
+ "Chrome": "y",
+ "IE": "y",
+ "Edge": "y",
+ "Firefox": "y",
+ "Safari": "y"
+ },
+ "小程序": {
+ "微信": "y",
+ "阿里": "y",
+ "百度": "y",
+ "字节跳动": "y",
+ "QQ": "y"
+ },
+ "快应用": {
+ "华为": "n",
+ "联盟": "n"
+ },
+ "Vue": {
+ "vue2": "y",
+ "vue3": "y"
+ }
+ }
+ }
+ }
+}
diff --git a/uni_modules/uni-scss/readme.md b/uni_modules/uni-scss/readme.md
new file mode 100644
index 0000000..b7d1c25
--- /dev/null
+++ b/uni_modules/uni-scss/readme.md
@@ -0,0 +1,4 @@
+`uni-sass` 是 `uni-ui`提供的一套全局样式 ,通过一些简单的类名和`sass`变量,实现简单的页面布局操作,比如颜色、边距、圆角等。
+
+### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-sass)
+#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839
\ No newline at end of file
diff --git a/uni_modules/uni-scss/styles/index.scss b/uni_modules/uni-scss/styles/index.scss
new file mode 100644
index 0000000..ffac4fe
--- /dev/null
+++ b/uni_modules/uni-scss/styles/index.scss
@@ -0,0 +1,7 @@
+@import './setting/_variables.scss';
+@import './setting/_border.scss';
+@import './setting/_color.scss';
+@import './setting/_space.scss';
+@import './setting/_radius.scss';
+@import './setting/_text.scss';
+@import './setting/_styles.scss';
diff --git a/uni_modules/uni-scss/styles/setting/_border.scss b/uni_modules/uni-scss/styles/setting/_border.scss
new file mode 100644
index 0000000..12a11c3
--- /dev/null
+++ b/uni_modules/uni-scss/styles/setting/_border.scss
@@ -0,0 +1,3 @@
+.uni-border {
+ border: 1px $uni-border-1 solid;
+}
\ No newline at end of file
diff --git a/uni_modules/uni-scss/styles/setting/_color.scss b/uni_modules/uni-scss/styles/setting/_color.scss
new file mode 100644
index 0000000..1ededd9
--- /dev/null
+++ b/uni_modules/uni-scss/styles/setting/_color.scss
@@ -0,0 +1,66 @@
+
+// TODO 暂时不需要 class ,需要用户使用变量实现 ,如果使用类名其实并不推荐
+// @mixin get-styles($k,$c) {
+// @if $k == size or $k == weight{
+// font-#{$k}:#{$c}
+// }@else{
+// #{$k}:#{$c}
+// }
+// }
+$uni-ui-color:(
+ // 主色
+ primary: $uni-primary,
+ primary-disable: $uni-primary-disable,
+ primary-light: $uni-primary-light,
+ // 辅助色
+ success: $uni-success,
+ success-disable: $uni-success-disable,
+ success-light: $uni-success-light,
+ warning: $uni-warning,
+ warning-disable: $uni-warning-disable,
+ warning-light: $uni-warning-light,
+ error: $uni-error,
+ error-disable: $uni-error-disable,
+ error-light: $uni-error-light,
+ info: $uni-info,
+ info-disable: $uni-info-disable,
+ info-light: $uni-info-light,
+ // 中性色
+ main-color: $uni-main-color,
+ base-color: $uni-base-color,
+ secondary-color: $uni-secondary-color,
+ extra-color: $uni-extra-color,
+ // 背景色
+ bg-color: $uni-bg-color,
+ // 边框颜色
+ border-1: $uni-border-1,
+ border-2: $uni-border-2,
+ border-3: $uni-border-3,
+ border-4: $uni-border-4,
+ // 黑色
+ black:$uni-black,
+ // 白色
+ white:$uni-white,
+ // 透明
+ transparent:$uni-transparent
+) !default;
+@each $key, $child in $uni-ui-color {
+ .uni-#{"" + $key} {
+ color: $child;
+ }
+ .uni-#{"" + $key}-bg {
+ background-color: $child;
+ }
+}
+.uni-shadow-sm {
+ box-shadow: $uni-shadow-sm;
+}
+.uni-shadow-base {
+ box-shadow: $uni-shadow-base;
+}
+.uni-shadow-lg {
+ box-shadow: $uni-shadow-lg;
+}
+.uni-mask {
+ background-color:$uni-mask;
+}
diff --git a/uni_modules/uni-scss/styles/setting/_radius.scss b/uni_modules/uni-scss/styles/setting/_radius.scss
new file mode 100644
index 0000000..9a0428b
--- /dev/null
+++ b/uni_modules/uni-scss/styles/setting/_radius.scss
@@ -0,0 +1,55 @@
+@mixin radius($r,$d:null ,$important: false){
+ $radius-value:map-get($uni-radius, $r) if($important, !important, null);
+ // Key exists within the $uni-radius variable
+ @if (map-has-key($uni-radius, $r) and $d){
+ @if $d == t {
+ border-top-left-radius:$radius-value;
+ border-top-right-radius:$radius-value;
+ }@else if $d == r {
+ border-top-right-radius:$radius-value;
+ border-bottom-right-radius:$radius-value;
+ }@else if $d == b {
+ border-bottom-left-radius:$radius-value;
+ border-bottom-right-radius:$radius-value;
+ }@else if $d == l {
+ border-top-left-radius:$radius-value;
+ border-bottom-left-radius:$radius-value;
+ }@else if $d == tl {
+ border-top-left-radius:$radius-value;
+ }@else if $d == tr {
+ border-top-right-radius:$radius-value;
+ }@else if $d == br {
+ border-bottom-right-radius:$radius-value;
+ }@else if $d == bl {
+ border-bottom-left-radius:$radius-value;
+ }
+ }@else{
+ border-radius:$radius-value;
+ }
+}
+
+@each $key, $child in $uni-radius {
+ @if($key){
+ .uni-radius-#{"" + $key} {
+ @include radius($key)
+ }
+ }@else{
+ .uni-radius {
+ @include radius($key)
+ }
+ }
+}
+
+@each $direction in t, r, b, l,tl, tr, br, bl {
+ @each $key, $child in $uni-radius {
+ @if($key){
+ .uni-radius-#{"" + $direction}-#{"" + $key} {
+ @include radius($key,$direction,false)
+ }
+ }@else{
+ .uni-radius-#{$direction} {
+ @include radius($key,$direction,false)
+ }
+ }
+ }
+}
diff --git a/uni_modules/uni-scss/styles/setting/_space.scss b/uni_modules/uni-scss/styles/setting/_space.scss
new file mode 100644
index 0000000..3c89528
--- /dev/null
+++ b/uni_modules/uni-scss/styles/setting/_space.scss
@@ -0,0 +1,56 @@
+
+@mixin fn($space,$direction,$size,$n) {
+ @if $n {
+ #{$space}-#{$direction}: #{$size*$uni-space-root}px
+ } @else {
+ #{$space}-#{$direction}: #{-$size*$uni-space-root}px
+ }
+}
+@mixin get-styles($direction,$i,$space,$n){
+ @if $direction == t {
+ @include fn($space, top,$i,$n);
+ }
+ @if $direction == r {
+ @include fn($space, right,$i,$n);
+ }
+ @if $direction == b {
+ @include fn($space, bottom,$i,$n);
+ }
+ @if $direction == l {
+ @include fn($space, left,$i,$n);
+ }
+ @if $direction == x {
+ @include fn($space, left,$i,$n);
+ @include fn($space, right,$i,$n);
+ }
+ @if $direction == y {
+ @include fn($space, top,$i,$n);
+ @include fn($space, bottom,$i,$n);
+ }
+ @if $direction == a {
+ @if $n {
+ #{$space}:#{$i*$uni-space-root}px;
+ } @else {
+ #{$space}:#{-$i*$uni-space-root}px;
+ }
+ }
+}
+
+@each $orientation in m,p {
+ $space: margin;
+ @if $orientation == m {
+ $space: margin;
+ } @else {
+ $space: padding;
+ }
+ @for $i from 0 through 16 {
+ @each $direction in t, r, b, l, x, y, a {
+ .uni-#{$orientation}#{$direction}-#{$i} {
+ @include get-styles($direction,$i,$space,true);
+ }
+ .uni-#{$orientation}#{$direction}-n#{$i} {
+ @include get-styles($direction,$i,$space,false);
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/uni_modules/uni-scss/styles/setting/_styles.scss b/uni_modules/uni-scss/styles/setting/_styles.scss
new file mode 100644
index 0000000..689afec
--- /dev/null
+++ b/uni_modules/uni-scss/styles/setting/_styles.scss
@@ -0,0 +1,167 @@
+/* #ifndef APP-NVUE */
+
+$-color-white:#fff;
+$-color-black:#000;
+@mixin base-style($color) {
+ color: #fff;
+ background-color: $color;
+ border-color: mix($-color-black, $color, 8%);
+ &:not([hover-class]):active {
+ background: mix($-color-black, $color, 10%);
+ border-color: mix($-color-black, $color, 20%);
+ color: $-color-white;
+ outline: none;
+ }
+}
+@mixin is-color($color) {
+ @include base-style($color);
+ &[loading] {
+ @include base-style($color);
+ &::before {
+ margin-right:5px;
+ }
+ }
+ &[disabled] {
+ &,
+ &[loading],
+ &:not([hover-class]):active {
+ color: $-color-white;
+ border-color: mix(darken($color,10%), $-color-white);
+ background-color: mix($color, $-color-white);
+ }
+ }
+
+}
+@mixin base-plain-style($color) {
+ color:$color;
+ background-color: mix($-color-white, $color, 90%);
+ border-color: mix($-color-white, $color, 70%);
+ &:not([hover-class]):active {
+ background: mix($-color-white, $color, 80%);
+ color: $color;
+ outline: none;
+ border-color: mix($-color-white, $color, 50%);
+ }
+}
+@mixin is-plain($color){
+ &[plain] {
+ @include base-plain-style($color);
+ &[loading] {
+ @include base-plain-style($color);
+ &::before {
+ margin-right:5px;
+ }
+ }
+ &[disabled] {
+ &,
+ &:active {
+ color: mix($-color-white, $color, 40%);
+ background-color: mix($-color-white, $color, 90%);
+ border-color: mix($-color-white, $color, 80%);
+ }
+ }
+ }
+}
+
+
+.uni-btn {
+ margin: 5px;
+ color: #393939;
+ border:1px solid #ccc;
+ font-size: 16px;
+ font-weight: 200;
+ background-color: #F9F9F9;
+ // TODO 暂时处理边框隐藏一边的问题
+ overflow: visible;
+ &::after{
+ border: none;
+ }
+
+ &:not([type]),&[type=default] {
+ color: #999;
+ &[loading] {
+ background: none;
+ &::before {
+ margin-right:5px;
+ }
+ }
+
+
+
+ &[disabled]{
+ color: mix($-color-white, #999, 60%);
+ &,
+ &[loading],
+ &:active {
+ color: mix($-color-white, #999, 60%);
+ background-color: mix($-color-white,$-color-black , 98%);
+ border-color: mix($-color-white, #999, 85%);
+ }
+ }
+
+ &[plain] {
+ color: #999;
+ background: none;
+ border-color: $uni-border-1;
+ &:not([hover-class]):active {
+ background: none;
+ color: mix($-color-white, $-color-black, 80%);
+ border-color: mix($-color-white, $-color-black, 90%);
+ outline: none;
+ }
+ &[disabled]{
+ &,
+ &[loading],
+ &:active {
+ background: none;
+ color: mix($-color-white, #999, 60%);
+ border-color: mix($-color-white, #999, 85%);
+ }
+ }
+ }
+ }
+
+ &:not([hover-class]):active {
+ color: mix($-color-white, $-color-black, 50%);
+ }
+
+ &[size=mini] {
+ font-size: 16px;
+ font-weight: 200;
+ border-radius: 8px;
+ }
+
+
+
+ &.uni-btn-small {
+ font-size: 14px;
+ }
+ &.uni-btn-mini {
+ font-size: 12px;
+ }
+
+ &.uni-btn-radius {
+ border-radius: 999px;
+ }
+ &[type=primary] {
+ @include is-color($uni-primary);
+ @include is-plain($uni-primary)
+ }
+ &[type=success] {
+ @include is-color($uni-success);
+ @include is-plain($uni-success)
+ }
+ &[type=error] {
+ @include is-color($uni-error);
+ @include is-plain($uni-error)
+ }
+ &[type=warning] {
+ @include is-color($uni-warning);
+ @include is-plain($uni-warning)
+ }
+ &[type=info] {
+ @include is-color($uni-info);
+ @include is-plain($uni-info)
+ }
+}
+/* #endif */
diff --git a/uni_modules/uni-scss/styles/setting/_text.scss b/uni_modules/uni-scss/styles/setting/_text.scss
new file mode 100644
index 0000000..a34d08f
--- /dev/null
+++ b/uni_modules/uni-scss/styles/setting/_text.scss
@@ -0,0 +1,24 @@
+@mixin get-styles($k,$c) {
+ @if $k == size or $k == weight{
+ font-#{$k}:#{$c}
+ }@else{
+ #{$k}:#{$c}
+ }
+}
+
+@each $key, $child in $uni-headings {
+ /* #ifndef APP-NVUE */
+ .uni-#{$key} {
+ @each $k, $c in $child {
+ @include get-styles($k,$c)
+ }
+ }
+ /* #endif */
+ /* #ifdef APP-NVUE */
+ .container .uni-#{$key} {
+ @each $k, $c in $child {
+ @include get-styles($k,$c)
+ }
+ }
+ /* #endif */
+}
diff --git a/uni_modules/uni-scss/styles/setting/_variables.scss b/uni_modules/uni-scss/styles/setting/_variables.scss
new file mode 100644
index 0000000..557d3d7
--- /dev/null
+++ b/uni_modules/uni-scss/styles/setting/_variables.scss
@@ -0,0 +1,146 @@
+// @use "sass:math";
+@import '../tools/functions.scss';
+// 间距基础倍数
+$uni-space-root: 2 !default;
+// 边框半径默认值
+$uni-radius-root:5px !default;
+$uni-radius: () !default;
+// 边框半径断点
+$uni-radius: map-deep-merge(
+ (
+ 0: 0,
+ // TODO 当前版本暂时不支持 sm 属性
+ // 'sm': math.div($uni-radius-root, 2),
+ null: $uni-radius-root,
+ 'lg': $uni-radius-root * 2,
+ 'xl': $uni-radius-root * 6,
+ 'pill': 9999px,
+ 'circle': 50%
+ ),
+ $uni-radius
+);
+// 字体家族
+$body-font-family: 'Roboto', sans-serif !default;
+// 文本
+$heading-font-family: $body-font-family !default;
+$uni-headings: () !default;
+$letterSpacing: -0.01562em;
+$uni-headings: map-deep-merge(
+ (
+ 'h1': (
+ size: 32px,
+ weight: 300,
+ line-height: 50px,
+ // letter-spacing:-0.01562em
+ ),
+ 'h2': (
+ size: 28px,
+ weight: 300,
+ line-height: 40px,
+ // letter-spacing: -0.00833em
+ ),
+ 'h3': (
+ size: 24px,
+ weight: 400,
+ line-height: 32px,
+ // letter-spacing: normal
+ ),
+ 'h4': (
+ size: 20px,
+ weight: 400,
+ line-height: 30px,
+ // letter-spacing: 0.00735em
+ ),
+ 'h5': (
+ size: 16px,
+ weight: 400,
+ line-height: 24px,
+ // letter-spacing: normal
+ ),
+ 'h6': (
+ size: 14px,
+ weight: 500,
+ line-height: 18px,
+ // letter-spacing: 0.0125em
+ ),
+ 'subtitle': (
+ size: 12px,
+ weight: 400,
+ line-height: 20px,
+ // letter-spacing: 0.00937em
+ ),
+ 'body': (
+ font-size: 14px,
+ font-weight: 400,
+ line-height: 22px,
+ // letter-spacing: 0.03125em
+ ),
+ 'caption': (
+ 'size': 12px,
+ 'weight': 400,
+ 'line-height': 20px,
+ // 'letter-spacing': 0.03333em,
+ // 'text-transform': false
+ )
+ ),
+ $uni-headings
+);
+
+
+
+// 主色
+$uni-primary: #2979ff !default;
+$uni-primary-disable:lighten($uni-primary,20%) !default;
+$uni-primary-light: lighten($uni-primary,25%) !default;
+
+// 辅助色
+// 除了主色外的场景色,需要在不同的场景中使用(例如危险色表示危险的操作)。
+$uni-success: #18bc37 !default;
+$uni-success-disable:lighten($uni-success,20%) !default;
+$uni-success-light: lighten($uni-success,25%) !default;
+
+$uni-warning: #f3a73f !default;
+$uni-warning-disable:lighten($uni-warning,20%) !default;
+$uni-warning-light: lighten($uni-warning,25%) !default;
+
+$uni-error: #e43d33 !default;
+$uni-error-disable:lighten($uni-error,20%) !default;
+$uni-error-light: lighten($uni-error,25%) !default;
+
+$uni-info: #8f939c !default;
+$uni-info-disable:lighten($uni-info,20%) !default;
+$uni-info-light: lighten($uni-info,25%) !default;
+
+// 中性色
+// 中性色用于文本、背景和边框颜色。通过运用不同的中性色,来表现层次结构。
+$uni-main-color: #3a3a3a !default; // 主要文字
+$uni-base-color: #6a6a6a !default; // 常规文字
+$uni-secondary-color: #909399 !default; // 次要文字
+$uni-extra-color: #c7c7c7 !default; // 辅助说明
+
+// 边框颜色
+$uni-border-1: #F0F0F0 !default;
+$uni-border-2: #EDEDED !default;
+$uni-border-3: #DCDCDC !default;
+$uni-border-4: #B9B9B9 !default;
+
+// 常规色
+$uni-black: #000000 !default;
+$uni-white: #ffffff !default;
+$uni-transparent: rgba($color: #000000, $alpha: 0) !default;
+
+// 背景色
+$uni-bg-color: #f7f7f7 !default;
+
+/* 水平间距 */
+$uni-spacing-sm: 8px !default;
+$uni-spacing-base: 15px !default;
+$uni-spacing-lg: 30px !default;
+
+// 阴影
+$uni-shadow-sm:0 0 5px rgba($color: #d8d8d8, $alpha: 0.5) !default;
+$uni-shadow-base:0 1px 8px 1px rgba($color: #a5a5a5, $alpha: 0.2) !default;
+$uni-shadow-lg:0px 1px 10px 2px rgba($color: #a5a4a4, $alpha: 0.5) !default;
+
+// 蒙版
+$uni-mask: rgba($color: #000000, $alpha: 0.4) !default;
diff --git a/uni_modules/uni-scss/styles/tools/functions.scss b/uni_modules/uni-scss/styles/tools/functions.scss
new file mode 100644
index 0000000..ac6f63e
--- /dev/null
+++ b/uni_modules/uni-scss/styles/tools/functions.scss
@@ -0,0 +1,19 @@
+// 合并 map
+@function map-deep-merge($parent-map, $child-map){
+ $result: $parent-map;
+ @each $key, $child in $child-map {
+ $parent-has-key: map-has-key($result, $key);
+ $parent-value: map-get($result, $key);
+ $parent-type: type-of($parent-value);
+ $child-type: type-of($child);
+ $parent-is-map: $parent-type == map;
+ $child-is-map: $child-type == map;
+
+ @if (not $parent-has-key) or ($parent-type != $child-type) or (not ($parent-is-map and $child-is-map)){
+ $result: map-merge($result, ( $key: $child ));
+ }@else {
+ $result: map-merge($result, ( $key: map-deep-merge($parent-value, $child) ));
+ }
+ }
+ @return $result;
+};
diff --git a/uni_modules/uni-scss/theme.scss b/uni_modules/uni-scss/theme.scss
new file mode 100644
index 0000000..80ee62f
--- /dev/null
+++ b/uni_modules/uni-scss/theme.scss
@@ -0,0 +1,31 @@
+// 间距基础倍数
+$uni-space-root: 2;
+// 边框半径默认值
+$uni-radius-root:5px;
+// 主色
+$uni-primary: #2979ff;
+// 辅助色
+$uni-success: #4cd964;
+// 警告色
+$uni-warning: #f0ad4e;
+// 错误色
+$uni-error: #dd524d;
+// 描述色
+$uni-info: #909399;
+// 中性色
+$uni-main-color: #303133;
+$uni-base-color: #606266;
+$uni-secondary-color: #909399;
+$uni-extra-color: #C0C4CC;
+// 背景色
+$uni-bg-color: #f5f5f5;
+// 边框颜色
+$uni-border-1: #DCDFE6;
+$uni-border-2: #E4E7ED;
+$uni-border-3: #EBEEF5;
+$uni-border-4: #F2F6FC;
+
+// 常规色
+$uni-black: #000000;
+$uni-white: #ffffff;
+$uni-transparent: rgba($color: #000000, $alpha: 0);
diff --git a/uni_modules/uni-scss/variables.scss b/uni_modules/uni-scss/variables.scss
new file mode 100644
index 0000000..1c062d4
--- /dev/null
+++ b/uni_modules/uni-scss/variables.scss
@@ -0,0 +1,62 @@
+@import './styles/setting/_variables.scss';
+// 间距基础倍数
+$uni-space-root: 2;
+// 边框半径默认值
+$uni-radius-root:5px;
+
+// 主色
+$uni-primary: #2979ff;
+$uni-primary-disable:mix(#fff,$uni-primary,50%);
+$uni-primary-light: mix(#fff,$uni-primary,80%);
+
+// 辅助色
+// 除了主色外的场景色,需要在不同的场景中使用(例如危险色表示危险的操作)。
+$uni-success: #18bc37;
+$uni-success-disable:mix(#fff,$uni-success,50%);
+$uni-success-light: mix(#fff,$uni-success,80%);
+
+$uni-warning: #f3a73f;
+$uni-warning-disable:mix(#fff,$uni-warning,50%);
+$uni-warning-light: mix(#fff,$uni-warning,80%);
+
+$uni-error: #e43d33;
+$uni-error-disable:mix(#fff,$uni-error,50%);
+$uni-error-light: mix(#fff,$uni-error,80%);
+
+$uni-info: #8f939c;
+$uni-info-disable:mix(#fff,$uni-info,50%);
+$uni-info-light: mix(#fff,$uni-info,80%);
+
+// 中性色
+// 中性色用于文本、背景和边框颜色。通过运用不同的中性色,来表现层次结构。
+$uni-main-color: #3a3a3a; // 主要文字
+$uni-base-color: #6a6a6a; // 常规文字
+$uni-secondary-color: #909399; // 次要文字
+$uni-extra-color: #c7c7c7; // 辅助说明
+
+// 边框颜色
+$uni-border-1: #F0F0F0;
+$uni-border-2: #EDEDED;
+$uni-border-3: #DCDCDC;
+$uni-border-4: #B9B9B9;
+
+// 常规色
+$uni-black: #000000;
+$uni-white: #ffffff;
+$uni-transparent: rgba($color: #000000, $alpha: 0);
+
+// 背景色
+$uni-bg-color: #f7f7f7;
+
+/* 水平间距 */
+$uni-spacing-sm: 8px;
+$uni-spacing-base: 15px;
+$uni-spacing-lg: 30px;
+
+// 阴影
+$uni-shadow-sm:0 0 5px rgba($color: #d8d8d8, $alpha: 0.5);
+$uni-shadow-base:0 1px 8px 1px rgba($color: #a5a5a5, $alpha: 0.2);
+$uni-shadow-lg:0px 1px 10px 2px rgba($color: #a5a4a4, $alpha: 0.5);
+
+// 蒙版
+$uni-mask: rgba($color: #000000, $alpha: 0.4);
diff --git a/uni_modules/uni-swiper-dot/changelog.md b/uni_modules/uni-swiper-dot/changelog.md
new file mode 100644
index 0000000..85cf54d
--- /dev/null
+++ b/uni_modules/uni-swiper-dot/changelog.md
@@ -0,0 +1,12 @@
+## 1.2.0(2021-11-19)
+- 优化 组件UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource)
+- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-swiper-dot](https://uniapp.dcloud.io/component/uniui/uni-swiper-dot)
+## 1.1.0(2021-07-30)
+- 组件兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834)
+## 1.0.6(2021-05-12)
+- 新增 示例地址
+- 修复 示例项目缺少组件的Bug
+## 1.0.5(2021-02-05)
+- 调整为uni_modules目录规范
+- 新增 clickItem 事件,支持指示点控制轮播
+- 新增 支持 pc 可用
diff --git a/uni_modules/uni-swiper-dot/components/uni-swiper-dot/uni-swiper-dot.vue b/uni_modules/uni-swiper-dot/components/uni-swiper-dot/uni-swiper-dot.vue
new file mode 100644
index 0000000..b222c0f
--- /dev/null
+++ b/uni_modules/uni-swiper-dot/components/uni-swiper-dot/uni-swiper-dot.vue
@@ -0,0 +1,218 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ (current+1)+"/"+info.length +' ' +info[current][field] }}
+
+
+ {{ index+1 }}
+
+
+
+
+
+
+
diff --git a/uni_modules/uni-swiper-dot/package.json b/uni_modules/uni-swiper-dot/package.json
new file mode 100644
index 0000000..f2dd8d2
--- /dev/null
+++ b/uni_modules/uni-swiper-dot/package.json
@@ -0,0 +1,87 @@
+{
+ "id": "uni-swiper-dot",
+ "displayName": "uni-swiper-dot 轮播图指示点",
+ "version": "1.2.0",
+ "description": "自定义轮播图指示点组件",
+ "keywords": [
+ "uni-ui",
+ "uniui",
+ "轮播图指示点",
+ "dot",
+ "swiper"
+],
+ "repository": "https://github.com/dcloudio/uni-ui",
+ "engines": {
+ "HBuilderX": ""
+ },
+ "directories": {
+ "example": "../../temps/example_temps"
+ },
+ "dcloudext": {
+ "category": [
+ "前端组件",
+ "通用组件"
+ ],
+ "sale": {
+ "regular": {
+ "price": "0.00"
+ },
+ "sourcecode": {
+ "price": "0.00"
+ }
+ },
+ "contact": {
+ "qq": ""
+ },
+ "declaration": {
+ "ads": "无",
+ "data": "无",
+ "permissions": "无"
+ },
+ "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui"
+ },
+ "uni_modules": {
+ "dependencies": ["uni-scss"],
+ "encrypt": [],
+ "platforms": {
+ "cloud": {
+ "tcb": "y",
+ "aliyun": "y"
+ },
+ "client": {
+ "App": {
+ "app-vue": "y",
+ "app-nvue": "y"
+ },
+ "H5-mobile": {
+ "Safari": "y",
+ "Android Browser": "y",
+ "微信浏览器(Android)": "y",
+ "QQ浏览器(Android)": "y"
+ },
+ "H5-pc": {
+ "Chrome": "y",
+ "IE": "y",
+ "Edge": "y",
+ "Firefox": "y",
+ "Safari": "y"
+ },
+ "小程序": {
+ "微信": "y",
+ "阿里": "y",
+ "百度": "y",
+ "字节跳动": "y",
+ "QQ": "y"
+ },
+ "快应用": {
+ "华为": "u",
+ "联盟": "u"
+ },
+ "Vue": {
+ "vue2": "y",
+ "vue3": "y"
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/uni_modules/uni-swiper-dot/readme.md b/uni_modules/uni-swiper-dot/readme.md
new file mode 100644
index 0000000..7d397e2
--- /dev/null
+++ b/uni_modules/uni-swiper-dot/readme.md
@@ -0,0 +1,11 @@
+
+
+## SwiperDot 轮播图指示点
+> **组件名:uni-swiper-dot**
+> 代码块: `uSwiperDot`
+
+
+自定义轮播图指示点
+
+### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-swiper-dot)
+#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839
\ No newline at end of file
diff --git a/uni_modules/uview-ui/LICENSE b/uni_modules/uview-ui/LICENSE
new file mode 100644
index 0000000..4db40ef
--- /dev/null
+++ b/uni_modules/uview-ui/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2023 www.uviewui.com
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/uni_modules/uview-ui/README.md b/uni_modules/uview-ui/README.md
new file mode 100644
index 0000000..c78ff47
--- /dev/null
+++ b/uni_modules/uview-ui/README.md
@@ -0,0 +1,66 @@
+
+
+
+uView 2.0
+多平台快速开发的UI框架
+
+[![stars](https://img.shields.io/github/stars/umicro/uView2.0?style=flat-square&logo=GitHub)](https://github.com/umicro/uView2.0)
+[![forks](https://img.shields.io/github/forks/umicro/uView2.0?style=flat-square&logo=GitHub)](https://github.com/umicro/uView2.0)
+[![issues](https://img.shields.io/github/issues/umicro/uView2.0?style=flat-square&logo=GitHub)](https://github.com/umicro/uView2.0/issues)
+[![Website](https://img.shields.io/badge/uView-up-blue?style=flat-square)](https://uviewui.com)
+[![release](https://img.shields.io/github/v/release/umicro/uView2.0?style=flat-square)](https://gitee.com/umicro/uView2.0/releases)
+[![license](https://img.shields.io/github/license/umicro/uView2.0?style=flat-square)](https://en.wikipedia.org/wiki/MIT_License)
+
+## 说明
+
+uView UI,是[uni-app](https://uniapp.dcloud.io/)全面兼容nvue的uni-app生态框架,全面的组件和便捷的工具会让您信手拈来,如鱼得水
+
+## [官方文档:https://uviewui.com](https://uviewui.com)
+
+
+## 预览
+
+您可以通过**微信**扫码,查看最佳的演示效果。
+
+
+
+
+
+## 链接
+
+- [官方文档](https://www.uviewui.com/)
+- [更新日志](https://www.uviewui.com/components/changelog.html)
+- [升级指南](https://www.uviewui.com/components/changeGuide.html)
+- [关于我们](https://www.uviewui.com/cooperation/about.html)
+
+## 交流反馈
+
+欢迎加入我们的QQ群交流反馈:[点此跳转](https://www.uviewui.com/components/addQQGroup.html)
+
+## 关于PR
+
+> 我们非常乐意接受各位的优质PR,但在此之前我希望您了解uView2.0是一个需要兼容多个平台的(小程序、h5、ios app、android app)包括nvue页面、vue页面。
+> 所以希望在您修复bug并提交之前尽可能的去这些平台测试一下兼容性。最好能携带测试截图以方便审核。非常感谢!
+
+## 安装
+
+#### **uni-app插件市场链接** —— [https://ext.dcloud.net.cn/plugin?id=1593](https://ext.dcloud.net.cn/plugin?id=1593)
+
+请通过[官网安装文档](https://www.uviewui.com/components/install.html)了解更详细的内容
+
+## 快速上手
+
+请通过[快速上手](https://uviewui.com/components/quickstart.html)了解更详细的内容
+
+## 使用方法
+配置easycom规则后,自动按需引入,无需`import`组件,直接引用即可。
+
+```html
+
+
+
+```
+
+## 版权信息
+uView遵循[MIT](https://en.wikipedia.org/wiki/MIT_License)开源协议,意味着您无需支付任何费用,也无需授权,即可将uView应用到您的产品中。
+
diff --git a/uni_modules/uview-ui/changelog.md b/uni_modules/uview-ui/changelog.md
new file mode 100644
index 0000000..f2bae72
--- /dev/null
+++ b/uni_modules/uview-ui/changelog.md
@@ -0,0 +1,362 @@
+## 2.0.36(2023-03-27)
+# uView2.0重磅发布,利剑出鞘,一统江湖
+
+1. 重构`deepClone` & `deepMerge`方法
+2. 其他优化
+## 2.0.34(2022-09-24)
+# uView2.0重磅发布,利剑出鞘,一统江湖
+
+1. `u-input`、`u-textarea`增加`ignoreCompositionEvent`属性
+2. 修复`route`方法调用可能报错的问题
+3. 修复`u-no-network`组件`z-index`无效的问题
+4. 修复`textarea`组件在h5上confirmType=""报错的问题
+5. `u-rate`适配`nvue`
+6. 优化验证手机号码的正则表达式(根据工信部发布的《电信网编号计划(2017年版)》进行修改。)
+7. `form-item`添加`labelPosition`属性
+8. `u-calendar`修复`maxDate`设置为当前日期,并且当前时间大于08:00时无法显示日期列表的问题 (#724)
+9. `u-radio`增加一个默认插槽用于自定义修改label内容 (#680)
+10. 修复`timeFormat`函数在safari重的兼容性问题 (#664)
+## 2.0.33(2022-06-17)
+# uView2.0重磅发布,利剑出鞘,一统江湖
+
+1. 修复`loadmore`组件`lineColor`类型错误问题
+2. 修复`u-parse`组件`imgtap`、`linktap`不生效问题
+## 2.0.32(2022-06-16)
+# uView2.0重磅发布,利剑出鞘,一统江湖
+1. `u-loadmore`新增自定义颜色、虚/实线
+2. 修复`u-swiper-action`组件部分平台不能上下滑动的问题
+3. 修复`u-list`回弹问题
+4. 修复`notice-bar`组件动画在低端安卓机可能会抖动的问题
+5. `u-loading-page`添加控制图标大小的属性`iconSize`
+6. 修复`u-tooltip`组件`color`参数不生效的问题
+7. 修复`u--input`组件使用`blur`事件输出为`undefined`的bug
+8. `u-code-input`组件新增键盘弹起时,是否自动上推页面参数`adjustPosition`
+9. 修复`image`组件`load`事件无回调对象问题
+10. 修复`button`组件`loadingSize`设置无效问题
+10. 其他修复
+## 2.0.31(2022-04-19)
+# uView2.0重磅发布,利剑出鞘,一统江湖
+
+1. 修复`upload`在`vue`页面上传成功后没有成功标志的问题
+2. 解决演示项目中微信小程序模拟上传图片一直出于上传中问题
+3. 修复`u-code-input`组件在`nvue`页面编译到`app`平台上光标异常问题(`app`去除此功能)
+4. 修复`actionSheet`组件标题关闭按钮点击事件名称错误的问题
+5. 其他修复
+## 2.0.30(2022-04-04)
+# uView2.0重磅发布,利剑出鞘,一统江湖
+
+1. `u-rate`增加`readonly`属性
+2. `tabs`滑块支持设置背景图片
+3. 修复`u-subsection` `mode`为`subsection`时,滑块样式不正确的问题
+4. `u-code-input`添加光标效果动画
+5. 修复`popup`的`open`事件不触发
+6. 修复`u-flex-column`无效的问题
+7. 修复`u-datetime-picker`索引在特定场合异常问题
+8. 修复`u-datetime-picker`最小时间字符串模板错误问题
+9. `u-swiper`添加`m3u8`验证
+10. `u-swiper`修改判断image和video逻辑
+11. 修复`swiper`无法使用本地图片问题,增加`type`参数
+12. 修复`u-row-notice`格式错误问题
+13. 修复`u-switch`组件当`unit`为`rpx`时,`nodeStyle`消失的问题
+14. 修复`datetime-picker`组件`showToolbar`与`visibleItemCount`属性无效的问题
+15. 修复`upload`组件条件编译位置判断错误,导致`previewImage`属性设置为`false`时,整个组件都会被隐藏的问题
+16. 修复`u-checkbox-group`设置`shape`属性无效的问题
+17. 修复`u-upload`的`capture`传入字符串的时候不生效的问题
+18. 修复`u-action-sheet`组件,关闭事件逻辑错误的问题
+19. 修复`u-list`触顶事件的触发错误的问题
+20. 修复`u-text`只有手机号可拨打的问题
+21. 修复`u-textarea`不能换行的问题
+22. 其他修复
+## 2.0.29(2022-03-13)
+# uView2.0重磅发布,利剑出鞘,一统江湖
+
+1. 修复`u--text`组件设置`decoration`属性未生效的问题
+2. 修复`u-datetime-picker`使用`formatter`后返回值不正确
+3. 修复`u-datetime-picker` `intercept` 可能为undefined
+4. 修复已设置单位 uni..config.unit = 'rpx'时,线型指示器 `transform` 的位置翻倍,导致指示器超出宽度
+5. 修复mixin中bem方法生成的类名在支付宝和字节小程序中失效
+6. 修复默认值传值为空的时候,打开`u-datetime-picker`报错,不能选中第一列时间的bug
+7. 修复`u-datetime-picker`使用`formatter`后返回值不正确
+8. 修复`u-image`组件`loading`无效果的问题
+9. 修复`config.unit`属性设为`rpx`时,导航栏占用高度不足导致塌陷的问题
+10. 修复`u-datetime-picker`组件`itemHeight`无效问题
+11. 其他修复
+## 2.0.28(2022-02-22)
+# uView2.0重磅发布,利剑出鞘,一统江湖
+
+1. search组件新增searchIconSize属性
+2. 兼容Safari/Webkit中传入时间格式如2022-02-17 12:00:56
+3. 修复text value.js 判断日期出format错误问题
+4. priceFormat格式化金额出现精度错误
+5. priceFormat在部分情况下出现精度损失问题
+6. 优化表单rules提示
+7. 修复avatar组件src为空时,展示状态不对
+8. 其他修复
+## 2.0.27(2022-01-28)
+# uView2.0重磅发布,利剑出鞘,一统江湖
+
+1.样式修复
+## 2.0.26(2022-01-28)
+# uView2.0重磅发布,利剑出鞘,一统江湖
+
+1.样式修复
+## 2.0.25(2022-01-27)
+# uView2.0重磅发布,利剑出鞘,一统江湖
+
+1. 修复text组件mode=price时,可能会导致精度错误的问题
+2. 添加$u.setConfig()方法,可设置uView内置的config, props, zIndex, color属性,详见:[修改uView内置配置方案](https://uviewui.com/components/setting.html#%E9%BB%98%E8%AE%A4%E5%8D%95%E4%BD%8D%E9%85%8D%E7%BD%AE)
+3. 优化form组件在errorType=toast时,如果输入错误页面会有抖动的问题
+4. 修复$u.addUnit()对配置默认单位可能无效的问题
+## 2.0.24(2022-01-25)
+# uView2.0重磅发布,利剑出鞘,一统江湖
+
+1. 修复swiper在current指定非0时缩放有误
+2. 修复u-icon添加stop属性的时候报错
+3. 优化遗留的通过正则判断rpx单位的问题
+4. 优化Layout布局 vue使用gutter时,会超出固定区域
+5. 优化search组件高度单位问题(rpx -> px)
+6. 修复u-image slot 加载和错误的图片失去了高度
+7. 修复u-index-list中footer插槽与header插槽存在性判断错误
+8. 修复部分机型下u-popup关闭时会闪烁
+9. 修复u-image在nvue-app下失去宽高
+10. 修复u-popup运行报错
+11. 修复u-tooltip报错
+12. 修复box-sizing在app下的警告
+13. 修复u-navbar在小程序中报运行时错误
+14. 其他修复
+## 2.0.23(2022-01-24)
+# uView2.0重磅发布,利剑出鞘,一统江湖
+
+1. 修复image组件在hx3.3.9的nvue下可能会显示异常的问题
+2. 修复col组件gutter参数带rpx单位处理不正确的问题
+3. 修复text组件单行时无法显示省略号的问题
+4. navbar添加titleStyle参数
+5. 升级到hx3.3.9可消除nvue下控制台样式警告的问题
+## 2.0.22(2022-01-19)
+# uView2.0重磅发布,利剑出鞘,一统江湖
+
+1. $u.page()方法优化,避免在特殊场景可能报错的问题
+2. picker组件添加immediateChange参数
+3. 新增$u.pages()方法
+## 2.0.21(2022-01-19)
+# uView2.0重磅发布,利剑出鞘,一统江湖
+
+1. 优化:form组件在用户设置rules的时候提示用户model必传
+2. 优化遗留的通过正则判断rpx单位的问题
+3. 修复微信小程序环境中tabbar组件开启safeAreaInsetBottom属性后,placeholder高度填充不正确
+4. 修复swiper在current指定非0时缩放有误
+5. 修复u-icon添加stop属性的时候报错
+6. 修复upload组件在accept=all的时候没有作用
+7. 修复在text组件mode为phone时call属性无效的问题
+8. 处理u-form clearValidate方法
+9. 其他修复
+## 2.0.20(2022-01-14)
+# uView2.0重磅发布,利剑出鞘,一统江湖
+
+1. 修复calendar默认会选择一个日期,如果直接点确定的话,无法取到值的问题
+2. 修复Slider缺少disabled props 还有注释
+3. 修复u-notice-bar点击事件无法拿到index索引值的问题
+4. 修复u-collapse-item在vue文件下,app端自定义插槽不生效的问题
+5. 优化头像为空时显示默认头像
+6. 修复图片地址赋值后判断加载状态为完成问题
+7. 修复日历滚动到默认日期月份区域
+8. search组件暴露点击左边icon事件
+9. 修复u-form clearValidate方法不生效
+10. upload h5端增加返回文件参数(文件的name参数)
+11. 处理upload选择文件后url为blob类型无法预览的问题
+12. u-code-input 修复输入框没有往左移出一半屏幕
+13. 修复Upload上传 disabled为true时,控制台报hoverClass类型错误
+14. 临时处理ios app下grid点击坍塌问题
+15. 其他修复
+## 2.0.19(2021-12-29)
+# uView2.0重磅发布,利剑出鞘,一统江湖
+
+1. 优化微信小程序包体积可在微信中预览,请升级HbuilderX3.3.4,同时在“运行->运行到小程序模拟器”中勾选“运行时是否压缩代码”
+2. 优化微信小程序setData性能,处理某些方法如$u.route()无法在模板中使用的问题
+3. navbar添加autoBack参数
+4. 允许avatar组件的事件冒泡
+5. 修复cell组件报错问题
+6. 其他修复
+## 2.0.18(2021-12-28)
+# uView2.0重磅发布,利剑出鞘,一统江湖
+
+1. 修复app端编译报错问题
+2. 重新处理微信小程序端setData过大的性能问题
+3. 修复边框问题
+4. 修复最大最小月份不大于0则没有数据出现的问题
+5. 修复SwipeAction微信小程序端无法上下滑动问题
+6. 修复input的placeholder在小程序端默认显示为true问题
+7. 修复divider组件click事件无效问题
+8. 修复u-code-input maxlength 属性值为 String 类型时显示异常
+9. 修复当 grid只有 1到2时 在小程序端algin设置无效的问题
+10. 处理form-item的label为top时,取消错误提示的左边距
+11. 其他修复
+## 2.0.17(2021-12-26)
+## uView正在参与开源中国的“年度最佳项目”评选,之前投过票的现在也可以投票,恳请同学们投一票,[点此帮助uView](https://www.oschina.net/project/top_cn_2021/?id=583)
+
+# uView2.0重磅发布,利剑出鞘,一统江湖
+
+1. 解决HBuilderX3.3.3.20211225版本导致的样式问题
+2. calendar日历添加monthNum参数
+3. navbar添加center slot
+## 2.0.16(2021-12-25)
+## uView正在参与开源中国的“年度最佳项目”评选,之前投过票的现在也可以投票,恳请同学们投一票,[点此帮助uView](https://www.oschina.net/project/top_cn_2021/?id=583)
+
+# uView2.0重磅发布,利剑出鞘,一统江湖
+
+1. 解决微信小程序setData性能问题
+2. 修复count-down组件change事件不触发问题
+## 2.0.15(2021-12-21)
+## uView正在参与开源中国的“年度最佳项目”评选,之前投过票的现在也可以投票,恳请同学们投一票,[点此帮助uView](https://www.oschina.net/project/top_cn_2021/?id=583)
+
+# uView2.0重磅发布,利剑出鞘,一统江湖
+
+1. 修复Cell单元格titleWidth无效
+2. 修复cheakbox组件ischecked不更新
+3. 修复keyboard是否显示"."按键默认值问题
+4. 修复number-keyboard是否显示键盘的"."符号问题
+5. 修复Input输入框 readonly无效
+6. 修复u-avatar 导致打包app、H5时候报错问题
+7. 修复Upload上传deletable无效
+8. 修复upload当设置maxSize时无效的问题
+9. 修复tabs lineWidth传入带单位的字符串的时候偏移量计算错误问题
+10. 修复rate组件在有padding的view内,显示的星星位置和可触摸区域不匹配,无法正常选中星星
+## 2.0.13(2021-12-14)
+## [点击加群交流反馈:364463526](https://jq.qq.com/?_chanwv=1027&k=mCxS3TGY)
+
+# uView2.0重磅发布,利剑出鞘,一统江湖
+
+1. 修复配置默认单位为rpx可能会导致自定义导航栏高度异常的问题
+## 2.0.12(2021-12-14)
+## [点击加群交流反馈:364463526](https://jq.qq.com/?_chanwv=1027&k=mCxS3TGY)
+
+# uView2.0重磅发布,利剑出鞘,一统江湖
+
+1. 修复tabs组件在vue环境下划线消失的问题
+2. 修复upload组件在安卓小程序无法选择视频的问题
+3. 添加uni.$u.config.unit配置,用于配置参数默认单位,详见:[默认单位配置](https://www.uviewui.com/components/setting.html#%E9%BB%98%E8%AE%A4%E5%8D%95%E4%BD%8D%E9%85%8D%E7%BD%AE)
+4. 修复textarea组件在没绑定v-model时,字符统计不生效问题
+5. 修复nvue下控制是否出现滚动条失效问题
+## 2.0.11(2021-12-13)
+## [点击加群交流反馈:364463526](https://jq.qq.com/?_chanwv=1027&k=mCxS3TGY)
+
+# uView2.0重磅发布,利剑出鞘,一统江湖
+
+1. text组件align参数无效的问题
+2. subsection组件添加keyName参数
+3. upload组件无法判断[Object file]类型的问题
+4. 处理notify层级过低问题
+5. codeInput组件添加disabledDot参数
+6. 处理actionSheet组件round参数无效的问题
+7. calendar组件添加round参数用于控制圆角值
+8. 处理swipeAction组件在vue环境下默认被打开的问题
+9. button组件的throttleTime节流参数无效的问题
+10. 解决u-notify手动关闭方法close()无效的问题
+11. input组件readonly不生效问题
+12. tag组件type参数为info不生效问题
+## 2.0.10(2021-12-08)
+## [点击加群交流反馈:364463526](https://jq.qq.com/?_chanwv=1027&k=mCxS3TGY)
+
+# uView2.0重磅发布,利剑出鞘,一统江湖
+
+1. 修复button sendMessagePath属性不生效
+2. 修复DatetimePicker选择器title无效
+3. 修复u-toast设置loading=true不生效
+4. 修复u-text金额模式传0报错
+5. 修复u-toast组件的icon属性配置不生效
+6. button的icon在特殊场景下的颜色优化
+7. IndexList优化,增加#
+## 2.0.9(2021-12-01)
+## [点击加群交流反馈:232041042](https://jq.qq.com/?_wv=1027&k=KnbeceDU)
+
+# uView2.0重磅发布,利剑出鞘,一统江湖
+
+1. 优化swiper的height支持100%值(仅vue有效),修复嵌入视频时click事件无法触发的问题
+2. 优化tabs组件对list值为空的判断,或者动态变化list时重新计算相关尺寸的问题
+3. 优化datetime-picker组件逻辑,让其后续打开的默认值为上一次的选中值,需要通过v-model绑定值才有效
+4. 修复upload内嵌在其他组件中,选择图片可能不会换行的问题
+## 2.0.8(2021-12-01)
+## [点击加群交流反馈:232041042](https://jq.qq.com/?_wv=1027&k=KnbeceDU)
+
+# uView2.0重磅发布,利剑出鞘,一统江湖
+
+1. 修复toast的position参数无效问题
+2. 处理input在ios nvue上无法获得焦点的问题
+3. avatar-group组件添加extraValue参数,让剩余展示数量可手动控制
+4. tabs组件添加keyName参数用于配置从对象中读取的键名
+5. 处理text组件名字脱敏默认配置无效的问题
+6. 处理picker组件item文本太长换行问题
+## 2.0.7(2021-11-30)
+## [点击加群交流反馈:232041042](https://jq.qq.com/?_wv=1027&k=KnbeceDU)
+
+# uView2.0重磅发布,利剑出鞘,一统江湖
+
+1. 修复radio和checkbox动态改变v-model无效的问题。
+2. 优化form规则validator在微信小程序用法
+3. 修复backtop组件mode参数在微信小程序无效的问题
+4. 处理Album的previewFullImage属性无效的问题
+5. 处理u-datetime-picker组件mode='time'在选择改变时间时,控制台报错的问题
+## 2.0.6(2021-11-27)
+## [点击加群交流反馈:232041042](https://jq.qq.com/?_wv=1027&k=KnbeceDU)
+
+# uView2.0重磅发布,利剑出鞘,一统江湖
+
+1. 处理tag组件在vue下边框无效的问题。
+2. 处理popup组件圆角参数可能无效的问题。
+3. 处理tabs组件lineColor参数可能无效的问题。
+4. propgress组件在值很小时,显示异常的问题。
+## 2.0.5(2021-11-25)
+## [点击加群交流反馈:232041042](https://jq.qq.com/?_wv=1027&k=KnbeceDU)
+
+# uView2.0重磅发布,利剑出鞘,一统江湖
+
+1. calendar在vue下显示异常问题。
+2. form组件labelPosition和errorType参数无效的问题
+3. input组件inputAlign无效的问题
+4. 其他一些修复
+## 2.0.4(2021-11-23)
+## [点击加群交流反馈:232041042](https://jq.qq.com/?_wv=1027&k=KnbeceDU)
+
+# uView2.0重磅发布,利剑出鞘,一统江湖
+
+0. input组件缺失@confirm事件,以及subfix和prefix无效问题
+1. component.scss文件样式在vue下干扰全局布局问题
+2. 修复subsection在vue环境下表现异常的问题
+3. tag组件的bgColor等参数无效的问题
+4. upload组件不换行的问题
+5. 其他的一些修复处理
+## 2.0.3(2021-11-16)
+## [点击加群交流反馈:1129077272](https://jq.qq.com/?_wv=1027&k=KnbeceDU)
+
+# uView2.0重磅发布,利剑出鞘,一统江湖
+
+1. uView2.0已实现全面兼容nvue
+2. uView2.0对1.x进行了架构重构,细节和性能都有极大提升
+3. 目前uView2.0为公测阶段,相关细节可能会有变动
+4. 我们写了一份与1.x的对比指南,详见[对比1.x](https://www.uviewui.com/components/diff1.x.html)
+5. 处理modal的confirm回调事件拼写错误问题
+6. 处理input组件@input事件参数错误问题
+7. 其他一些修复
+## 2.0.2(2021-11-16)
+## [点击加群交流反馈:1129077272](https://jq.qq.com/?_wv=1027&k=KnbeceDU)
+
+# uView2.0重磅发布,利剑出鞘,一统江湖
+
+1. uView2.0已实现全面兼容nvue
+2. uView2.0对1.x进行了架构重构,细节和性能都有极大提升
+3. 目前uView2.0为公测阶段,相关细节可能会有变动
+4. 我们写了一份与1.x的对比指南,详见[对比1.x](https://www.uviewui.com/components/diff1.x.html)
+5. 修复input组件formatter参数缺失问题
+6. 优化loading-icon组件的scss写法问题,防止不兼容新版本scss
+## 2.0.0(2020-11-15)
+## [点击加群交流反馈:1129077272](https://jq.qq.com/?_wv=1027&k=KnbeceDU)
+
+# uView2.0重磅发布,利剑出鞘,一统江湖
+
+1. uView2.0已实现全面兼容nvue
+2. uView2.0对1.x进行了架构重构,细节和性能都有极大提升
+3. 目前uView2.0为公测阶段,相关细节可能会有变动
+4. 我们写了一份与1.x的对比指南,详见[对比1.x](https://www.uviewui.com/components/diff1.x.html)
+5. 修复input组件formatter参数缺失问题
+
+
diff --git a/uni_modules/uview-ui/components/u--form/u--form.vue b/uni_modules/uview-ui/components/u--form/u--form.vue
new file mode 100644
index 0000000..fdfc212
--- /dev/null
+++ b/uni_modules/uview-ui/components/u--form/u--form.vue
@@ -0,0 +1,78 @@
+
+
+
+
+
+
+
diff --git a/uni_modules/uview-ui/components/u--image/u--image.vue b/uni_modules/uview-ui/components/u--image/u--image.vue
new file mode 100644
index 0000000..21b7ab1
--- /dev/null
+++ b/uni_modules/uview-ui/components/u--image/u--image.vue
@@ -0,0 +1,47 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/uni_modules/uview-ui/components/u--input/u--input.vue b/uni_modules/uview-ui/components/u--input/u--input.vue
new file mode 100644
index 0000000..1e58b01
--- /dev/null
+++ b/uni_modules/uview-ui/components/u--input/u--input.vue
@@ -0,0 +1,73 @@
+
+ $emit('blur', e)"
+ @keyboardheightchange="$emit('keyboardheightchange')"
+ @change="e => $emit('change', e)"
+ @input="e => $emit('input', e)"
+ @confirm="e => $emit('confirm', e)"
+ @clear="$emit('clear')"
+ @click="$emit('click')"
+ >
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/uni_modules/uview-ui/components/u--text/u--text.vue b/uni_modules/uview-ui/components/u--text/u--text.vue
new file mode 100644
index 0000000..44ee52a
--- /dev/null
+++ b/uni_modules/uview-ui/components/u--text/u--text.vue
@@ -0,0 +1,44 @@
+
+
+
+
+
diff --git a/uni_modules/uview-ui/components/u--textarea/u--textarea.vue b/uni_modules/uview-ui/components/u--textarea/u--textarea.vue
new file mode 100644
index 0000000..f4df0b9
--- /dev/null
+++ b/uni_modules/uview-ui/components/u--textarea/u--textarea.vue
@@ -0,0 +1,48 @@
+
+ $emit('focus')"
+ @blur="e => $emit('blur')"
+ @linechange="e => $emit('linechange', e)"
+ @confirm="e => $emit('confirm')"
+ @input="e => $emit('input', e)"
+ @keyboardheightchange="e => $emit('keyboardheightchange')"
+ >
+
+
+
diff --git a/uni_modules/uview-ui/components/u-action-sheet/props.js b/uni_modules/uview-ui/components/u-action-sheet/props.js
new file mode 100644
index 0000000..e96e04f
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-action-sheet/props.js
@@ -0,0 +1,54 @@
+export default {
+ props: {
+ // 操作菜单是否展示 (默认false)
+ show: {
+ type: Boolean,
+ default: uni.$u.props.actionSheet.show
+ },
+ // 标题
+ title: {
+ type: String,
+ default: uni.$u.props.actionSheet.title
+ },
+ // 选项上方的描述信息
+ description: {
+ type: String,
+ default: uni.$u.props.actionSheet.description
+ },
+ // 数据
+ actions: {
+ type: Array,
+ default: uni.$u.props.actionSheet.actions
+ },
+ // 取消按钮的文字,不为空时显示按钮
+ cancelText: {
+ type: String,
+ default: uni.$u.props.actionSheet.cancelText
+ },
+ // 点击某个菜单项时是否关闭弹窗
+ closeOnClickAction: {
+ type: Boolean,
+ default: uni.$u.props.actionSheet.closeOnClickAction
+ },
+ // 处理底部安全区(默认true)
+ safeAreaInsetBottom: {
+ type: Boolean,
+ default: uni.$u.props.actionSheet.safeAreaInsetBottom
+ },
+ // 小程序的打开方式
+ openType: {
+ type: String,
+ default: uni.$u.props.actionSheet.openType
+ },
+ // 点击遮罩是否允许关闭 (默认true)
+ closeOnClickOverlay: {
+ type: Boolean,
+ default: uni.$u.props.actionSheet.closeOnClickOverlay
+ },
+ // 圆角值
+ round: {
+ type: [Boolean, String, Number],
+ default: uni.$u.props.actionSheet.round
+ }
+ }
+}
diff --git a/uni_modules/uview-ui/components/u-action-sheet/u-action-sheet.vue b/uni_modules/uview-ui/components/u-action-sheet/u-action-sheet.vue
new file mode 100644
index 0000000..26d5d8d
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-action-sheet/u-action-sheet.vue
@@ -0,0 +1,278 @@
+
+
+
+
+
+ {{description}}
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{cancelText}}
+
+
+
+
+
+
+
+
diff --git a/uni_modules/uview-ui/components/u-album/props.js b/uni_modules/uview-ui/components/u-album/props.js
new file mode 100644
index 0000000..75cdb37
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-album/props.js
@@ -0,0 +1,59 @@
+export default {
+ props: {
+ // 图片地址,Array|Array