首页静态完成

This commit is contained in:
魏啾
2024-04-01 16:31:14 +08:00
parent a9b9da0bbf
commit 653da2ad81
54 changed files with 6265 additions and 687 deletions

View File

@@ -0,0 +1,26 @@
## 1.2.32024-02-20
- 新增 支持控制小时分钟的显隐showHour showMinute
## 1.2.22022-01-19
- 修复 在微信小程序中样式不生效的bug
## 1.2.12022-01-18
- 新增 update 方法 ,在动态更新时间后,刷新组件
## 1.2.02021-11-19
- 优化 组件UI并提供设计资源详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource)
- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-countdown](https://uniapp.dcloud.io/component/uniui/uni-countdown)
## 1.1.32021-10-18
- 重构
- 新增 font-size 支持自定义字体大小
## 1.1.22021-08-24
- 新增 支持国际化
## 1.1.12021-07-30
- 优化 vue3下小程序事件警告的问题
## 1.1.02021-07-30
- 组件兼容 vue3如何创建vue3项目详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834)
## 1.0.52021-06-18
- 修复 uni-countdown 重复赋值跳两秒的 bug
## 1.0.42021-05-12
- 新增 组件示例地址
## 1.0.32021-05-08
- 修复 uni-countdown 不能控制倒计时的 bug
## 1.0.22021-02-04
- 调整为uni_modules目录规范

View File

@@ -0,0 +1,6 @@
{
"uni-countdown.day": "day",
"uni-countdown.h": "h",
"uni-countdown.m": "m",
"uni-countdown.s": "s"
}

View File

@@ -0,0 +1,8 @@
import en from './en.json'
import zhHans from './zh-Hans.json'
import zhHant from './zh-Hant.json'
export default {
en,
'zh-Hans': zhHans,
'zh-Hant': zhHant
}

View File

@@ -0,0 +1,6 @@
{
"uni-countdown.day": "天",
"uni-countdown.h": "时",
"uni-countdown.m": "分",
"uni-countdown.s": "秒"
}

View File

@@ -0,0 +1,6 @@
{
"uni-countdown.day": "天",
"uni-countdown.h": "時",
"uni-countdown.m": "分",
"uni-countdown.s": "秒"
}

View File

@@ -0,0 +1,281 @@
<template>
<view class="uni-countdown">
<text v-if="showDay" :style="[timeStyle]" class="uni-countdown__number">{{ d }}</text>
<text v-if="showDay" :style="[splitorStyle]" class="uni-countdown__splitor">{{dayText}}</text>
<text v-if="showHour" :style="[timeStyle]" class="uni-countdown__number">{{ h }}</text>
<text v-if="showHour" :style="[splitorStyle]" class="uni-countdown__splitor">{{ showColon ? ':' : hourText }}</text>
<text v-if="showMinute" :style="[timeStyle]" class="uni-countdown__number">{{ i }}</text>
<text v-if="showMinute" :style="[splitorStyle]" class="uni-countdown__splitor">{{ showColon ? ':' : minuteText }}</text>
<text :style="[timeStyle]" class="uni-countdown__number">{{ s }}</text>
<text v-if="!showColon" :style="[splitorStyle]" class="uni-countdown__splitor">{{secondText}}</text>
</view>
</template>
<script>
import {
initVueI18n
} from '@dcloudio/uni-i18n'
import messages from './i18n/index.js'
const {
t
} = initVueI18n(messages)
/**
* Countdown 倒计时
* @description 倒计时组件
* @tutorial https://ext.dcloud.net.cn/plugin?id=25
* @property {String} backgroundColor 背景色
* @property {String} color 文字颜色
* @property {Number} day 天数
* @property {Number} hour 小时
* @property {Number} minute 分钟
* @property {Number} second 秒
* @property {Number} timestamp 时间戳
* @property {Boolean} showDay = [true|false] 是否显示天数
* @property {Boolean} showHour = [true|false] 是否显示小时
* @property {Boolean} showMinute = [true|false] 是否显示分钟
* @property {Boolean} show-colon = [true|false] 是否以冒号为分隔符
* @property {String} splitorColor 分割符号颜色
* @event {Function} timeup 倒计时时间到触发事件
* @example <uni-countdown :day="1" :hour="1" :minute="12" :second="40"></uni-countdown>
*/
export default {
name: 'UniCountdown',
emits: ['timeup'],
props: {
showDay: {
type: Boolean,
default: true
},
showHour: {
type: Boolean,
default: true
},
showMinute: {
type: Boolean,
default: true
},
showColon: {
type: Boolean,
default: true
},
start: {
type: Boolean,
default: true
},
backgroundColor: {
type: String,
default: ''
},
color: {
type: String,
default: '#333'
},
fontSize: {
type: Number,
default: 14
},
splitorColor: {
type: String,
default: '#333'
},
day: {
type: Number,
default: 0
},
hour: {
type: Number,
default: 0
},
minute: {
type: Number,
default: 0
},
second: {
type: Number,
default: 0
},
timestamp: {
type: Number,
default: 0
}
},
data() {
return {
timer: null,
syncFlag: false,
d: '00',
h: '00',
i: '00',
s: '00',
leftTime: 0,
seconds: 0
}
},
computed: {
dayText() {
return t("uni-countdown.day")
},
hourText(val) {
return t("uni-countdown.h")
},
minuteText(val) {
return t("uni-countdown.m")
},
secondText(val) {
return t("uni-countdown.s")
},
timeStyle() {
const {
color,
backgroundColor,
fontSize
} = this
return {
color,
backgroundColor,
fontSize: `${fontSize}px`,
width: `${fontSize * 22 / 14}px`, // 按字体大小为 14px 时的比例缩放
lineHeight: `${fontSize * 20 / 14}px`,
borderRadius: `${fontSize * 3 / 14}px`,
}
},
splitorStyle() {
const { splitorColor, fontSize, backgroundColor } = this
return {
color: splitorColor,
fontSize: `${fontSize * 12 / 14}px`,
margin: backgroundColor ? `${fontSize * 4 / 14}px` : ''
}
}
},
watch: {
day(val) {
this.changeFlag()
},
hour(val) {
this.changeFlag()
},
minute(val) {
this.changeFlag()
},
second(val) {
this.changeFlag()
},
start: {
immediate: true,
handler(newVal, oldVal) {
if (newVal) {
this.startData();
} else {
if (!oldVal) return
clearInterval(this.timer)
}
}
}
},
created: function(e) {
this.seconds = this.toSeconds(this.timestamp, this.day, this.hour, this.minute, this.second)
this.countDown()
},
// #ifndef VUE3
destroyed() {
clearInterval(this.timer)
},
// #endif
// #ifdef VUE3
unmounted() {
clearInterval(this.timer)
},
// #endif
methods: {
toSeconds(timestamp, day, hours, minutes, seconds) {
if (timestamp) {
return timestamp - parseInt(new Date().getTime() / 1000, 10)
}
return day * 60 * 60 * 24 + hours * 60 * 60 + minutes * 60 + seconds
},
timeUp() {
clearInterval(this.timer)
this.$emit('timeup')
},
countDown() {
let seconds = this.seconds
let [day, hour, minute, second] = [0, 0, 0, 0]
if (seconds > 0) {
day = Math.floor(seconds / (60 * 60 * 24))
hour = Math.floor(seconds / (60 * 60)) - (day * 24)
minute = Math.floor(seconds / 60) - (day * 24 * 60) - (hour * 60)
second = Math.floor(seconds) - (day * 24 * 60 * 60) - (hour * 60 * 60) - (minute * 60)
} else {
this.timeUp()
}
if (day < 10) {
day = '0' + day
}
if (hour < 10) {
hour = '0' + hour
}
if (minute < 10) {
minute = '0' + minute
}
if (second < 10) {
second = '0' + second
}
this.d = day
this.h = hour
this.i = minute
this.s = second
},
startData() {
this.seconds = this.toSeconds(this.timestamp, this.day, this.hour, this.minute, this.second)
if (this.seconds <= 0) {
this.seconds = this.toSeconds(0, 0, 0, 0, 0)
this.countDown()
return
}
clearInterval(this.timer)
this.countDown()
this.timer = setInterval(() => {
this.seconds--
if (this.seconds < 0) {
this.timeUp()
return
}
this.countDown()
}, 1000)
},
update(){
this.startData();
},
changeFlag() {
if (!this.syncFlag) {
this.seconds = this.toSeconds(this.timestamp, this.day, this.hour, this.minute, this.second)
this.startData();
this.syncFlag = true;
}
}
}
}
</script>
<style lang="scss" scoped>
$font-size: 14px;
.uni-countdown {
display: flex;
flex-direction: row;
justify-content: flex-start;
align-items: center;
&__splitor {
margin: 0 2px;
font-size: $font-size;
color: #333;
}
&__number {
border-radius: 3px;
text-align: center;
font-size: $font-size;
}
}
</style>

View File

@@ -0,0 +1,83 @@
{
"id": "uni-countdown",
"displayName": "uni-countdown 倒计时",
"version": "1.2.3",
"description": "CountDown 倒计时组件",
"keywords": [
"uni-ui",
"uniui",
"countdown",
"倒计时"
],
"repository": "https://github.com/dcloudio/uni-ui",
"engines": {
"HBuilderX": ""
},
"directories": {
"example": "../../temps/example_temps"
},
"dcloudext": {
"sale": {
"regular": {
"price": "0.00"
},
"sourcecode": {
"price": "0.00"
}
},
"contact": {
"qq": ""
},
"declaration": {
"ads": "无",
"data": "无",
"permissions": "无"
},
"npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui",
"type": "component-vue"
},
"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"
}
}
}
}
}

View File

@@ -0,0 +1,10 @@
## CountDown 倒计时
> **组件名uni-countdown**
> 代码块: `uCountDown`
倒计时组件。
### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-countdown)
#### 如使用过程中有任何问题或者您对uni-ui有一些好的建议欢迎加入 uni-ui 交流群871950839

View File

@@ -0,0 +1,8 @@
## 1.1.02024-03-25
[重要] 支持支付宝小程序云
## 1.0.22023-08-01
优化配置读取方式
## 1.0.12023-08-01
初版
## 1.0.02023-08-01
初版文档地址https://uniapp.dcloud.net.cn/uniCloud/uni-map-common.html

View File

@@ -0,0 +1,83 @@
{
"id": "uni-map-common",
"displayName": "uni-map-common地图服务端API",
"version": "1.1.0",
"description": "聚合了多家地图供应商的服务端API几行代码即可快速接入地图API",
"keywords": [
"uni-map-common",
"地图服务端API"
],
"repository": "",
"engines": {
"HBuilderX": "^3.1.0"
},
"dcloudext": {
"type": "unicloud-template-function",
"sale": {
"regular": {
"price": "0.00"
},
"sourcecode": {
"price": "0.00"
}
},
"contact": {
"qq": ""
},
"declaration": {
"ads": "无",
"data": "插件不采集任何数据",
"permissions": "无"
},
"npmurl": ""
},
"uni_modules": {
"dependencies": [],
"encrypt": [],
"platforms": {
"cloud": {
"tcb": "y",
"aliyun": "y",
"alipay": "y"
},
"client": {
"Vue": {
"vue2": "u",
"vue3": "u"
},
"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",
"飞书": "u",
"京东": "u"
},
"快应用": {
"华为": "u",
"联盟": "u"
}
}
}
}
}

View File

@@ -0,0 +1,11 @@
# uni-map-common
聚合了多家地图供应商的服务端API
## 使用教程
> 文档地址:[https://uniapp.dcloud.net.cn/uniCloud/uni-map-common.html](https://uniapp.dcloud.net.cn/uniCloud/uni-map-common.html)
## bug反馈地址
> 加群:[uni-map交流群](https://im.dcloud.net.cn/#/?joinGroup=64d62b106823de10406ad72f)

View File

@@ -0,0 +1,100 @@
const service = require('./service/index.js');
class UniMap {
// 构造函数
constructor(data = {}) {
let {
provider, // 平台 weixin-mp 微信小程序 weixin-h5 微信公众号
key, // 密钥
needOriginalResult = false, // 是否需要返回原始信息默认false
} = data;
let runService = service[provider];
if (!runService) {
throw new Error(`不支持平台:${provider}`);
}
this.service = new runService({
provider,
key,
needOriginalResult
});
//return this.service;
}
// API - 逆地址解析(坐标转地址)
async location2address(data = {}) {
let res = await this._call("location2address", data);
return res;
}
// API - 地址解析(地址转坐标)
async address2location(data = {}) {
let res = await this._call("address2location", data);
return res;
}
// API - 坐标转换
async translate(data = {}) {
let res = await this._call("translate", data);
return res;
}
// API - IP定位
async ip2location(data = {}) {
let res = await this._call("ip2location", data);
return res;
}
// API - 关键词输入提示
async inputtips(data = {}) {
let res = await this._call("inputtips", data);
return res;
}
// API - 周边搜索
async search(data = {}) {
let res = await this._call("search", data);
return res;
}
// API - 行政区划
async districtSearch(data = {}) {
let res = await this._call("districtSearch", data);
return res;
}
// API - 路线规划(驾车/步行/骑行/电动车/公交)
async route(data = {}) {
let urlObj = {
"driving": "drivingRoute",
"walking": "walkingRoute",
"bicycling": "bicyclingRoute",
"ebicycling": "ebicyclingRoute",
"transit": "transitRoute"
};
let res = await this._call(urlObj[data.mode], data);
res.result.mode = data.mode;
return res;
}
// 私有函数
async _call(name, data = {}) {
let runFunction = this.service[name];
if (!runFunction) {
throw new Error(`平台:${this.service.config.provider} 不支持API${name}`);
}
let res = await runFunction.call(this.service, data); // 此处需要使用call防止里面的this作用域被意外改变
if (!this.service.config.needOriginalResult) {
delete res.originalResult;
}
//res = JSON.parse(JSON.stringify(res));
return {
provider: this.service.config.provider,
...res
};
}
}
module.exports = UniMap;

View File

@@ -0,0 +1,74 @@
/**
* 通用公共函数
*/
var common = {};
// 经纬度表示形式转换
common.getLocation = function(location = "", type = "", returnType = "") {
let lat;
let lng;
// 去除所有空格
type = type.trim();
returnType = returnType.replace(/\s+/g, '');
if (type === "lat,lng") {
location = location.replace(/\s+/g, '');
let arr = location.split(",");
lat = arr[0];
lng = arr[1];
} else if (type === "lng,lat") {
location = location.replace(/\s+/g, '');
let arr = location.split(",");
lat = arr[1];
lng = arr[0];
} else if (type === "lat lng") {
let arr = location.split(" ");
lat = arr[0];
lng = arr[1];
} else if (type === "lng lat") {
let arr = location.split(" ");
lat = arr[1];
lng = arr[0];
} else {
lat = location.lat;
lng = location.lng;
}
if (returnType == "lng,lat") {
return `${lng},${lat}`;
} else if (returnType == "lat,lng") {
return `${lat},${lng}`;
} else {
return {
lat: Number(lat),
lng: Number(lng)
}
}
};
// 字符串格式的坐标经纬度反转
common.getReversalLocation = function(input="") {
// 按分隔符拆分字符串
let parts = input.split("|");
// 遍历每个部分进行值交换
for (let i = 0; i < parts.length; i++) {
let pairs = parts[i].split(";");
for (let j = 0; j < pairs.length; j++) {
let values = pairs[j].split(",");
// 交换两个值
let temp = values[0];
values[0] = values[1];
values[1] = temp;
// 更新交换后的值
pairs[j] = values.join(",");
}
// 更新交换后的部分
parts[i] = pairs.join(";");
}
// 返回交换后的结果
return parts.join("|");
};
module.exports = common;

View File

@@ -0,0 +1,13 @@
const errSubject = "uni-map-common";
class UniCloudError {
constructor(options = {}) {
this.errCode = options.errCode || options.code;
this.errMsg = options.errMsg || options.msg || options.message || "";
this.errSubject = options.subject || errSubject;
}
}
module.exports = {
UniCloudError
}

View File

@@ -0,0 +1,7 @@
const common = require('./common');
const error = require('./error');
module.exports = {
common,
error
};

View File

@@ -0,0 +1,15 @@
{
"name": "uni-map-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"
}
}

View File

@@ -0,0 +1,979 @@
const libs = require('../libs');
// https://lbs.amap.com/api/webservice/guide/tools/info
const ERRCODE = {
"10000": 0,
"10001": 190,
"10002": 113,
"10003": 121,
"10004": 120,
"10005": 112,
"10006": 110,
"10007": 111,
"10008": 111,
"10009": 110,
"10010": 122,
"10011": 311,
"10012": 113,
"10013": 190,
"10014": 500,
"10015": 500,
"10016": 500,
"10017": 500,
"10019": 500,
"10020": 500,
"10021": 500,
"10026": 110,
"10029": 500,
"10041": 110,
"10044": 121,
"10045": 121,
"20000": 395,
"20001": 300,
"20002": 500,
"20003": 500,
"20011": 395,
"20012": 395,
"20801": 395,
"20802": 395,
"20803": 373,
"40000": 123,
"40001": 123,
"40002": 123,
"40003": 123
};
class Service {
// 构造函数
constructor(data = {}) {
let {
key,
needOriginalResult = false, // 是否需要返回原始信息默认false
} = data;
this.config = {
provider: "amap",
key,
needOriginalResult,
serviceUrl: "https://restapi.amap.com"
}
}
async request(obj = {}) {
let {
url,
data = {}
} = obj;
if (url.indexOf("http") !== 0) {
url = `${this.config.serviceUrl}/${url}`
}
if (this.config.key && !data.key) {
data.key = this.config.key;
}
obj.data = JSON.parse(JSON.stringify(obj.data));
let requestRes = await uniCloud.httpclient.request(url, obj);
let result = this.getResult(requestRes);
if (result.errCode != 0) {
throw new libs.error.UniCloudError(result);
}
return result;
}
getResult(requestRes) {
let {
data: originalResult = {}
} = requestRes;
let res = {
errCode: originalResult.infocode == "10000" ? 0 : this.getErrCode(originalResult.infocode),
errMsg: originalResult.info,
originalResult,
};
return res;
}
getErrCode(errCode) {
return ERRCODE[errCode] || errCode;
}
// API - 逆地址解析(坐标转地址)
async location2address(data = {}) {
let {
location,
get_poi,
poi_options,
} = data;
let requestData = {
location: libs.common.getLocation(location, "lat,lng", "lng,lat"),
extensions: get_poi ? "all" : "base",
};
if (get_poi && typeof poi_options == "object") {
let {
poitype,
radius,
roadlevel,
homeorcorp
} = poi_options;
requestData = Object.assign(requestData, {
poitype,
radius,
roadlevel,
homeorcorp
})
}
let requestRes = await this.request({
method: "GET",
url: "v3/geocode/regeo",
dataType: "json",
data: requestData
});
let originalResult = requestRes.originalResult.regeocode;
let pois;
if (originalResult.pois) {
pois = originalResult.pois.map((item) => {
return {
id: item.id,
title: item.name,
address: item.address,
location: libs.common.getLocation(item.location, "lng,lat", "object"),
distance: item.distance,
direction: item.direction,
category: item.type
}
});
}
let roads;
if (originalResult.roads) {
roads = originalResult.roads.map((item) => {
return {
id: item.id,
title: item.name,
distance: Number(item.distance),
direction: item.direction,
location: libs.common.getLocation(item.location, "lng,lat", "object")
}
});
}
let roadinters;
if (originalResult.roadinters) {
roadinters = originalResult.roadinters.map((item) => {
return {
distance: Number(item.distance),
direction: item.direction,
first_id: item.first_id,
first_name: item.first_name,
second_id: item.second_id,
second_name: item.second_name,
location: libs.common.getLocation(item.location, "lng,lat", "object")
}
});
}
let result = {
formatted_addresses: originalResult.formatted_address,
country: originalResult.addressComponent.country,
province: originalResult.addressComponent.province,
city: JSON.stringify(originalResult.addressComponent.city) === "[]" || !originalResult.addressComponent.city ? originalResult.addressComponent.province : originalResult
.addressComponent.city,
district: originalResult.addressComponent.district,
street: originalResult.addressComponent.country,
street_number: originalResult.addressComponent.streetNumber.street + originalResult.addressComponent.streetNumber.number,
adcode: originalResult.addressComponent.adcode,
pois,
roads,
roadinters
};
let res = {
result,
...requestRes
};
return res;
}
// API - 地址解析(地址转坐标)
async address2location(data = {}) {
let {
address,
city,
} = data;
let requestRes = await this.request({
method: "GET",
url: "v3/geocode/geo",
dataType: "json",
data: {
address,
city
}
});
let originalResult = requestRes.originalResult.geocodes[0];
let result = {
location: libs.common.getLocation(originalResult.location, "lng,lat", "object"),
adcode: originalResult.adcode,
province: originalResult.province,
city: originalResult.city,
district: originalResult.district,
street: originalResult.street,
street_number: originalResult.number,
};
let res = {
result,
...requestRes
};
return res;
}
// API - 坐标转换
async translate(data = {}) {
let {
locations,
type,
} = data;
let locationsStr = "";
locations.map((item, index) => {
if (index > 0) {
locationsStr += ";";
}
locationsStr += libs.common.getLocation(item, "object", "lng,lat");
})
let coordsys = {
"1": "gps",
"4": "mapbar",
"3": "baidu",
"": "autonavi",
} [type + ""];
let requestRes = await this.request({
method: "GET",
url: "v3/assistant/coordinate/convert",
dataType: "json",
data: {
locations: locationsStr,
coordsys
}
});
let originalResult = requestRes.originalResult;
let returnLocationsStr = originalResult.locations;
let arr = returnLocationsStr.split(";");
let returnLocations = arr.map((item) => {
return libs.common.getLocation(item, "lng,lat", "object");
});
let result = {
locations: returnLocations
};
let res = {
result,
...requestRes
};
return res;
}
// API - IP定位
async ip2location(data = {}) {
let {
ip,
} = data;
let requestRes = await this.request({
method: "GET",
url: "v3/ip",
dataType: "json",
data: {
ip
}
});
let originalResult = requestRes.originalResult;
let result = {
adcode: originalResult.adcode,
province: originalResult.province,
city: originalResult.city,
rectangle: originalResult.rectangle
};
let res = {
result,
...requestRes
};
return res;
}
// API - 关键词输入提示
async inputtips(data = {}) {
let {
keyword,
city,
citylimit,
location,
datatype,
} = data;
let requestData = {
keywords: keyword,
city,
citylimit,
datatype
};
if (location) {
requestData.location = libs.common.getLocation(location, "object", "lng,lat");
}
let requestRes = await this.request({
method: "GET",
url: "v3/assistant/inputtips",
dataType: "json",
data: requestData,
});
let originalResult = requestRes.originalResult;
let _data = originalResult.tips.map((item) => {
return {
id: item.id,
name: item.name,
address: item.address,
location: libs.common.getLocation(item.location, "lng,lat", "object"),
adcode: item.adcode,
district: item.district
}
});
let result = {
data: _data
};
let res = {
result,
...requestRes
};
return res;
}
// API - 周边搜索
async search(data = {}) {
let {
keyword,
location,
radius = 1000,
auto_extend = 1,
get_subpois,
orderby,
page_index = 1,
page_size = 20,
types,
city
} = data;
let requestData = {
keywords: keyword,
types,
location: libs.common.getLocation(location, "object", "lng,lat"),
radius,
sortrule: orderby,
region: city,
city_limit: auto_extend ? false : true,
page_num: page_index,
page_size,
show_fields: get_subpois ? "children,business,navi,photos" : "business,navi,photos"
};
let requestRes = await this.request({
method: "GET",
url: "v5/place/around",
dataType: "json",
data: requestData
});
let originalResult = requestRes.originalResult;
let _data = originalResult.pois.map((item) => {
return {
id: item.id,
title: item.name,
tel: item.business.tel,
address: item.address,
category: item.type,
location: libs.common.getLocation(item.location, "lng,lat", "object"),
distance: Number(item.distance),
adcode: item.adcode,
province: item.pname,
city: item.cityname,
district: item.adname,
children: item.children ? item.children.map((item2) => {
return {
parent_id: item.id,
id: item2.id,
title: item2.name,
address: item2.address,
category: item2.subtype,
location: libs.common.getLocation(item2.location, "lng,lat", "object")
}
}) : get_subpois ? [] : undefined,
}
});
let result = {
data: _data
};
let res = {
result,
...requestRes
};
return res;
}
// API - 行政区划
async districtSearch(data = {}) {
let {
adcode,
get_polygon,
page_index,
page_size,
filter,
subdistrict
} = data;
let requestData = {
keywords: adcode,
subdistrict,
page: page_index,
offset: page_size,
filter
};
let requestRes = await this.request({
method: "GET",
url: "v3/config/district",
dataType: "json",
data: requestData
});
let originalResult = requestRes.originalResult;
const formatDistricts = (list) => {
return list.map((item) => {
return {
adcode: item.adcode,
name: item.name,
fullname: item.name,
location: libs.common.getLocation(item.center, "lng,lat", "object"),
level: item.level,
children: typeof item.districts !== "undefined" ? formatDistricts(item.districts): undefined,
//polygon: item.polyline,
}
});
}
let _data = formatDistricts(originalResult.districts[0].districts);
let result = {
data: _data
};
let res = {
result,
...requestRes
};
return res;
}
// API - 路线规划(驾车)
async drivingRoute(data = {}) {
let {
mode,
from,
to,
from_poi,
to_poi,
policy,
waypoints,
avoid_polygons,
road_type,
plate_number,
cartype,
avoidroad,
ferry,
} = data;
let requestRes = await this.request({
method: "GET",
url: `v5/direction/driving`,
dataType: "json",
data: {
origin: libs.common.getLocation(from, "lat,lng", "lng,lat"),
destination: libs.common.getLocation(to, "lat,lng", "lng,lat"),
origin_id: from_poi,
destination_id: to_poi,
strategy: policy,
waypoints: libs.common.getReversalLocation(waypoints),
avoidpolygons: libs.common.getReversalLocation(avoid_polygons),
origin_type: road_type,
plate: plate_number,
cartype,
avoidroad,
ferry,
show_fields: "cost,tmcs,navi,cities,polyline"
}
});
let originalResult = requestRes.originalResult.route;
let routes = originalResult.paths.map((item) => {
let steps = item.steps.map((item2) => {
return {
instruction: item2.instruction,
road_name: item2.road_name,
dir_desc: item2.orientation,
distance: Number(item2.step_distance),
act_desc: item2.navi.action,
accessorial_desc: item2.navi.assistant_action,
cost: this.costFormat(item2.cost),
speed: item2.tmcs ? item2.tmcs.map((item3) => {
let levelIndex = {
"畅通": 0,
"缓行": 1,
"拥堵": 2,
"未知": 3,
"严重拥堵": 4,
}
return {
distance: Number(item3.tmc_distance),
level: levelIndex[item3.tmc_status],
polyline: this.polylineFormat(item3.tmc_polyline),
}
}) : undefined,
cities: item2.cities,
polyline: this.polylineFormat(item2.polyline),
}
});
return {
mode: "driving",
distance: Number(item.distance),
restriction_status: Number(item.restriction),
taxi_cost: Number(originalResult.taxi_cost),
steps
}
});
let result = {
routes
};
let res = {
result,
...requestRes
};
return res;
}
// API - 路线规划(步行)
async walkingRoute(data = {}) {
let {
mode,
from,
to,
alternative_route,
} = data;
let requestRes = await this.request({
method: "GET",
url: `v5/direction/walking`,
dataType: "json",
data: {
origin: libs.common.getLocation(from, "lat,lng", "lng,lat"),
destination: libs.common.getLocation(to, "lat,lng", "lng,lat"),
alternative_route,
show_fields: "cost,navi,polyline", // 此处强制传,为了和腾讯地图字段对齐
}
});
let originalResult = requestRes.originalResult.route;
let routes = originalResult.paths.map((item) => {
let duration1 = 0;
let steps = item.steps.map((item2) => {
let duration2 = this.durationFormat(item2.cost.duration);
duration1 += duration2;
return {
instruction: item2.instruction,
road_name: item2.road_name,
dir_desc: item2.orientation,
distance: Number(item2.step_distance),
act_desc: item2.navi.action || item2.navi.assistant_action,
taxi_cost: item2.cost.taxi ? this.priceFormat(item2.cost.taxi) : undefined,
duration: duration2,
polyline: this.polylineFormat(item2.polyline),
}
});
return {
mode: "walking",
distance: Number(item.distance),
duration: duration1,
steps
}
});
let result = {
routes
};
let res = {
result,
...requestRes
};
return res;
}
// API - 路线规划(骑行)
async bicyclingRoute(data = {}) {
let {
mode,
from,
to,
alternative_route,
} = data;
let requestRes = await this.request({
method: "GET",
url: `v5/direction/bicycling`,
dataType: "json",
data: {
origin: libs.common.getLocation(from, "lat,lng", "lng,lat"),
destination: libs.common.getLocation(to, "lat,lng", "lng,lat"),
alternative_route,
show_fields: "cost,navi,polyline", // 此处强制传,为了和腾讯地图字段对齐
}
});
let originalResult = requestRes.originalResult.route;
let routes = originalResult.paths.map((item) => {
let duration1 = 0;
let steps = item.steps.map((item2) => {
let duration2 = this.durationFormat(item2.cost.duration);
duration1 += duration2;
return {
instruction: item2.instruction,
road_name: item2.road_name,
dir_desc: item2.orientation,
distance: Number(item2.step_distance),
act_desc: item2.navi.action || item2.navi.assistant_action,
duration: duration2,
polyline: this.polylineFormat(item2.polyline),
}
});
return {
mode: "walking",
distance: Number(item.distance),
duration: duration1,
steps
}
});
let result = {
routes
};
let res = {
result,
...requestRes
};
return res;
}
// API - 路线规划(电动车)
async ebicyclingRoute(data = {}) {
let {
mode,
from,
to,
alternative_route,
} = data;
let requestRes = await this.request({
method: "GET",
url: `v5/direction/electrobike`,
dataType: "json",
data: {
origin: libs.common.getLocation(from, "lat,lng", "lng,lat"),
destination: libs.common.getLocation(to, "lat,lng", "lng,lat"),
alternative_route,
show_fields: "cost,navi,polyline", // 此处强制传,为了和腾讯地图字段对齐
}
});
let originalResult = requestRes.originalResult.route;
let routes = originalResult.paths.map((item) => {
let duration1 = 0;
let steps = item.steps.map((item2) => {
let duration2 = this.durationFormat(item2.cost.duration);
duration1 += duration2;
return {
instruction: item2.instruction,
road_name: item2.road_name,
dir_desc: item2.orientation,
distance: Number(item2.step_distance),
act_desc: item2.navi.action || item2.navi.assistant_action,
duration: duration2,
polyline: this.polylineFormat(item2.polyline),
}
});
return {
mode: "walking",
distance: Number(item.distance),
duration: duration1,
steps
}
});
let result = {
routes
};
let res = {
result,
...requestRes
};
return res;
}
// API - 路线规划(公交)
async transitRoute(data = {}) {
let {
mode,
from,
to,
from_poi,
to_poi,
policy,
ad1,
ad2,
city1,
city2,
alternative_route,
multiexport,
max_trans,
nightflag,
date,
time
} = data;
let requestRes = await this.request({
method: "GET",
url: `v5/direction/transit/integrated`,
dataType: "json",
data: {
origin: libs.common.getLocation(from, "lat,lng", "lng,lat"),
destination: libs.common.getLocation(to, "lat,lng", "lng,lat"),
originpoi: from_poi,
destinationpoi: to_poi,
strategy: policy,
ad1,
ad2,
city1,
city2,
AlternativeRoute: alternative_route,
multiexport,
max_trans,
nightflag,
date,
time,
show_fields: "cost,navi,polyline", // 此处强制传,为了和腾讯地图字段对齐
}
});
let originalResult = requestRes.originalResult.route;
let routes = originalResult.transits.map((item) => {
let stepsItem = this.getSteps(item.segments);
let steps = stepsItem.map((item2) => {
let mode = item2.mode.toLowerCase();
if (mode === "walking") {
// 步行
return {
mode: "walking",
distance: Number(item2.distance),
duration: this.durationFormat(item2.cost.duration),
steps: item2.steps.map((item3) => {
return {
instruction: item3.instruction,
road_name: item3.road,
distance: Number(item3.distance),
act_desc: item3.navi.action || item3.navi.assistant_action,
polyline: this.polylineFormat(item3.polyline)
}
}),
}
} else if (mode === "bus") {
return {
mode: "transit",
lines: item2.buslines.map((item3) => {
return {
vehicle: item3.type.indexOf("地铁") > -1 ? "SUBWAY" : "BUS",
id: item3.id,
title: item3.name,
type: item3.type,
station_count: Number(item3.via_num),
distance: Number(item3.distance),
duration: this.durationFormat(item3.cost.duration),
polyline: this.polylineFormat(item3.polyline),
start_time: item3.start_time,
end_time: item3.end_time,
geton: {
id: item3.departure_stop.id,
title: item3.departure_stop.name,
location: libs.common.getLocation(item3.departure_stop.location, "lng,lat", "object"),
},
getoff: {
id: item3.arrival_stop.id,
title: item3.arrival_stop.name,
location: libs.common.getLocation(item3.arrival_stop.location, "lng,lat", "object"),
},
stations: item3.via_stops.map((item4) => {
return {
id: item4.id,
title: item4.name,
location: libs.common.getLocation(item4.location, "lng,lat", "object"),
}
})
}
}),
}
} else if (mode === "railway") {
// 火车
let item3 = item2;
return {
mode: "transit",
lines: [{
vehicle: "RAIL",
id: item3.id,
title: item3.name,
type: item3.type,
distance: Number(item3.distance),
duration: this.durationFormat(item3.time),
geton: {
id: item3.departure_stop.id,
title: item3.departure_stop.name,
location: libs.common.getLocation(item3.departure_stop.location, "lng lat", "object"),
adcode: item3.departure_stop.adcode,
time: item3.departure_stop.time,
start: Number(item3.departure_stop.start),
},
getoff: {
id: item3.arrival_stop.id,
title: item3.arrival_stop.name,
location: libs.common.getLocation(item3.arrival_stop.location, "lng lat", "object"),
adcode: item3.arrival_stop.adcode,
time: item3.arrival_stop.time,
end: Number(item3.arrival_stop.end),
},
spaces: item3.spaces ? item3.spaces.map((item4) => {
return {
code: item4.code,
cost: this.priceFormat(item4.cost),
}
}) : undefined
}],
}
} else if (mode === "taxi") {
// 打车
let item3 = item2;
return {
mode: "transit",
lines: [{
vehicle: "TAXI",
distance: Number(item3.distance),
price: this.priceFormat(item3.price),
drivetime: this.durationFormat(item3.drivetime),
polyline: this.polylineFormat(item3.polyline),
startpoint: libs.common.getLocation(item3.startpoint, "lng,lat", "lat,lng"),
startname: item3.startname,
endpoint: libs.common.getLocation(item3.endpoint, "lng,lat", "lat,lng"),
endname: item3.endname
}]
}
}
});
return {
mode: "transit",
distance: Number(item.distance),
duration: this.durationFormat(item.cost.duration),
transit_fee: this.priceFormat(item.cost.transit_fee),
steps
}
});
let result = {
routes
};
let res = {
result,
...requestRes
};
return res;
}
getSteps(segments) {
let steps = [];
segments.map((item, index) => {
for (let mode in item) {
steps.push({
mode,
...item[mode]
});
}
});
return steps;
}
// 格式化价格将字符串价格转成数值保留2位小数
priceFormat(price) {
try {
if (price === "") {
return -1;
} else {
return parseFloat(Number(price).toFixed(2));
}
} catch (err) {
return -1;
}
}
// 格式化cost
costFormat(cost = {}) {
let {
duration,
taxi_cost,
transit_fee,
tolls,
toll_distance,
toll_road,
traffic_lights
} = cost;
let res = {};
if (typeof duration !== "undefined") res.duration = this.durationFormat(duration);
if (typeof taxi_cost !== "undefined") res.taxi_cost = this.priceFormat(taxi_cost);
if (typeof transit_fee !== "undefined") res.transit_fee = this.priceFormat(transit_fee);
if (typeof tolls !== "undefined") res.tolls = this.priceFormat(tolls);
if (typeof toll_distance !== "undefined") res.toll_distance = Number(toll_distance);
if (typeof toll_road !== "undefined") res.toll_road = toll_road;
if (typeof traffic_lights !== "undefined") res.traffic_lights = Number(traffic_lights);
return res;
}
// 格式化polyline将原本polyline.polyline转成polyline
polylineFormat(polyline = {}) {
if (polyline.polyline) {
return libs.common.getReversalLocation(polyline.polyline);
} else if (typeof polyline === "string") {
return libs.common.getReversalLocation(polyline);
} else {
return "";
}
}
// 格式化时间秒转分向上进1
durationFormat(duration) {
try {
return Math.ceil(Number(duration) / 60);
} catch (err) {
return undefined;
}
}
}
module.exports = Service;

View File

@@ -0,0 +1,4 @@
module.exports = {
"qqmap": require('./qqmap.js'),
"amap": require('./amap.js')
}

View File

@@ -0,0 +1,847 @@
const libs = require('../libs');
class Service {
// 构造函数
constructor(data = {}) {
let {
key,
needOriginalResult = false, // 是否需要返回原始信息默认false
} = data;
this.config = {
provider: "qqmap",
key,
needOriginalResult,
serviceUrl: "https://apis.map.qq.com"
}
}
async request(obj = {}) {
let {
url,
data = {}
} = obj;
if (url.indexOf("http") !== 0) {
url = `${this.config.serviceUrl}/${url}`
}
if (this.config.key && !data.key) {
data.key = this.config.key;
}
obj.data = JSON.parse(JSON.stringify(obj.data));
let requestRes = await uniCloud.httpclient.request(url, obj);
let result = this.getResult(requestRes);
if (result.errCode != 0) {
throw new libs.error.UniCloudError(result);
}
return result;
}
getResult(requestRes) {
let {
data: originalResult = {}
} = requestRes;
let res = {
errCode: originalResult.status == 0 ? 0 : this.getErrCode(originalResult.status),
errMsg: originalResult.message,
originalResult,
};
return res;
}
getErrCode(errCode) {
return errCode;
}
// API - 逆地址解析(坐标转地址)
async location2address(data = {}) {
let {
location,
get_poi,
poi_options
} = data;
let _poi_options = "";
if (typeof poi_options === "object") {
let {
address_format,
radius,
policy
} = poi_options;
if (address_format && address_format !== "long") {
_poi_options += `address_format=${address_format};`
}
if (radius) {
_poi_options += `radius=${radius};`
}
if (policy) {
_poi_options += `policy=${policy};`
}
if (_poi_options.lastIndexOf(";") === _poi_options.length - 1) {
_poi_options = _poi_options.substring(0, _poi_options.length - 1);
}
}
if (!_poi_options) _poi_options = undefined;
let requestRes = await this.request({
method: "GET",
url: "ws/geocoder/v1/",
dataType: "json",
data: {
location,
get_poi,
poi_options: _poi_options,
}
});
let originalResult = requestRes.originalResult.result;
let pois;
if (originalResult.pois) {
pois = originalResult.pois.map((item) => {
return {
id: item.id,
title: item.title,
address: item.address,
location: item.location,
distance: item._distance,
direction: item._dir_desc,
category: item.category
}
});
}
let result = {
formatted_addresses: originalResult.address,
country: originalResult.address_component.nation,
province: originalResult.address_component.province,
city: originalResult.address_component.city,
district: originalResult.address_component.district,
street: originalResult.address_component.street,
street_number: originalResult.address_component.street_number,
adcode: originalResult.ad_info.adcode,
pois
};
let res = {
result,
...requestRes
};
return res;
}
// API - 地址解析(地址转坐标)
async address2location(data = {}) {
let {
address,
city,
} = data;
let requestRes = await this.request({
method: "GET",
url: "ws/geocoder/v1/",
dataType: "json",
data: {
smart_address: address,
region: city,
}
});
let originalResult = requestRes.originalResult.result;
let result = {
location: originalResult.location,
adcode: originalResult.ad_info.adcode,
province: originalResult.address_components.province,
city: originalResult.address_components.city,
district: originalResult.address_components.district,
street: originalResult.address_components.street,
street_number: originalResult.address_components.street_number,
};
let res = {
result,
...requestRes
};
return res;
}
// API - 坐标转换
async translate(data = {}) {
let {
locations,
type,
} = data;
let locationsStr = "";
locations.map((item, index) => {
if (index > 0) {
locationsStr += ";";
}
locationsStr += libs.common.getLocation(item, "object", "lat,lng");
})
let requestRes = await this.request({
method: "GET",
url: "ws/coord/v1/translate",
dataType: "json",
data: {
locations: locationsStr,
type
}
});
let originalResult = requestRes.originalResult;
let result = {
locations: originalResult.locations
};
let res = {
result,
...requestRes
};
return res;
}
// API - IP定位
async ip2location(data = {}) {
let {
ip,
} = data;
let requestRes = await this.request({
method: "GET",
url: "ws/location/v1/ip",
dataType: "json",
data: {
ip
}
});
let originalResult = requestRes.originalResult.result;
let result = {
location: libs.common.getLocation(originalResult.location, "object", "object"),
nation: originalResult.ad_info.nation,
nation_code: originalResult.ad_info.nation_code,
adcode: originalResult.ad_info.adcode,
province: originalResult.ad_info.province,
city: originalResult.ad_info.city,
district: originalResult.ad_info.district
};
let res = {
result,
...requestRes
};
return res;
}
// API - 关键词输入提示
async inputtips(data = {}) {
let {
keyword,
city,
citylimit,
location,
get_subpois,
policy,
filter,
address_format,
page_index,
page_size
} = data;
let requestData = {
keyword,
region: city,
region_fix: citylimit ? 1 : 0,
get_subpois,
policy,
filter,
address_format,
page_index,
page_size
};
if (location) {
requestData.location = libs.common.getLocation(location, "object", "lat,lng");
}
let requestRes = await this.request({
method: "GET",
url: "ws/place/v1/suggestion",
dataType: "json",
data: requestData
});
let originalResult = requestRes.originalResult;
let _data = originalResult.data.map((item) => {
let children;
if (originalResult.sub_pois) {
children = [];
originalResult.sub_pois.map((item2) => {
if (item2.parent_id === item.id) {
children.push({
parent_id: item.id,
id: item2.id,
title: item2.title,
address: item2.address,
category: item2.category,
location: item2.location,
adcode: String(item2.adcode),
city: item2.city,
});
}
});
}
return {
id: item.id,
title: item.title,
address: item.address,
category: item.category,
type: item.type,
location: item.location,
adcode: item.adcode,
province: item.province,
city: item.city,
district: item.district,
children
}
});
let result = {
data: _data
};
let res = {
result,
...requestRes
};
return res;
}
// API - 周边搜索
async search(data = {}) {
let {
keyword,
location,
radius = 1000,
auto_extend = 1,
get_subpois,
orderby,
page_index = 1,
page_size = 20,
filter
} = data;
if (radius < 10) radius = 10;
let boundary = `nearby(${location.lat},${location.lng},${radius},${auto_extend})`;
let requestData = {
keyword,
boundary,
get_subpois,
filter,
orderby: orderby === "distance" ? "_distance" : undefined,
page_index,
page_size
};
let requestRes = await this.request({
method: "GET",
url: "ws/place/v1/search",
dataType: "json",
data: requestData
});
let originalResult = requestRes.originalResult;
let _data = originalResult.data.map((item) => {
let children;
if (originalResult.sub_pois) {
children = [];
originalResult.sub_pois.map((item2) => {
if (item2.parent_id === item.id) {
children.push({
parent_id: item.id,
id: item2.id,
title: item2.title,
address: item2.address,
category: item2.category,
location: item2.location,
tel: item2.tel,
adcode: String(item2.ad_info.adcode),
province: item2.ad_info.province,
city: item2.ad_info.city,
district: item2.ad_info.district,
});
}
});
}
return {
id: item.id,
title: item.title,
tel: item.tel,
address: item.address,
category: item.category,
type: item.type,
location: item.location,
distance: item._distance,
adcode: String(item.ad_info.adcode),
province: item.ad_info.province,
city: item.ad_info.city,
district: item.ad_info.district,
children
}
});
let result = {
data: _data
};
let res = {
result,
...requestRes
};
return res;
}
// API - 行政区划
async districtSearch(data = {}) {
let {
adcode,
get_polygon,
max_offset
} = data;
let requestData = {
id: adcode,
get_polygon,
max_offset
};
let requestRes = await this.request({
method: "GET",
url: "ws/district/v1/getchildren",
dataType: "json",
data: requestData
});
let originalResult = requestRes.originalResult;
let _data = originalResult.result[0].map((item) => {
return {
adcode: item.id,
name: item.name || item.fullname,
fullname: item.fullname,
location: item.location,
pinyin: item.pinyin,
cidx: item.cidx,
polygon: item.polygon,
}
});
let result = {
data: _data,
data_version: originalResult.data_version
};
let res = {
result,
...requestRes
};
return res;
}
// API - 路线规划(驾车)
async drivingRoute(data = {}) {
let {
mode,
from,
to,
from_poi,
to_poi,
policy,
waypoints,
avoid_polygons,
road_type,
plate_number,
cartype,
heading,
speed,
accuracy,
from_track,
get_mp,
no_step
} = data;
let requestRes = await this.request({
method: "GET",
url: `ws/direction/v1/driving`,
dataType: "json",
data: {
from,
to,
from_poi,
to_poi,
policy,
waypoints,
avoid_polygons,
road_type,
plate_number,
cartype,
heading,
speed,
accuracy,
from_track,
get_mp,
get_speed: 1,
added_fields: "cities",
no_step
}
});
let originalResult = requestRes.originalResult.result;
let routes = originalResult.routes.map((item) => {
let waypoints;
if (item.waypoints) {
waypoints = item.waypoints.map((item2) => {
return {
title: item2.title,
location: item2.location,
duration: item2.duration,
distance: item2.distance,
polyline: this.getPolyline(item.polyline, item2.polyline_idx),
polyline_idx: item2.polyline_idx,
}
});
}
let steps = item.steps.map((item2) => {
return {
instruction: item2.instruction,
road_name: item2.road_name,
dir_desc: item2.dir_desc,
distance: item2.distance,
act_desc: item2.act_desc,
accessorial_desc: item2.accessorial_desc,
polyline: this.getPolyline(item.polyline, item2.polyline_idx),
polyline_idx: item2.polyline_idx,
}
});
let speed = item.speed.map((item2) => {
return {
distance: item2.distance,
level: item2.level,
polyline: this.getPolyline(item.polyline, item2.polyline_idx),
polyline_idx: item2.polyline_idx,
}
});
return {
mode: "driving",
tags: item.tags,
distance: item.distance,
duration: item.duration,
traffic_light_count: item.traffic_light_count,
restriction_status: item.restriction.status,
polyline: this.polylineFormat(item.polyline),
waypoints,
taxi_cost: item.taxi_fare.fare,
cities: item.cities,
steps,
speed
}
});
let result = {
routes
};
let res = {
result,
...requestRes
};
return res;
}
// API - 路线规划(步行)
async walkingRoute(data = {}) {
let {
mode,
from,
to,
to_poi
} = data;
let requestRes = await this.request({
method: "GET",
url: `ws/direction/v1/walking`,
dataType: "json",
data: {
from,
to,
to_poi
}
});
let originalResult = requestRes.originalResult.result;
let routes = originalResult.routes.map((item) => {
let steps = item.steps.map((item2) => {
return {
instruction: item2.instruction,
road_name: item2.road_name,
dir_desc: item2.dir_desc,
distance: item2.distance,
act_desc: item2.act_desc,
type: item2.type,
polyline: this.getPolyline(item.polyline, item2.polyline_idx),
polyline_idx: item2.polyline_idx,
}
});
return {
mode: "walking",
distance: item.distance,
duration: item.duration,
direction: item.direction,
polyline: this.polylineFormat(item.polyline),
steps
}
});
let result = {
routes
};
let res = {
result,
...requestRes
};
return res;
}
// API - 路线规划(骑行)
async bicyclingRoute(data = {}) {
let {
mode,
from,
to,
to_poi
} = data;
let requestRes = await this.request({
method: "GET",
url: `ws/direction/v1/bicycling`,
dataType: "json",
data: {
from,
to,
to_poi
}
});
let originalResult = requestRes.originalResult.result;
let routes = originalResult.routes.map((item) => {
let steps = item.steps.map((item2) => {
return {
instruction: item2.instruction,
road_name: item2.road_name,
dir_desc: item2.dir_desc,
distance: item2.distance,
act_desc: item2.act_desc,
polyline: this.getPolyline(item.polyline, item2.polyline_idx),
polyline_idx: item2.polyline_idx
}
});
return {
mode: "bicycling",
distance: item.distance,
duration: item.duration,
direction: item.direction,
polyline: this.polylineFormat(item.polyline),
steps
}
});
let result = {
routes
};
let res = {
result,
...requestRes
};
return res;
}
// API - 路线规划(电动车)
async ebicyclingRoute(data = {}) {
let {
mode,
from,
to,
to_poi
} = data;
let requestRes = await this.request({
method: "GET",
url: `ws/direction/v1/ebicycling`,
dataType: "json",
data: {
from,
to,
to_poi
}
});
let originalResult = requestRes.originalResult.result;
let routes = originalResult.routes.map((item) => {
let steps = item.steps.map((item2) => {
return {
instruction: item2.instruction,
polyline_idx: item2.polyline_idx,
road_name: item2.road_name,
dir_desc: item2.dir_desc,
distance: item2.distance,
act_desc: item2.act_desc,
polyline: this.getPolyline(item.polyline, item2.polyline_idx)
}
});
return {
mode: "ebicycling",
distance: item.distance,
duration: item.duration,
direction: item.direction,
polyline: this.polylineFormat(item.polyline),
steps
}
});
let result = {
routes
};
let res = {
result,
...requestRes
};
return res;
}
// API - 路线规划(公交)
async transitRoute(data = {}) {
let {
mode,
from,
to,
from_poi,
to_poi,
departure_time,
policy
} = data;
let requestRes = await this.request({
method: "GET",
url: `ws/direction/v1/transit`,
dataType: "json",
data: {
from,
to,
from_poi,
to_poi,
departure_time,
policy
}
});
let originalResult = requestRes.originalResult.result;
let routes = originalResult.routes.map((item) => {
let steps = item.steps.map((item2) => {
let mode = item2.mode.toLowerCase();
if (mode === "walking") {
// 步行
return {
mode: mode,
distance: item2.distance,
duration: item2.duration,
direction: item2.direction,
polyline: this.polylineFormat(item2.polyline),
steps: item2.steps ? item2.steps.map((item3) => {
return {
instruction: item3.instruction,
road_name: item3.road_name,
act_desc: item3.dir_desc,
distance: item3.distance,
polyline: this.getPolyline(item2.polyline, item3.polyline_idx),
polyline_idx: item3.polyline_idx,
}
}) : undefined,
}
} else {
// 非步行
return {
mode: mode,
lines: item2.lines.map((item3) => {
return {
...item3,
price: item3.vehicle !== "RAIL" ? this.priceFormat(item3.price) : item3.price,
polyline: this.polylineFormat(item3.polyline)
}
})
}
}
});
return {
mode: "transit",
distance: item.distance,
duration: item.duration,
bounds: item.bounds,
steps
}
});
let result = {
routes
};
let res = {
result,
...requestRes
};
return res;
}
// 格式化polyline将压缩的polyline还原成完整的经纬度
polylineFormat(polyline) {
try {
let coors = JSON.parse(JSON.stringify(polyline));
for (let i = 2; i < coors.length; i++) {
coors[i] = parseFloat((coors[i - 2] + coors[i] / 1000000).toFixed(6));
}
return coors;
} catch (err) {
return "";
}
}
// 格式化价格将以分为单位的价格转元保留2位小数
priceFormat(price) {
try {
if (price === "" || price == -1) {
return -1;
} else {
return parseFloat((price / 100).toFixed(2));
}
} catch (err) {
return -1;
}
}
getPolyline(polyline, polyline_idx) {
let polylineArr = this.polylineFormat(polyline);
if (typeof polyline_idx == "object") {
let arr = polylineArr.slice(polyline_idx[0], polyline_idx[1] + 1);
let str = "";
arr.map((item, index) => {
if (index % 2 === 0) {
str += `${item}`
} else {
str += `,${item};`
}
});
// 去除最后一个;
if (str.lastIndexOf(";") === str.length - 1) {
str = str.substring(0, str.length - 1);
}
return str;
} else {
return polylineArr[polyline_idx] + "," + polylineArr[polyline_idx + 1];
}
}
}
module.exports = Service;

View File

@@ -0,0 +1,501 @@
// 引入uni-map-common公共模块
const UniMap = require('uni-map-common');
const configCenter = require("uni-config-center");
// 读取配置中心地图配置
var UniMapConfig = configCenter({ pluginId: 'uni-map' }).requireFile('config.js');
// 本地地图配置
var LocalMapConfig = {
"default": "", // 默认使用的平台
"key": {
"qqmap": "", // 腾讯地图key
"amap": "", // 高德地图key
}
}
const db = uniCloud.database();
const _ = db.command;
const $ = _.aggregate;
const opendbPoiDB = db.collection("opendb-poi");
module.exports = {
_before: function() {
// 如果配置中心不存在地图配置,则使用本地地图配置
if (!UniMapConfig) {
UniMapConfig = LocalMapConfig;
}
let defaultProvider = UniMapConfig.default || "qqmap";
let params = this.getParams();
let {
provider = defaultProvider
} = params[0] || {};
console.log('provider: ', provider)
const key = UniMapConfig.key[provider] || LocalMapConfig.key[provider];
if (!key) {
throw { errCode: -1, errMsg: `请在uni-config-center/uni-map/config.js中或LocalMapConfig中配置地图供应商${provider}对应的key` };
}
// 初始化实例
let uniMap = new UniMap({
provider: provider, // 指定使用哪家地图供应商
key: key,
needOriginalResult: false
});
this.uniMap = uniMap;
},
_after: function(error, res) {
if (error) {
throw error; // 如果方法抛出错误,也直接抛出不处理
}
console.log("result", res.result);
return res;
},
// 经纬度坐标转地址
async location2address(data = {}) {
let res = {};
// 获取uniMap实例
const uniMap = this.uniMap;
// 调用API
let result = await uniMap.location2address(data);
res.result = result;
return res;
},
// 地址转经纬度坐标
async address2location(data = {}) {
let res = {};
// 获取uniMap实例
const uniMap = this.uniMap;
// 调用API
let result = await uniMap.address2location(data);
res.result = result;
return res;
},
// 坐标系转换
async translate(data = {}) {
let res = {};
// 获取uniMap实例
const uniMap = this.uniMap;
// 调用API
let result = await uniMap.translate(data);
res.result = result;
return res;
},
// ip定位
async ip2location(data = {}) {
let res = {};
// 获取uniMap实例
const uniMap = this.uniMap;
// 调用API
let result = await uniMap.ip2location(data);
res.result = result;
return res;
},
// 输入提示
async inputtips(data = {}) {
let res = {};
// 获取uniMap实例
const uniMap = this.uniMap;
// 调用API
let result = await uniMap.inputtips(data);
res.result = result;
return res;
},
// 搜索
async search(data = {}) {
let res = {};
// 获取uniMap实例
const uniMap = this.uniMap;
// 调用API
let result = await uniMap.search(data);
res.result = result;
return res;
},
// 行政区划
async districtSearch(data = {}) {
let res = {};
// 获取uniMap实例
const uniMap = this.uniMap;
// 调用API
let result = await uniMap.districtSearch(data);
res.result = result;
return res;
},
// 路径规划
async route(data = {}) {
let res = {};
// 获取uniMap实例
const uniMap = this.uniMap;
// 调用API
let result = await uniMap.route(data);
res.result = result;
return res;
},
// 演示用 - 清空所有的测试POI
async clearPoi(data = {}) {
let res = { errCode: 0 };
const db = uniCloud.database();
await db.collection("opendb-poi").where({
is_random: true
}).remove();
return res;
},
// 演示用 - 初始化静态001场景演示数据
async initStatic001(data = {}) {
let res = { errCode: 0 };
const category = "static-001";
// 先删除
await opendbPoiDB.where({
category: category
}).remove();
// 后添加随机数据
// 以天安门为中心
let tiananmen = {
longitude: 116.39747,
latitude: 39.908823,
};
let time = Date.now();
// 随机生成6个门店地址
let list = [];
for (let i = 1; i <= 6; i++) {
let randomCoordinate = getRandomCoordinateWithinRadius(tiananmen.longitude, tiananmen.latitude, 10); // 随机生成在天安门方圆X KM内的坐标
list.push({
category: category, // 场景值用于区分这些POI所属哪张地图
type: "门店",
title: `随机门店-${i}`,
location: new db.Geo.Point(randomCoordinate.longitude, randomCoordinate.latitude),
create_date: time,
visible: true,
is_random: true, // 表示此为随机生成的点,方便删除
level: i
});
}
// 随机生成1个总部地址
let randomCoordinate = getRandomCoordinateWithinRadius(tiananmen.longitude, tiananmen.latitude, 1); // 随机生成在天安门方圆X KM内的坐标
list.push({
category: category, // 场景值用于区分这些POI所属哪张地图
type: "总部",
title: `随机总部`,
location: new db.Geo.Point(randomCoordinate.longitude, randomCoordinate.latitude),
create_date: time,
visible: true,
is_random: true, // 表示此为随机生成的点,方便删除
level: 7
});
// 添加到数据库
await opendbPoiDB.add(list);
return res;
},
// 演示用 - 初始化动态001场景演示数据模拟送外卖场景
async initDynamics001(data = {}) {
let res = { errCode: 0 };
const category = "dynamics-001";
// 先删除
await opendbPoiDB.where({
category: category
}).remove();
// 后添加随机数据
// 以天安门为中心
let tiananmen = {
longitude: 116.39747,
latitude: 39.908823,
};
let time = Date.now();
// 随机生成配送员坐标
let randomCoordinate1 = getRandomCoordinateWithinRadius(tiananmen.longitude, tiananmen.latitude, 2); // 随机生成在天安门方圆X KM内的坐标
let data1 = {
category: category, // 场景值用于区分这些POI所属哪张地图
type: "配送员",
title: "配送员",
location: new db.Geo.Point(randomCoordinate1.longitude, randomCoordinate1.latitude),
create_date: time,
visible: true,
is_random: true, // 表示此为随机生成的点,方便删除
}
// 随机生成目的地坐标
let randomCoordinate2 = getRandomCoordinateWithinRadius(tiananmen.longitude, tiananmen.latitude, 2); // 随机生成在天安门方圆X KM内的坐标
let data2 = {
category: category, // 场景值用于区分这些POI所属哪张地图
type: "目的地",
title: "配送目的地",
location: new db.Geo.Point(randomCoordinate2.longitude, randomCoordinate2.latitude),
create_date: time,
visible: true,
is_random: true, // 表示此为随机生成的点,方便删除
}
let list = [data1, data2];
// 添加到数据库
await opendbPoiDB.add(list);
// 获取配送路线
// 获取uniMap实例
const uniMap = this.uniMap;
// 调用电瓶车路径规划API
let result = await uniMap.route({
mode: "ebicycling",
from: `${randomCoordinate1.latitude},${randomCoordinate1.longitude}`,
to: `${randomCoordinate2.latitude},${randomCoordinate2.longitude}`,
alternative_route: 1
});
let route = result.result.routes[0];
let { steps = [] } = route;
let points = [];
steps.map((step) => {
let {
polyline = ""
} = step;
let arr = polyline.split(";");
arr.map((item) => {
let arr2 = item.split(",");
points.push({
latitude: arr2[0],
longitude: arr2[1],
});
});
});
let polyline = {
points,
color: "#19b411",
width: 6,
dottedLine: false,
arrowLine: true,
borderWidth: 1,
borderColor: "#000000",
};
res.polyline = [polyline];
return res;
},
// 演示用 - 获取配送员配送路径
async getPolyline(data = {}) {
let res = { errCode: 0 };
const category = "dynamics-001";
let getRes1 = await opendbPoiDB.where({
category: category,
type: "配送员",
visible: true
}).get();
let poi1 = getRes1.data[0];
let getRes2 = await opendbPoiDB.where({
category: category,
type: "目的地",
visible: true
}).get();
let poi2 = getRes2.data[0];
if (!poi2) {
return {
errCode: 0,
end: true
}
}
let coordinate1 = {
longitude: poi1.location.coordinates[0],
latitude: poi1.location.coordinates[1]
};
let coordinate2 = {
longitude: poi2.location.coordinates[0],
latitude: poi2.location.coordinates[1]
};
// 获取uniMap实例
const uniMap = this.uniMap;
// 调用电瓶车路径规划API
let result = await uniMap.route({
mode: "ebicycling",
from: `${coordinate1.latitude},${coordinate1.longitude}`,
to: `${coordinate2.latitude},${coordinate2.longitude}`,
alternative_route: 1
});
let route = result.result.routes[0];
//console.log('route: ', route)
let { steps = [], distance, duration } = route;
let points = [];
let dir_desc;
steps.map((step) => {
let {
polyline = ""
} = step;
if (!dir_desc) dir_desc = step.dir_desc;
if (polyline) {
let arr = polyline.split(";");
arr.map((item) => {
let arr2 = item.split(",");
if (!isNaN(arr2[0]) && !isNaN(arr2[1])) {
points.push({
latitude: Number(arr2[0]),
longitude: Number(arr2[1]),
});
}
});
}
});
let polyline = {
points,
color: "#19b411",
width: 6,
dottedLine: false,
arrowLine: true,
borderWidth: 1,
borderColor: "#000000",
};
res.polyline = [polyline];
if (distance <= 30 || duration <= 0) {
await opendbPoiDB.doc(poi1._id).update({
title: `配送员已到达目的地`,
location: new db.Geo.Point(Number(coordinate2.longitude), Number(coordinate2.latitude)),
rotate: 0
});
// 隐藏目的地
await opendbPoiDB.doc(poi2._id).update({
visible: false,
});
return {
errCode: 0,
end: true
}
} else {
// 从最近2个点计算出当前行驶方向
let rotate = 0;
if (points && points.length >= 2) {
rotate = calculateDirectionAngle(points[0], points[1]);
}
await opendbPoiDB.doc(poi1._id).update({
title: `配送员正在配送\r\n还有 ${distance}\r\n预计 ${duration} 分钟送达`,
rotate: rotate, // 设置角度0°的图片方向应朝左(西) 故90° 朝上(北) 180° 朝右(东) 270° 朝下(南)
});
}
return res;
},
// 演示用 - 模拟上报配送员坐标
async updateMyLocation(data = {}) {
let res = {};
const category = "dynamics-001";
let {
longitude,
latitude
} = data;
let getRes1 = await opendbPoiDB.where({
category: category,
type: "配送员",
visible: true
}).get();
let poi1 = getRes1.data[0];
await opendbPoiDB.doc(poi1._id).update({
location: new db.Geo.Point(Number(longitude), Number(latitude))
});
return res;
},
// 演示用 - xxxx
async test(data = {}) {
let res = {};
// 获取uniMap实例
const uniMap = this.uniMap;
// 调用API
let result = await uniMap.location2address({
});
res.result = result;
return res;
}
}
/**
* 生成在指定经纬度圆内的随机坐标
const latitude = 39.908823; // 指定纬度
const longitude = 116.39747; // 指定经度
const radiusInKm = 10; // 指定圆的半径(单位:千米)
const randomCoordinate = getRandomCoordinateWithinRadius(latitude, longitude, radiusInKm);
console.log(randomCoordinate);
*/
function getRandomCoordinateWithinRadius(longitude, latitude, radiusInKm) {
// 地球半径(单位:千米)
const earthRadius = 6371;
// 将圆的半径转换为弧度
const radiusInRad = radiusInKm / earthRadius;
// 生成随机的方位角弧度0到2π
const randomAngleRad = Math.random() * 2 * Math.PI;
// 生成随机的距离弧度0到圆的半径
const randomDistanceRad = Math.acos(Math.random() * (Math.cos(radiusInRad) - 1) + 1);
// 使用球面三角学计算随机点的纬度和经度
const randomLatitudeRad = latitude * (Math.PI / 180) + randomDistanceRad * Math.cos(randomAngleRad);
const randomLongitudeRad = longitude * (Math.PI / 180) + randomDistanceRad * Math.sin(randomAngleRad) / Math.cos(latitude * (Math.PI / 180));
// 转换为度并保留6位小数
const randomLatitude = parseFloat((randomLatitudeRad * (180 / Math.PI)).toFixed(6));
const randomLongitude = parseFloat((randomLongitudeRad * (180 / Math.PI)).toFixed(6));
return { latitude: randomLatitude, longitude: randomLongitude };
}
/**
* 计算坐标B在坐标A的方向0代表正西方 90 代表正北方
const latitude = 39.908823; // 指定纬度
const longitude = 116.39747; // 指定经度
const radiusInKm = 10; // 指定圆的半径(单位:千米)
const randomCoordinate = getRandomCoordinateWithinRadius(latitude, longitude, radiusInKm);
console.log(randomCoordinate);
*/
function calculateDirectionAngle(coordA, coordB) {
const toRadians = (angle) => angle * (Math.PI / 180);
const toDegrees = (angle) => angle * (180 / Math.PI);
const lat1 = toRadians(coordA.latitude);
const lon1 = toRadians(coordA.longitude);
const lat2 = toRadians(coordB.latitude);
const lon2 = toRadians(coordB.longitude);
const dLon = lon2 - lon1;
const y = Math.sin(dLon) * Math.cos(lat2);
const x =
Math.cos(lat1) * Math.sin(lat2) -
Math.sin(lat1) * Math.cos(lat2) * Math.cos(dLon);
const angleRadians = Math.atan2(y, x);
let angleDegrees = toDegrees(angleRadians);
angleDegrees = (angleDegrees + 360) % 360;
angleDegrees = (angleDegrees > 180) ? angleDegrees - 180 : angleDegrees + 180;
angleDegrees -= 90; // 以正西方为0°表示因此需要-90
return angleDegrees;
}

View File

@@ -0,0 +1,9 @@
{
"name": "uni-map-co",
"dependencies": {
"uni-config-center": "file:../../../../uni-config-center/uniCloud/cloudfunctions/common/uni-config-center",
"uni-map-common": "file:../common/uni-map-common",
"uni-id-common": "file:../../../../uni-id-common/uniCloud/cloudfunctions/common/uni-id-common"
},
"extensions": {}
}

View File

@@ -0,0 +1,104 @@
location2address({
location: "39.908815,116.397507",
get_poi: 1,
poi_options: {
address_format: "short",
radius: 5000,
policy: 4,
//poitype: "010101",
roadlevel: 1,
homeorcorp: 1
}
});
// address2location({
// address: "北京市海淀区彩和坊路海淀西大街74号",
// city: "北京"
// });
// translate({
// locations: [
// { lat: 39.908815, lng: 116.397507 },
// { lat: 39.908815, lng: 116.397107 }
// ],
// type: 3
// });
// ip定位
// ip2location({
// ip: "111.206.145.41"
// });
// 输入提示
// inputtips({
// keyword: "人民医院",
// city: "北京市",
// datatype: "all",
// get_subpois: 1
// });
// 周边搜索
// search({
// keyword: "酒店",
// location: {
// lat: 39.908815,
// lng: 116.397507
// },
// radius: 1000,
// auto_extend: 1,
// get_subpois: 1,
// orderby: "weight",
// page_index: 1,
// page_size: 20,
// city: "北京市"
// });
// 行政区划
// districtSearch({
// adcode: "110000",
// get_polygon: 2,
// max_offset: 500,
// subdistrict: 2
// });
// 导航 - 驾车
// route({
// mode: "driving",
// from: "39.808815,116.387507",
// to: "39.908815,116.397507",
// get_mp: 1,
// });
// 导航 - 步行
// route({
// mode: "walking",
// from: "40.034852,116.319820",
// to: "39.771075,116.351395",
// alternative_route: 3
// });
// 导航 - 骑行
// route({
// mode: "bicycling",
// from: "40.034852,116.319820",
// to: "39.771075,116.351395",
// alternative_route: 3
// });
// 导航 - 电动车
// route({
// mode: "ebicycling",
// from: "40.034852,116.319820",
// to: "39.771075,116.351395",
// alternative_route: 3
// });
// 导航 - 公交
// route({
// mode: "transit",
// from: "40.034852,116.319820",
// to: "29.771075,116.351395",
// //alternative_route: 3,
// city1: "010",
// city2: "0792",
// });

View File

@@ -0,0 +1,8 @@
## 1.0.32022-01-21
- 优化 组件示例
## 1.0.22021-11-22
- 修复 / 符号在 vue 不同版本兼容问题引起的报错问题
## 1.0.12021-11-22
- 修复 vue3中scss语法兼容问题
## 1.0.02021-11-18
- init

View File

@@ -0,0 +1 @@
@import './styles/index.scss';

View File

@@ -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"
}
}
}
}
}

View File

@@ -0,0 +1,4 @@
`uni-sass``uni-ui`提供的一套全局样式 ,通过一些简单的类名和`sass`变量,实现简单的页面布局操作,比如颜色、边距、圆角等。
### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-sass)
#### 如使用过程中有任何问题或者您对uni-ui有一些好的建议欢迎加入 uni-ui 交流群871950839

View File

@@ -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';

View File

@@ -0,0 +1,3 @@
.uni-border {
border: 1px $uni-border-1 solid;
}

View File

@@ -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;
}

View File

@@ -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)
}
}
}
}

View File

@@ -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);
}
}
}
}

View File

@@ -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 */

View File

@@ -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 */
}

View File

@@ -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;

View File

@@ -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;
};

View File

@@ -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);

View File

@@ -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);