'初始化框架'
This commit is contained in:
commit
4c8780569f
3
.env.development
Normal file
3
.env.development
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
NODE_ENV='development'
|
||||||
|
VITE_APP_TITLE='开发环境'
|
||||||
|
VITE_APP_BASE_API='http://114.132.197.85:8099'
|
3
.env.production
Normal file
3
.env.production
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
NODE_ENV='production'
|
||||||
|
VITE_APP_TITLE='生产环境'
|
||||||
|
VITE_APP_BASE_API=''
|
3
.env.test
Normal file
3
.env.test
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
NODE_ENV='test'
|
||||||
|
VITE_APP_TITLE='测试环境'
|
||||||
|
VITE_APP_BASE_API=''
|
21
.gitignore
vendored
Normal file
21
.gitignore
vendored
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
# Logs
|
||||||
|
logs
|
||||||
|
*.log
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
pnpm-debug.log*
|
||||||
|
lerna-debug.log*
|
||||||
|
|
||||||
|
node_modules
|
||||||
|
.DS_Store
|
||||||
|
dist
|
||||||
|
*.local
|
||||||
|
|
||||||
|
# Editor directories and files
|
||||||
|
.idea
|
||||||
|
*.suo
|
||||||
|
*.ntvs*
|
||||||
|
*.njsproj
|
||||||
|
*.sln
|
||||||
|
*.sw?
|
24
README.md
Normal file
24
README.md
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
## 介绍
|
||||||
|
- - DCloud / uni-preset-vue 基于这个框架再次进行修改
|
||||||
|
- - 基于vue3、pinia、uni-ui、luch-request、sass、uniapp强大的移动端框架。
|
||||||
|
- - 开箱即用省去部分的开发时间;支持微信小程序和h5的框架
|
||||||
|
- - 本框架已实现请求数据库的封装,pinia的基本使用,跨域请求数据、以及全局的自定义样式弹窗(个人感觉比uniapp里面的好看和实用)
|
||||||
|
|
||||||
|
## 安装依赖
|
||||||
|
建议node版本在18版本
|
||||||
|
pnpm install
|
||||||
|
|
||||||
|
# 开发注意
|
||||||
|
1. 处理富文本必须使用rich-text标签,用html-parser.js来转换数据
|
||||||
|
2. 简单的弹窗提醒用公共组件ConfirmPopup
|
||||||
|
3. 消息提醒必须用uni.$showTost
|
||||||
|
|
||||||
|
# h5打包发布
|
||||||
|
配置相对应的env文件
|
||||||
|
测试环境 pnpm run build:h5:test
|
||||||
|
正式环境 pnpm run build:h5
|
||||||
|
|
||||||
|
# 如果使用pnpm install报错 (应该是报的版本问题:Error: Expected "0.17.19" but got "0.16.17")
|
||||||
|
1. pnpm store prune
|
||||||
|
2. 删除node_modules
|
||||||
|
3. 手动安装esbuild@0.17.19
|
20
index.html
Normal file
20
index.html
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<script>
|
||||||
|
var coverSupport = 'CSS' in window && typeof CSS.supports === 'function' && (CSS.supports('top: env(a)') ||
|
||||||
|
CSS.supports('top: constant(a)'))
|
||||||
|
document.write(
|
||||||
|
'<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0' +
|
||||||
|
(coverSupport ? ', viewport-fit=cover' : '') + '" />')
|
||||||
|
</script>
|
||||||
|
<title></title>
|
||||||
|
<!--preload-links-->
|
||||||
|
<!--app-context-->
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="app"><!--app-html--></div>
|
||||||
|
<script type="module" src="/src/main.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
76
package.json
Normal file
76
package.json
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
{
|
||||||
|
"name": "uni-preset-vue",
|
||||||
|
"version": "0.0.0",
|
||||||
|
"scripts": {
|
||||||
|
"dev:app": "uni -p app",
|
||||||
|
"dev:app-android": "uni -p app-android",
|
||||||
|
"dev:app-ios": "uni -p app-ios",
|
||||||
|
"dev:custom": "uni -p",
|
||||||
|
"dev:h5": "cross-env vite --mode development",
|
||||||
|
"dev:h5:ssr": "uni --ssr",
|
||||||
|
"dev:mp-alipay": "uni -p mp-alipay",
|
||||||
|
"dev:mp-baidu": "uni -p mp-baidu",
|
||||||
|
"dev:mp-jd": "uni -p mp-jd",
|
||||||
|
"dev:mp-kuaishou": "uni -p mp-kuaishou",
|
||||||
|
"dev:mp-lark": "uni -p mp-lark",
|
||||||
|
"dev:mp-qq": "uni -p mp-qq",
|
||||||
|
"dev:mp-toutiao": "uni -p mp-toutiao",
|
||||||
|
"dev:mp-weixin": "uni -p mp-weixin",
|
||||||
|
"dev:mp-xhs": "uni -p mp-xhs",
|
||||||
|
"dev:quickapp-webview": "uni -p quickapp-webview",
|
||||||
|
"dev:quickapp-webview-huawei": "uni -p quickapp-webview-huawei",
|
||||||
|
"dev:quickapp-webview-union": "uni -p quickapp-webview-union",
|
||||||
|
"build:app": "uni build -p app",
|
||||||
|
"build:app-android": "uni build -p app-android",
|
||||||
|
"build:app-ios": "uni build -p app-ios",
|
||||||
|
"build:custom": "uni build -p",
|
||||||
|
"build:h5:test": "cross-env NODE_ENV=test vite build --mode test",
|
||||||
|
"build:h5": "cross-env NODE_ENV=production vite build --mode production",
|
||||||
|
"build:h5:ssr": "uni build --ssr",
|
||||||
|
"build:mp-alipay": "uni build -p mp-alipay",
|
||||||
|
"build:mp-baidu": "uni build -p mp-baidu",
|
||||||
|
"build:mp-jd": "uni build -p mp-jd",
|
||||||
|
"build:mp-kuaishou": "uni build -p mp-kuaishou",
|
||||||
|
"build:mp-lark": "uni build -p mp-lark",
|
||||||
|
"build:mp-qq": "uni build -p mp-qq",
|
||||||
|
"build:mp-toutiao": "uni build -p mp-toutiao",
|
||||||
|
"build:mp-weixin": "uni build -p mp-weixin",
|
||||||
|
"build:mp-xhs": "uni build -p mp-xhs",
|
||||||
|
"build:quickapp-webview": "uni build -p quickapp-webview",
|
||||||
|
"build:quickapp-webview-huawei": "uni build -p quickapp-webview-huawei",
|
||||||
|
"build:quickapp-webview-union": "uni build -p quickapp-webview-union"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@dcloudio/uni-app": "3.0.0-3090420231025001",
|
||||||
|
"@dcloudio/uni-app-plus": "3.0.0-3090420231025001",
|
||||||
|
"@dcloudio/uni-components": "3.0.0-3090420231025001",
|
||||||
|
"@dcloudio/uni-h5": "3.0.0-3090420231025001",
|
||||||
|
"@dcloudio/uni-mp-alipay": "3.0.0-3090420231025001",
|
||||||
|
"@dcloudio/uni-mp-baidu": "3.0.0-3090420231025001",
|
||||||
|
"@dcloudio/uni-mp-jd": "3.0.0-3090420231025001",
|
||||||
|
"@dcloudio/uni-mp-kuaishou": "3.0.0-3090420231025001",
|
||||||
|
"@dcloudio/uni-mp-lark": "3.0.0-3090420231025001",
|
||||||
|
"@dcloudio/uni-mp-qq": "3.0.0-3090420231025001",
|
||||||
|
"@dcloudio/uni-mp-toutiao": "3.0.0-3090420231025001",
|
||||||
|
"@dcloudio/uni-mp-weixin": "3.0.0-3090420231025001",
|
||||||
|
"@dcloudio/uni-mp-xhs": "3.0.0-3090420231025001",
|
||||||
|
"@dcloudio/uni-quickapp-webview": "3.0.0-3090420231025001",
|
||||||
|
"@dcloudio/uni-ui": "^1.5.6",
|
||||||
|
"cross-env": "^7.0.3",
|
||||||
|
"esbuild": "0.17.19",
|
||||||
|
"lodash": "^4.17.21",
|
||||||
|
"pinia": "2.0.3",
|
||||||
|
"sass": "1.63.4",
|
||||||
|
"vue": "^3.2.45",
|
||||||
|
"vue-i18n": "9.1.9"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@dcloudio/types": "^3.3.2",
|
||||||
|
"@dcloudio/uni-automator": "3.0.0-3090420231025001",
|
||||||
|
"@dcloudio/uni-cli-shared": "3.0.0-3090420231025001",
|
||||||
|
"@dcloudio/uni-stacktracey": "3.0.0-3090420231025001",
|
||||||
|
"@dcloudio/vite-plugin-uni": "3.0.0-3090420231025001",
|
||||||
|
"@vue/runtime-core": "^3.2.45",
|
||||||
|
"vite": "4.0.3"
|
||||||
|
}
|
||||||
|
}
|
7514
pnpm-lock.yaml
Normal file
7514
pnpm-lock.yaml
Normal file
File diff suppressed because it is too large
Load Diff
19
src/App.vue
Normal file
19
src/App.vue
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
globalData: {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { onLaunch } from "@dcloudio/uni-app";
|
||||||
|
import { ref } from "vue";
|
||||||
|
|
||||||
|
onLaunch( async(e) => {
|
||||||
|
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
<style lang="scss">
|
||||||
|
@import 'assets/css/common.scss';
|
||||||
|
</style>
|
10
src/api/index.js
Normal file
10
src/api/index.js
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
import request from '@/utils/request';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @function
|
||||||
|
* @return
|
||||||
|
**/
|
||||||
|
export const getFriendLink = (params) => {
|
||||||
|
return request.get('',{params})
|
||||||
|
}
|
||||||
|
|
12
src/assets/css/common.scss
Normal file
12
src/assets/css/common.scss
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
view{
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
button {
|
||||||
|
margin: 0 !important;
|
||||||
|
border: none !important;
|
||||||
|
border-radius: 16rpx;
|
||||||
|
}
|
||||||
|
.pages {
|
||||||
|
height: 100vh;
|
||||||
|
font-size: 26rpx;
|
||||||
|
}
|
137
src/components/comfirm-popup.vue
Normal file
137
src/components/comfirm-popup.vue
Normal file
@ -0,0 +1,137 @@
|
|||||||
|
<template>
|
||||||
|
<view>
|
||||||
|
<uni-popup ref="popup" background-color="#fff" :is-mask-click="processLoad.isMaskClick" :mask-click="processLoad.isMaskClick">
|
||||||
|
<view class="popup-content">
|
||||||
|
<view class="header">{{params.title}}</view>
|
||||||
|
<view class="main">
|
||||||
|
<slot name="main">
|
||||||
|
<view class="content-box" v-if="!processLoad.isHtml" :style="processLoad.contentStyle">
|
||||||
|
{{params.content}}
|
||||||
|
</view>
|
||||||
|
<rich-text v-else class="content-box" :style="processLoad.contentStyle" :nodes="params.content"></rich-text>
|
||||||
|
</slot>
|
||||||
|
</view>
|
||||||
|
<slot name="footer">
|
||||||
|
<view class="footer">
|
||||||
|
<view v-if="processLoad.showCancel" class="confirm-btn1 cancel" @click="close" type="primary">取消</view>
|
||||||
|
<button :loading="confirmLoading" class="confirm-btn1" @click="confirm" type="primary">{{processLoad.confirmMsg}}</button>
|
||||||
|
</view>
|
||||||
|
</slot>
|
||||||
|
</view>
|
||||||
|
</uni-popup>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref,computed } from 'vue';
|
||||||
|
|
||||||
|
const popup = ref()
|
||||||
|
const confirmLoading = ref(false)
|
||||||
|
const params = ref({})
|
||||||
|
|
||||||
|
const processLoad = computed(() => {
|
||||||
|
const {
|
||||||
|
isHtml=false, // 是否为html
|
||||||
|
showCancel=true, // 是否显示取消按钮
|
||||||
|
isMaskClick=false, //点击遮罩层是否关闭弹窗
|
||||||
|
isLoading=false, // 确认按钮是否加loading
|
||||||
|
confirmMsg='确定', // 确认按钮的文字
|
||||||
|
close=()=>{}, // 弹窗关闭回调
|
||||||
|
confirm=()=>{}, // 弹窗确认回调
|
||||||
|
contentStyle // content样式
|
||||||
|
} = params.value.load || {}
|
||||||
|
|
||||||
|
return {
|
||||||
|
isHtml,
|
||||||
|
showCancel,
|
||||||
|
isMaskClick,
|
||||||
|
isLoading,
|
||||||
|
confirmMsg,
|
||||||
|
close,
|
||||||
|
confirm,
|
||||||
|
contentStyle
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const setParams = (row) => {
|
||||||
|
params.value = row
|
||||||
|
}
|
||||||
|
|
||||||
|
const close = () => {
|
||||||
|
processLoad.value.close()
|
||||||
|
popup.value.close()
|
||||||
|
}
|
||||||
|
|
||||||
|
const confirm = async () => {
|
||||||
|
if (processLoad.value.isLoading) {
|
||||||
|
confirmLoading.value = true
|
||||||
|
try {
|
||||||
|
await processLoad.value.confirm()
|
||||||
|
confirmLoading.value = false
|
||||||
|
popup.value.close()
|
||||||
|
} catch(err) {
|
||||||
|
confirmLoading.value = false
|
||||||
|
popup.value.close()
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
popup.value.close()
|
||||||
|
processLoad.value.confirm()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
defineExpose({
|
||||||
|
popup,
|
||||||
|
setParams
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
:deep(.uni-popup__wrapper) {
|
||||||
|
border-radius: 16rpx;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
.popup-content {
|
||||||
|
width: 668rpx;
|
||||||
|
.header {
|
||||||
|
width: 100%;
|
||||||
|
height: 90rpx;
|
||||||
|
line-height: 90rpx;
|
||||||
|
text-align: center;
|
||||||
|
color: #4679f0;
|
||||||
|
font-size: 35rpx;
|
||||||
|
background-color: #eff3ff;
|
||||||
|
}
|
||||||
|
.main {
|
||||||
|
width: 100%;
|
||||||
|
max-height: 800rpx;
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
padding: 22rpx;
|
||||||
|
overflow-y: auto;
|
||||||
|
.content-box {
|
||||||
|
margin-top: 40rpx;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.footer {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-around;
|
||||||
|
padding-bottom: 20rpx;
|
||||||
|
.confirm-btn1 {
|
||||||
|
width: 260rpx;
|
||||||
|
height: 80rpx;
|
||||||
|
background: #4679F0;
|
||||||
|
border-radius: 16rpx;
|
||||||
|
font-size: 30rpx;
|
||||||
|
color: #FFFFFF;
|
||||||
|
text-align: center;
|
||||||
|
line-height: 80rpx;
|
||||||
|
}
|
||||||
|
.cancel {
|
||||||
|
border: 1px solid #e8e8e8;
|
||||||
|
background: none !important;
|
||||||
|
color:#333333;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
25
src/hooks/utils.js
Normal file
25
src/hooks/utils.js
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
import { ref, nextTick } from 'vue';
|
||||||
|
|
||||||
|
// 公共弹窗hooks
|
||||||
|
export const useComfirmPopup = () => {
|
||||||
|
const popupShow = ref(false)
|
||||||
|
const comfirmPopupRef = ref()
|
||||||
|
|
||||||
|
const openPopup = (row = {}) => {
|
||||||
|
popupShow.value = true
|
||||||
|
nextTick(() => {
|
||||||
|
comfirmPopupRef.value.setParams({
|
||||||
|
title: row.title || '温馨提示',
|
||||||
|
content: row.content || '',
|
||||||
|
load: row.load || {}
|
||||||
|
})
|
||||||
|
comfirmPopupRef.value.popup.open()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
popupShow,
|
||||||
|
comfirmPopupRef,
|
||||||
|
openPopup
|
||||||
|
}
|
||||||
|
}
|
132
src/js_sdk/luch-request/luch-request/adapters/index.js
Normal file
132
src/js_sdk/luch-request/luch-request/adapters/index.js
Normal file
@ -0,0 +1,132 @@
|
|||||||
|
import buildURL from '../helpers/buildURL'
|
||||||
|
import buildFullPath from '../core/buildFullPath'
|
||||||
|
import settle from '../core/settle'
|
||||||
|
import {isUndefined} from "../utils"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 返回可选值存在的配置
|
||||||
|
* @param {Array} keys - 可选值数组
|
||||||
|
* @param {Object} config2 - 配置
|
||||||
|
* @return {{}} - 存在的配置项
|
||||||
|
*/
|
||||||
|
const mergeKeys = (keys, config2) => {
|
||||||
|
let config = {}
|
||||||
|
keys.forEach(prop => {
|
||||||
|
if (!isUndefined(config2[prop])) {
|
||||||
|
config[prop] = config2[prop]
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return config
|
||||||
|
}
|
||||||
|
export default (config) => {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
let fullPath = buildURL(buildFullPath(config.baseURL, config.url), config.params, config.paramsSerializer)
|
||||||
|
const _config = {
|
||||||
|
url: fullPath,
|
||||||
|
header: config.header,
|
||||||
|
complete: (response) => {
|
||||||
|
config.fullPath = fullPath
|
||||||
|
response.config = config
|
||||||
|
response.rawData = response.data
|
||||||
|
try {
|
||||||
|
let jsonParseHandle = false
|
||||||
|
const forcedJSONParsingType = typeof config.forcedJSONParsing
|
||||||
|
if (forcedJSONParsingType === 'boolean') {
|
||||||
|
jsonParseHandle = config.forcedJSONParsing
|
||||||
|
} else if (forcedJSONParsingType === 'object') {
|
||||||
|
const includesMethod = config.forcedJSONParsing.include || []
|
||||||
|
jsonParseHandle = includesMethod.includes(config.method)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 对可能字符串不是json 的情况容错
|
||||||
|
if (jsonParseHandle && typeof response.data === 'string') {
|
||||||
|
response.data = JSON.parse(response.data)
|
||||||
|
}
|
||||||
|
// eslint-disable-next-line no-empty
|
||||||
|
} catch (e) {
|
||||||
|
}
|
||||||
|
settle(resolve, reject, response)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let requestTask
|
||||||
|
if (config.method === 'UPLOAD') {
|
||||||
|
delete _config.header['content-type']
|
||||||
|
delete _config.header['Content-Type']
|
||||||
|
let otherConfig = {
|
||||||
|
// #ifdef MP-ALIPAY
|
||||||
|
fileType: config.fileType,
|
||||||
|
// #endif
|
||||||
|
filePath: config.filePath,
|
||||||
|
name: config.name
|
||||||
|
}
|
||||||
|
const optionalKeys = [
|
||||||
|
// #ifdef APP-PLUS || H5
|
||||||
|
'files',
|
||||||
|
// #endif
|
||||||
|
// #ifdef H5
|
||||||
|
'file',
|
||||||
|
// #endif
|
||||||
|
// #ifdef H5 || APP-PLUS || MP-WEIXIN || MP-ALIPAY || MP-TOUTIAO || MP-KUAISHOU
|
||||||
|
'timeout',
|
||||||
|
// #endif
|
||||||
|
'formData'
|
||||||
|
]
|
||||||
|
requestTask = uni.uploadFile({..._config, ...otherConfig, ...mergeKeys(optionalKeys, config)})
|
||||||
|
} else if (config.method === 'DOWNLOAD') {
|
||||||
|
const optionalKeys = [
|
||||||
|
// #ifdef H5 || APP-PLUS || MP-WEIXIN || MP-ALIPAY || MP-TOUTIAO || MP-KUAISHOU
|
||||||
|
'timeout',
|
||||||
|
// #endif
|
||||||
|
// #ifdef MP
|
||||||
|
'filePath',
|
||||||
|
// #endif
|
||||||
|
]
|
||||||
|
requestTask = uni.downloadFile({..._config, ...mergeKeys(optionalKeys, config)})
|
||||||
|
} else {
|
||||||
|
const optionalKeys = [
|
||||||
|
'data',
|
||||||
|
'method',
|
||||||
|
// #ifdef H5 || APP-PLUS || MP-ALIPAY || MP-WEIXIN
|
||||||
|
'timeout',
|
||||||
|
// #endif
|
||||||
|
'dataType',
|
||||||
|
// #ifndef MP-ALIPAY
|
||||||
|
'responseType',
|
||||||
|
// #endif
|
||||||
|
// #ifdef APP-PLUS
|
||||||
|
'sslVerify',
|
||||||
|
// #endif
|
||||||
|
// #ifdef H5
|
||||||
|
'withCredentials',
|
||||||
|
// #endif
|
||||||
|
// #ifdef APP-PLUS
|
||||||
|
'firstIpv4',
|
||||||
|
// #endif
|
||||||
|
// #ifdef MP-WEIXIN
|
||||||
|
'enableHttp2',
|
||||||
|
'enableQuic',
|
||||||
|
// #endif
|
||||||
|
// #ifdef MP-TOUTIAO || MP-WEIXIN
|
||||||
|
'enableCache',
|
||||||
|
// #endif
|
||||||
|
// #ifdef MP-WEIXIN
|
||||||
|
'enableHttpDNS',
|
||||||
|
'httpDNSServiceId',
|
||||||
|
'enableChunked',
|
||||||
|
'forceCellularNetwork',
|
||||||
|
// #endif
|
||||||
|
// #ifdef MP-ALIPAY
|
||||||
|
'enableCookie',
|
||||||
|
// #endif
|
||||||
|
// #ifdef MP-BAIDU
|
||||||
|
'cloudCache',
|
||||||
|
'defer'
|
||||||
|
// #endif
|
||||||
|
]
|
||||||
|
requestTask = uni.request({..._config, ...mergeKeys(optionalKeys, config)})
|
||||||
|
}
|
||||||
|
if (config.getTask) {
|
||||||
|
config.getTask(requestTask, config)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
@ -0,0 +1,51 @@
|
|||||||
|
'use strict'
|
||||||
|
|
||||||
|
|
||||||
|
function InterceptorManager() {
|
||||||
|
this.handlers = []
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a new interceptor to the stack
|
||||||
|
*
|
||||||
|
* @param {Function} fulfilled The function to handle `then` for a `Promise`
|
||||||
|
* @param {Function} rejected The function to handle `reject` for a `Promise`
|
||||||
|
*
|
||||||
|
* @return {Number} An ID used to remove interceptor later
|
||||||
|
*/
|
||||||
|
InterceptorManager.prototype.use = function use(fulfilled, rejected) {
|
||||||
|
this.handlers.push({
|
||||||
|
fulfilled: fulfilled,
|
||||||
|
rejected: rejected
|
||||||
|
})
|
||||||
|
return this.handlers.length - 1
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove an interceptor from the stack
|
||||||
|
*
|
||||||
|
* @param {Number} id The ID that was returned by `use`
|
||||||
|
*/
|
||||||
|
InterceptorManager.prototype.eject = function eject(id) {
|
||||||
|
if (this.handlers[id]) {
|
||||||
|
this.handlers[id] = null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Iterate over all the registered interceptors
|
||||||
|
*
|
||||||
|
* This method is particularly useful for skipping over any
|
||||||
|
* interceptors that may have become `null` calling `eject`.
|
||||||
|
*
|
||||||
|
* @param {Function} fn The function to call for each interceptor
|
||||||
|
*/
|
||||||
|
InterceptorManager.prototype.forEach = function forEach(fn) {
|
||||||
|
this.handlers.forEach(h => {
|
||||||
|
if (h !== null) {
|
||||||
|
fn(h)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export default InterceptorManager
|
201
src/js_sdk/luch-request/luch-request/core/Request.js
Normal file
201
src/js_sdk/luch-request/luch-request/core/Request.js
Normal file
@ -0,0 +1,201 @@
|
|||||||
|
/**
|
||||||
|
* @Class Request
|
||||||
|
* @description luch-request http请求插件
|
||||||
|
* @Author lu-ch
|
||||||
|
* @Email webwork.s@qq.com
|
||||||
|
* 文档: https://www.quanzhan.co/luch-request/
|
||||||
|
* github: https://github.com/lei-mu/luch-request
|
||||||
|
* DCloud: http://ext.dcloud.net.cn/plugin?id=392
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
import dispatchRequest from './dispatchRequest'
|
||||||
|
import InterceptorManager from './InterceptorManager'
|
||||||
|
import mergeConfig from './mergeConfig'
|
||||||
|
import defaults from './defaults'
|
||||||
|
import { isPlainObject } from '../utils'
|
||||||
|
import clone from '../utils/clone'
|
||||||
|
|
||||||
|
export default class Request {
|
||||||
|
/**
|
||||||
|
* @param {Object} arg - 全局配置
|
||||||
|
* @param {String} arg.baseURL - 全局根路径
|
||||||
|
* @param {Object} arg.header - 全局header
|
||||||
|
* @param {String} arg.method = [GET|POST|PUT|DELETE|CONNECT|HEAD|OPTIONS|TRACE] - 全局默认请求方式
|
||||||
|
* @param {String} arg.dataType = [json] - 全局默认的dataType
|
||||||
|
* @param {String} arg.responseType = [text|arraybuffer] - 全局默认的responseType。支付宝小程序不支持
|
||||||
|
* @param {Object} arg.custom - 全局默认的自定义参数
|
||||||
|
* @param {Number} arg.timeout - 全局默认的超时时间,单位 ms。默认60000。H5(HBuilderX 2.9.9+)、APP(HBuilderX 2.9.9+)、微信小程序(2.10.0)、支付宝小程序
|
||||||
|
* @param {Boolean} arg.sslVerify - 全局默认的是否验证 ssl 证书。默认true.仅App安卓端支持(HBuilderX 2.3.3+)
|
||||||
|
* @param {Boolean} arg.withCredentials - 全局默认的跨域请求时是否携带凭证(cookies)。默认false。仅H5支持(HBuilderX 2.6.15+)
|
||||||
|
* @param {Boolean} arg.firstIpv4 - 全DNS解析时优先使用ipv4。默认false。仅 App-Android 支持 (HBuilderX 2.8.0+)
|
||||||
|
* @param {Function(statusCode):Boolean} arg.validateStatus - 全局默认的自定义验证器。默认statusCode >= 200 && statusCode < 300
|
||||||
|
*/
|
||||||
|
constructor(arg = {}) {
|
||||||
|
if (!isPlainObject(arg)) {
|
||||||
|
arg = {}
|
||||||
|
console.warn('设置全局参数必须接收一个Object')
|
||||||
|
}
|
||||||
|
this.config = clone({...defaults, ...arg})
|
||||||
|
this.interceptors = {
|
||||||
|
request: new InterceptorManager(),
|
||||||
|
response: new InterceptorManager()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Function
|
||||||
|
* @param {Request~setConfigCallback} f - 设置全局默认配置
|
||||||
|
*/
|
||||||
|
setConfig(f) {
|
||||||
|
this.config = f(this.config)
|
||||||
|
}
|
||||||
|
|
||||||
|
middleware(config) {
|
||||||
|
config = mergeConfig(this.config, config)
|
||||||
|
let chain = [dispatchRequest, undefined]
|
||||||
|
let promise = Promise.resolve(config)
|
||||||
|
|
||||||
|
this.interceptors.request.forEach(function unshiftRequestInterceptors(interceptor) {
|
||||||
|
chain.unshift(interceptor.fulfilled, interceptor.rejected)
|
||||||
|
})
|
||||||
|
|
||||||
|
this.interceptors.response.forEach(function pushResponseInterceptors(interceptor) {
|
||||||
|
chain.push(interceptor.fulfilled, interceptor.rejected)
|
||||||
|
})
|
||||||
|
|
||||||
|
while (chain.length) {
|
||||||
|
promise = promise.then(chain.shift(), chain.shift())
|
||||||
|
}
|
||||||
|
|
||||||
|
return promise
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Function
|
||||||
|
* @param {Object} config - 请求配置项
|
||||||
|
* @prop {String} options.url - 请求路径
|
||||||
|
* @prop {Object} options.data - 请求参数
|
||||||
|
* @prop {Object} [options.responseType = config.responseType] [text|arraybuffer] - 响应的数据类型
|
||||||
|
* @prop {Object} [options.dataType = config.dataType] - 如果设为 json,会尝试对返回的数据做一次 JSON.parse
|
||||||
|
* @prop {Object} [options.header = config.header] - 请求header
|
||||||
|
* @prop {Object} [options.method = config.method] - 请求方法
|
||||||
|
* @returns {Promise<unknown>}
|
||||||
|
*/
|
||||||
|
request(config = {}) {
|
||||||
|
return this.middleware(config)
|
||||||
|
}
|
||||||
|
|
||||||
|
get(url, options = {}) {
|
||||||
|
return this.middleware({
|
||||||
|
url,
|
||||||
|
method: 'GET',
|
||||||
|
...options
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
post(url, data, options = {}) {
|
||||||
|
return this.middleware({
|
||||||
|
url,
|
||||||
|
data,
|
||||||
|
method: 'POST',
|
||||||
|
...options
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// #ifndef MP-ALIPAY || MP-KUAISHOU || MP-JD
|
||||||
|
put(url, data, options = {}) {
|
||||||
|
return this.middleware({
|
||||||
|
url,
|
||||||
|
data,
|
||||||
|
method: 'PUT',
|
||||||
|
...options
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// #endif
|
||||||
|
|
||||||
|
// #ifdef APP-PLUS || H5 || MP-WEIXIN || MP-BAIDU
|
||||||
|
delete(url, data, options = {}) {
|
||||||
|
return this.middleware({
|
||||||
|
url,
|
||||||
|
data,
|
||||||
|
method: 'DELETE',
|
||||||
|
...options
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// #endif
|
||||||
|
|
||||||
|
// #ifdef H5 || MP-WEIXIN
|
||||||
|
connect(url, data, options = {}) {
|
||||||
|
return this.middleware({
|
||||||
|
url,
|
||||||
|
data,
|
||||||
|
method: 'CONNECT',
|
||||||
|
...options
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// #endif
|
||||||
|
|
||||||
|
// #ifdef H5 || MP-WEIXIN || MP-BAIDU
|
||||||
|
head(url, data, options = {}) {
|
||||||
|
return this.middleware({
|
||||||
|
url,
|
||||||
|
data,
|
||||||
|
method: 'HEAD',
|
||||||
|
...options
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// #endif
|
||||||
|
|
||||||
|
// #ifdef APP-PLUS || H5 || MP-WEIXIN || MP-BAIDU
|
||||||
|
options(url, data, options = {}) {
|
||||||
|
return this.middleware({
|
||||||
|
url,
|
||||||
|
data,
|
||||||
|
method: 'OPTIONS',
|
||||||
|
...options
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// #endif
|
||||||
|
|
||||||
|
// #ifdef H5 || MP-WEIXIN
|
||||||
|
trace(url, data, options = {}) {
|
||||||
|
return this.middleware({
|
||||||
|
url,
|
||||||
|
data,
|
||||||
|
method: 'TRACE',
|
||||||
|
...options
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// #endif
|
||||||
|
|
||||||
|
upload(url, config = {}) {
|
||||||
|
config.url = url
|
||||||
|
config.method = 'UPLOAD'
|
||||||
|
return this.middleware(config)
|
||||||
|
}
|
||||||
|
|
||||||
|
download(url, config = {}) {
|
||||||
|
config.url = url
|
||||||
|
config.method = 'DOWNLOAD'
|
||||||
|
return this.middleware(config)
|
||||||
|
}
|
||||||
|
|
||||||
|
get version () {
|
||||||
|
return '3.1.0'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* setConfig回调
|
||||||
|
* @return {Object} - 返回操作后的config
|
||||||
|
* @callback Request~setConfigCallback
|
||||||
|
* @param {Object} config - 全局默认config
|
||||||
|
*/
|
20
src/js_sdk/luch-request/luch-request/core/buildFullPath.js
Normal file
20
src/js_sdk/luch-request/luch-request/core/buildFullPath.js
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
'use strict'
|
||||||
|
|
||||||
|
import isAbsoluteURL from '../helpers/isAbsoluteURL'
|
||||||
|
import combineURLs from '../helpers/combineURLs'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new URL by combining the baseURL with the requestedURL,
|
||||||
|
* only when the requestedURL is not already an absolute URL.
|
||||||
|
* If the requestURL is absolute, this function returns the requestedURL untouched.
|
||||||
|
*
|
||||||
|
* @param {string} baseURL The base URL
|
||||||
|
* @param {string} requestedURL Absolute or relative URL to combine
|
||||||
|
* @returns {string} The combined full path
|
||||||
|
*/
|
||||||
|
export default function buildFullPath(baseURL, requestedURL) {
|
||||||
|
if (baseURL && !isAbsoluteURL(requestedURL)) {
|
||||||
|
return combineURLs(baseURL, requestedURL)
|
||||||
|
}
|
||||||
|
return requestedURL
|
||||||
|
}
|
33
src/js_sdk/luch-request/luch-request/core/defaults.js
Normal file
33
src/js_sdk/luch-request/luch-request/core/defaults.js
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
/**
|
||||||
|
* 默认的全局配置
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
export default {
|
||||||
|
baseURL: '',
|
||||||
|
header: {},
|
||||||
|
method: 'GET',
|
||||||
|
dataType: 'json',
|
||||||
|
paramsSerializer: null,
|
||||||
|
// #ifndef MP-ALIPAY
|
||||||
|
responseType: 'text',
|
||||||
|
// #endif
|
||||||
|
custom: {},
|
||||||
|
// #ifdef H5 || APP-PLUS || MP-WEIXIN || MP-ALIPAY || MP-TOUTIAO || MP-KUAISHOU
|
||||||
|
timeout: 60000,
|
||||||
|
// #endif
|
||||||
|
// #ifdef APP-PLUS
|
||||||
|
sslVerify: true,
|
||||||
|
// #endif
|
||||||
|
// #ifdef H5
|
||||||
|
withCredentials: false,
|
||||||
|
// #endif
|
||||||
|
// #ifdef APP-PLUS
|
||||||
|
firstIpv4: false,
|
||||||
|
// #endif
|
||||||
|
validateStatus: function validateStatus(status) {
|
||||||
|
return status >= 200 && status < 300
|
||||||
|
},
|
||||||
|
// 是否尝试将响应数据json化
|
||||||
|
forcedJSONParsing: true
|
||||||
|
}
|
@ -0,0 +1,6 @@
|
|||||||
|
import adapter from '../adapters/index'
|
||||||
|
|
||||||
|
|
||||||
|
export default (config) => {
|
||||||
|
return adapter(config)
|
||||||
|
}
|
126
src/js_sdk/luch-request/luch-request/core/mergeConfig.js
Normal file
126
src/js_sdk/luch-request/luch-request/core/mergeConfig.js
Normal file
@ -0,0 +1,126 @@
|
|||||||
|
import {deepMerge, isUndefined} from '../utils'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 合并局部配置优先的配置,如果局部有该配置项则用局部,如果全局有该配置项则用全局
|
||||||
|
* @param {Array} keys - 配置项
|
||||||
|
* @param {Object} globalsConfig - 当前的全局配置
|
||||||
|
* @param {Object} config2 - 局部配置
|
||||||
|
* @return {{}}
|
||||||
|
*/
|
||||||
|
const mergeKeys = (keys, globalsConfig, config2) => {
|
||||||
|
let config = {}
|
||||||
|
keys.forEach(prop => {
|
||||||
|
if (!isUndefined(config2[prop])) {
|
||||||
|
config[prop] = config2[prop]
|
||||||
|
} else if (!isUndefined(globalsConfig[prop])) {
|
||||||
|
config[prop] = globalsConfig[prop]
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return config
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param globalsConfig - 当前实例的全局配置
|
||||||
|
* @param config2 - 当前的局部配置
|
||||||
|
* @return - 合并后的配置
|
||||||
|
*/
|
||||||
|
export default (globalsConfig, config2 = {}) => {
|
||||||
|
const method = config2.method || globalsConfig.method || 'GET'
|
||||||
|
let config = {
|
||||||
|
baseURL: config2.baseURL || globalsConfig.baseURL || '',
|
||||||
|
method: method,
|
||||||
|
url: config2.url || '',
|
||||||
|
params: config2.params || {},
|
||||||
|
custom: {...(globalsConfig.custom || {}), ...(config2.custom || {})},
|
||||||
|
header: deepMerge(globalsConfig.header || {}, config2.header || {})
|
||||||
|
}
|
||||||
|
const defaultToConfig2Keys = ['getTask', 'validateStatus', 'paramsSerializer', 'forcedJSONParsing']
|
||||||
|
config = {...config, ...mergeKeys(defaultToConfig2Keys, globalsConfig, config2)}
|
||||||
|
|
||||||
|
// eslint-disable-next-line no-empty
|
||||||
|
if (method === 'DOWNLOAD') {
|
||||||
|
const downloadKeys = [
|
||||||
|
// #ifdef H5 || APP-PLUS || MP-WEIXIN || MP-ALIPAY || MP-TOUTIAO || MP-KUAISHOU
|
||||||
|
'timeout',
|
||||||
|
// #endif
|
||||||
|
// #ifdef MP
|
||||||
|
'filePath',
|
||||||
|
// #endif
|
||||||
|
]
|
||||||
|
config = {...config, ...mergeKeys(downloadKeys, globalsConfig, config2)}
|
||||||
|
} else if (method === 'UPLOAD') {
|
||||||
|
delete config.header['content-type']
|
||||||
|
delete config.header['Content-Type']
|
||||||
|
const uploadKeys = [
|
||||||
|
// #ifdef APP-PLUS || H5
|
||||||
|
'files',
|
||||||
|
// #endif
|
||||||
|
// #ifdef MP-ALIPAY
|
||||||
|
'fileType',
|
||||||
|
// #endif
|
||||||
|
// #ifdef H5
|
||||||
|
'file',
|
||||||
|
// #endif
|
||||||
|
'filePath',
|
||||||
|
'name',
|
||||||
|
// #ifdef H5 || APP-PLUS || MP-WEIXIN || MP-ALIPAY || MP-TOUTIAO || MP-KUAISHOU
|
||||||
|
'timeout',
|
||||||
|
// #endif
|
||||||
|
'formData',
|
||||||
|
]
|
||||||
|
uploadKeys.forEach(prop => {
|
||||||
|
if (!isUndefined(config2[prop])) {
|
||||||
|
config[prop] = config2[prop]
|
||||||
|
}
|
||||||
|
})
|
||||||
|
// #ifdef H5 || APP-PLUS || MP-WEIXIN || MP-ALIPAY || MP-TOUTIAO || MP-KUAISHOU
|
||||||
|
if (isUndefined(config.timeout) && !isUndefined(globalsConfig.timeout)) {
|
||||||
|
config['timeout'] = globalsConfig['timeout']
|
||||||
|
}
|
||||||
|
// #endif
|
||||||
|
} else {
|
||||||
|
const defaultsKeys = [
|
||||||
|
'data',
|
||||||
|
// #ifdef H5 || APP-PLUS || MP-ALIPAY || MP-WEIXIN
|
||||||
|
'timeout',
|
||||||
|
// #endif
|
||||||
|
'dataType',
|
||||||
|
// #ifndef MP-ALIPAY
|
||||||
|
'responseType',
|
||||||
|
// #endif
|
||||||
|
// #ifdef APP-PLUS
|
||||||
|
'sslVerify',
|
||||||
|
// #endif
|
||||||
|
// #ifdef H5
|
||||||
|
'withCredentials',
|
||||||
|
// #endif
|
||||||
|
// #ifdef APP-PLUS
|
||||||
|
'firstIpv4',
|
||||||
|
// #endif
|
||||||
|
// #ifdef MP-WEIXIN
|
||||||
|
'enableHttp2',
|
||||||
|
'enableQuic',
|
||||||
|
// #endif
|
||||||
|
// #ifdef MP-TOUTIAO || MP-WEIXIN
|
||||||
|
'enableCache',
|
||||||
|
// #endif
|
||||||
|
// #ifdef MP-WEIXIN
|
||||||
|
'enableHttpDNS',
|
||||||
|
'httpDNSServiceId',
|
||||||
|
'enableChunked',
|
||||||
|
'forceCellularNetwork',
|
||||||
|
// #endif
|
||||||
|
// #ifdef MP-ALIPAY
|
||||||
|
'enableCookie',
|
||||||
|
// #endif
|
||||||
|
// #ifdef MP-BAIDU
|
||||||
|
'cloudCache',
|
||||||
|
'defer'
|
||||||
|
// #endif
|
||||||
|
|
||||||
|
]
|
||||||
|
config = {...config, ...mergeKeys(defaultsKeys, globalsConfig, config2)}
|
||||||
|
}
|
||||||
|
|
||||||
|
return config
|
||||||
|
}
|
16
src/js_sdk/luch-request/luch-request/core/settle.js
Normal file
16
src/js_sdk/luch-request/luch-request/core/settle.js
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
/**
|
||||||
|
* Resolve or reject a Promise based on response status.
|
||||||
|
*
|
||||||
|
* @param {Function} resolve A function that resolves the promise.
|
||||||
|
* @param {Function} reject A function that rejects the promise.
|
||||||
|
* @param {object} response The response.
|
||||||
|
*/
|
||||||
|
export default function settle(resolve, reject, response) {
|
||||||
|
const validateStatus = response.config.validateStatus
|
||||||
|
const status = response.statusCode
|
||||||
|
if (status && (!validateStatus || validateStatus(status))) {
|
||||||
|
resolve(response)
|
||||||
|
} else {
|
||||||
|
reject(response)
|
||||||
|
}
|
||||||
|
}
|
64
src/js_sdk/luch-request/luch-request/helpers/buildURL.js
Normal file
64
src/js_sdk/luch-request/luch-request/helpers/buildURL.js
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
'use strict'
|
||||||
|
|
||||||
|
import * as utils from './../utils'
|
||||||
|
|
||||||
|
function encode(val) {
|
||||||
|
return encodeURIComponent(val).replace(/%40/gi, '@').replace(/%3A/gi, ':').replace(/%24/g, '$').replace(/%2C/gi, ',').replace(/%20/g, '+').replace(/%5B/gi, '[').replace(/%5D/gi, ']')
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Build a URL by appending params to the end
|
||||||
|
*
|
||||||
|
* @param {string} url The base of the url (e.g., http://www.google.com)
|
||||||
|
* @param {object} [params] The params to be appended
|
||||||
|
* @returns {string} The formatted url
|
||||||
|
*/
|
||||||
|
export default function buildURL(url, params, paramsSerializer) {
|
||||||
|
/*eslint no-param-reassign:0*/
|
||||||
|
if (!params) {
|
||||||
|
return url
|
||||||
|
}
|
||||||
|
|
||||||
|
var serializedParams
|
||||||
|
if (paramsSerializer) {
|
||||||
|
serializedParams = paramsSerializer(params)
|
||||||
|
} else if (utils.isURLSearchParams(params)) {
|
||||||
|
serializedParams = params.toString()
|
||||||
|
} else {
|
||||||
|
var parts = []
|
||||||
|
|
||||||
|
utils.forEach(params, function serialize(val, key) {
|
||||||
|
if (val === null || typeof val === 'undefined') {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (utils.isArray(val)) {
|
||||||
|
key = key + '[]'
|
||||||
|
} else {
|
||||||
|
val = [val]
|
||||||
|
}
|
||||||
|
|
||||||
|
utils.forEach(val, function parseValue(v) {
|
||||||
|
if (utils.isDate(v)) {
|
||||||
|
v = v.toISOString()
|
||||||
|
} else if (utils.isObject(v)) {
|
||||||
|
v = JSON.stringify(v)
|
||||||
|
}
|
||||||
|
parts.push(encode(key) + '=' + encode(v))
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
serializedParams = parts.join('&')
|
||||||
|
}
|
||||||
|
|
||||||
|
if (serializedParams) {
|
||||||
|
var hashmarkIndex = url.indexOf('#')
|
||||||
|
if (hashmarkIndex !== -1) {
|
||||||
|
url = url.slice(0, hashmarkIndex)
|
||||||
|
}
|
||||||
|
|
||||||
|
url += (url.indexOf('?') === -1 ? '?' : '&') + serializedParams
|
||||||
|
}
|
||||||
|
|
||||||
|
return url
|
||||||
|
}
|
14
src/js_sdk/luch-request/luch-request/helpers/combineURLs.js
Normal file
14
src/js_sdk/luch-request/luch-request/helpers/combineURLs.js
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
'use strict'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new URL by combining the specified URLs
|
||||||
|
*
|
||||||
|
* @param {string} baseURL The base URL
|
||||||
|
* @param {string} relativeURL The relative URL
|
||||||
|
* @returns {string} The combined URL
|
||||||
|
*/
|
||||||
|
export default function combineURLs(baseURL, relativeURL) {
|
||||||
|
return relativeURL
|
||||||
|
? baseURL.replace(/\/+$/, '') + '/' + relativeURL.replace(/^\/+/, '')
|
||||||
|
: baseURL
|
||||||
|
}
|
@ -0,0 +1,14 @@
|
|||||||
|
'use strict'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines whether the specified URL is absolute
|
||||||
|
*
|
||||||
|
* @param {string} url The URL to test
|
||||||
|
* @returns {boolean} True if the specified URL is absolute, otherwise false
|
||||||
|
*/
|
||||||
|
export default function isAbsoluteURL(url) {
|
||||||
|
// A URL is considered absolute if it begins with "<scheme>://" or "//" (protocol-relative URL).
|
||||||
|
// RFC 3986 defines scheme name as a sequence of characters beginning with a letter and followed
|
||||||
|
// by any combination of letters, digits, plus, period, or hyphen.
|
||||||
|
return /^([a-z][a-z\d+\-.]*:)?\/\//i.test(url)
|
||||||
|
}
|
197
src/js_sdk/luch-request/luch-request/index.d.ts
vendored
Normal file
197
src/js_sdk/luch-request/luch-request/index.d.ts
vendored
Normal file
@ -0,0 +1,197 @@
|
|||||||
|
export type HttpTask = UniApp.RequestTask | UniApp.UploadTask | UniApp.DownloadTask;
|
||||||
|
|
||||||
|
export type HttpRequestTask = UniApp.RequestTask;
|
||||||
|
|
||||||
|
export type HttpUploadTask = UniApp.UploadTask;
|
||||||
|
|
||||||
|
export type HttpDownloadTask = UniApp.DownloadTask;
|
||||||
|
|
||||||
|
export type HttpMethod =
|
||||||
|
"GET"
|
||||||
|
| "POST"
|
||||||
|
| "PUT"
|
||||||
|
| "DELETE"
|
||||||
|
| "CONNECT"
|
||||||
|
| "HEAD"
|
||||||
|
| "OPTIONS"
|
||||||
|
| "TRACE"
|
||||||
|
| "UPLOAD"
|
||||||
|
| "DOWNLOAD";
|
||||||
|
|
||||||
|
export type HttpRequestHeader = Record<string, string>;
|
||||||
|
|
||||||
|
export type HttpParams = Record<string, any>;
|
||||||
|
|
||||||
|
export type HttpData = Record<string, any>;
|
||||||
|
|
||||||
|
export type HttpResponseType = 'arraybuffer' | 'text';
|
||||||
|
|
||||||
|
export type HttpCustom = Record<string, any>;
|
||||||
|
|
||||||
|
export type HttpFileType = 'image' | 'video' | 'audio';
|
||||||
|
|
||||||
|
export type HttpFormData = Record<string, any>;
|
||||||
|
|
||||||
|
export type HttpResponseHeader = Record<string, string> & {
|
||||||
|
"set-cookie"?: string[]
|
||||||
|
};
|
||||||
|
|
||||||
|
export interface HttpRequestConfig<T = HttpTask> {
|
||||||
|
/** @desc 请求服务器接口地址 */
|
||||||
|
url?: string;
|
||||||
|
/** @desc 请求方式,默认为 GET */
|
||||||
|
method?: HttpMethod;
|
||||||
|
/** @desc 请求基地址 */
|
||||||
|
baseURL?: string;
|
||||||
|
/** @desc 请求头信息,不能设置 Referer,App、H5 端会自动带上 cookie,且 H5 端不可手动修改 */
|
||||||
|
header?: HttpRequestHeader;
|
||||||
|
/** @desc 请求查询参数,自动拼接为查询字符串 */
|
||||||
|
params?: HttpParams;
|
||||||
|
/** @desc 请求体参数 */
|
||||||
|
data?: HttpData;
|
||||||
|
/** @desc 超时时间,单位 ms,默认为 60000,仅 H5 (HBuilderX 2.9.9+)、APP (HBuilderX 2.9.9+)、微信小程序 (2.10.0)、支付宝小程序支持 */
|
||||||
|
timeout?: number;
|
||||||
|
/** @desc 跨域请求时是否携带凭证 (cookies),默认为 false,仅 H5 (HBuilderX 2.6.15+) 支持 */
|
||||||
|
withCredentials?: boolean;
|
||||||
|
/** @desc 设置响应的数据类型,支付宝小程序不支持 */
|
||||||
|
responseType?: HttpResponseType;
|
||||||
|
/** @desc 全局自定义验证器 */
|
||||||
|
validateStatus?: ((statusCode: number) => boolean) | null;
|
||||||
|
|
||||||
|
|
||||||
|
/** params 参数自定义处理 */
|
||||||
|
paramsSerializer?: (params: AnyObject) => string | void;
|
||||||
|
|
||||||
|
/** @desc 默认为 json,如果设为 json,会尝试对返回的数据做一次 JSON.parse */
|
||||||
|
dataType?: string;
|
||||||
|
/** @desc DNS 解析时是否优先使用 ipv4,默认为 false,仅 App-Android (HBuilderX 2.8.0+) 支持 */
|
||||||
|
firstIpv4?: boolean;
|
||||||
|
/** @desc 是否验证 SSL 证书,默认为 true,仅 App-Android (HBuilderX 2.3.3+) 支持 */
|
||||||
|
sslVerify?: boolean;
|
||||||
|
|
||||||
|
/** @desc 开启 http2;微信小程序 */
|
||||||
|
enableHttp2?: boolean;
|
||||||
|
|
||||||
|
/** @desc 开启 quic;微信小程序 */
|
||||||
|
enableQuic?: boolean;
|
||||||
|
/** @desc 开启 cache;微信小程序、字节跳动小程序 2.31.0+ */
|
||||||
|
enableCache?: boolean;
|
||||||
|
/** @desc 开启 httpDNS;微信小程序 */
|
||||||
|
enableHttpDNS?: boolean;
|
||||||
|
/** @desc httpDNS 服务商;微信小程序 */
|
||||||
|
httpDNSServiceId?: string;
|
||||||
|
/** @desc 开启 transfer-encoding chunked;微信小程序 */
|
||||||
|
enableChunked?: boolean;
|
||||||
|
/** @desc wifi下使用移动网络发送请求;微信小程序 */
|
||||||
|
forceCellularNetwork?: boolean;
|
||||||
|
/** @desc 开启后可在headers中编辑cookie;支付宝小程序 10.2.33+ */
|
||||||
|
enableCookie?: boolean;
|
||||||
|
/** @desc 是否开启云加速;百度小程序 3.310.11+ */
|
||||||
|
cloudCache?: boolean | object;
|
||||||
|
/** @desc 控制当前请求是否延时至首屏内容渲染后发送;百度小程序 3.310.11+ */
|
||||||
|
defer?: boolean;
|
||||||
|
|
||||||
|
/** @desc 自定义参数 */
|
||||||
|
custom?: HttpCustom;
|
||||||
|
|
||||||
|
/** @desc 返回当前请求的 task 和 options,不要在这里修改 options */
|
||||||
|
getTask?: (task: T, options: HttpRequestConfig<T>) => void;
|
||||||
|
|
||||||
|
/** @desc 需要上传的文件列表,使用 files 时,filePath 和 name 不生效,仅支持 App、H5 (2.6.15+) */
|
||||||
|
files?: { name?: string; file?: File; uri: string; }[];
|
||||||
|
/** @desc 文件类型,仅支付宝小程序支持且为必填项 */
|
||||||
|
fileType?: HttpFileType;
|
||||||
|
/** @desc 要上传的文件对象,仅 H5 (2.6.15+) 支持 */
|
||||||
|
file?: File;
|
||||||
|
/** @desc 要上传文件资源的路径,使用 files 时,filePath 和 name 不生效 */
|
||||||
|
filePath?: string;
|
||||||
|
/** @desc 文件对应的 key,开发者在服务器端通过这个 key 可以获取到文件二进制内容,使用 files 时,filePath 和 name 不生效 */
|
||||||
|
name?: string;
|
||||||
|
/** @desc 请求中其他额外的 form data */
|
||||||
|
formData?: HttpFormData;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface HttpResponse<T = any, D = HttpTask> {
|
||||||
|
data: T;
|
||||||
|
statusCode: number;
|
||||||
|
header: HttpResponseHeader;
|
||||||
|
config: HttpRequestConfig<D>;
|
||||||
|
cookies: string[];
|
||||||
|
errMsg: string;
|
||||||
|
rawData: any;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface HttpUploadResponse<T = any, D = HttpTask> {
|
||||||
|
data: T;
|
||||||
|
statusCode: number;
|
||||||
|
config: HttpRequestConfig<D>;
|
||||||
|
errMsg: string;
|
||||||
|
rawData: any;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface HttpDownloadResponse extends HttpResponse {
|
||||||
|
tempFilePath: string;
|
||||||
|
apFilePath?: string;
|
||||||
|
filePath?: string;
|
||||||
|
fileContent?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface HttpError<T = any, D = HttpTask> {
|
||||||
|
data?: T;
|
||||||
|
statusCode?: number;
|
||||||
|
header?: HttpResponseHeader;
|
||||||
|
config: HttpRequestConfig<D>;
|
||||||
|
cookies?: string[];
|
||||||
|
errMsg: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface HttpPromise<T = any> extends Promise<HttpResponse<T>> {
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface HttpInterceptorManager<V, E = V> {
|
||||||
|
use(onFulfilled?: (value: V) => V | Promise<V>, onRejected?: (error: E) => T | Promise<E>): void;
|
||||||
|
|
||||||
|
eject(id: number): void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export abstract class HttpRequestAbstract {
|
||||||
|
constructor(config?: HttpRequestConfig);
|
||||||
|
|
||||||
|
interceptors: {
|
||||||
|
request: HttpInterceptorManager<HttpRequestConfig>;
|
||||||
|
response: HttpInterceptorManager<HttpResponse, HttpError>;
|
||||||
|
}
|
||||||
|
|
||||||
|
request<T = any, R = HttpResponse<T>, D = HttpRequestTask>(config: HttpRequestConfig<D>): Promise<R>;
|
||||||
|
|
||||||
|
get<T = any, R = HttpResponse<T>, D = HttpRequestTask>(url: string, config?: HttpRequestConfig<D>): Promise<R>;
|
||||||
|
|
||||||
|
delete<T = any, R = HttpResponse<T>, D = HttpRequestTask>(url: string, data?: HttpData, config?: HttpRequestConfig<D>): Promise<R>;
|
||||||
|
|
||||||
|
head<T = any, R = HttpResponse<T>, D = HttpRequestTask>(url: string, data?: HttpData, config?: HttpRequestConfig<D>): Promise<R>;
|
||||||
|
|
||||||
|
options<T = any, R = HttpResponse<T>, D = HttpRequestTask>(url: string, data?: HttpData, config?: HttpRequestConfig<D>): Promise<R>;
|
||||||
|
|
||||||
|
post<T = any, R = HttpResponse<T>, D = HttpRequestTask>(url: string, data?: HttpData, config?: HttpRequestConfig<D>): Promise<R>;
|
||||||
|
|
||||||
|
put<T = any, R = HttpResponse<T>, D = HttpRequestTask>(url: string, data?: HttpData, config?: HttpRequestConfig<D>): Promise<R>;
|
||||||
|
|
||||||
|
config: HttpRequestConfig;
|
||||||
|
|
||||||
|
setConfig<D = HttpTask>(onSend: (config: HttpRequestConfig<D>) => HttpRequestConfig<D>): void;
|
||||||
|
|
||||||
|
connect<T = any, R = HttpResponse<T>, D = HttpRequestTask>(url: string, data?: HttpData, config?: HttpRequestConfig<D>): Promise<R>;
|
||||||
|
|
||||||
|
trace<T = any, R = HttpResponse<T>, D = HttpRequestTask>(url: string, data?: HttpData, config?: HttpRequestConfig<D>): Promise<R>;
|
||||||
|
|
||||||
|
upload<T = any, R = HttpUploadResponse<T>, D = HttpUploadTask>(url: string, config?: HttpRequestConfig<D>): Promise<R>;
|
||||||
|
|
||||||
|
download<T = any, R = HttpDownloadResponse<T>, D = HttpDownloadTask>(url: string, config?: HttpRequestConfig<D>): Promise<R>;
|
||||||
|
|
||||||
|
middleware<T = any, R = HttpResponse<T>, D = HttpTask>(config: HttpRequestConfig<D>): Promise<R>;
|
||||||
|
}
|
||||||
|
|
||||||
|
declare class HttpRequest extends HttpRequestAbstract {
|
||||||
|
}
|
||||||
|
|
||||||
|
export default HttpRequest;
|
2
src/js_sdk/luch-request/luch-request/index.js
Normal file
2
src/js_sdk/luch-request/luch-request/index.js
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
import Request from './core/Request'
|
||||||
|
export default Request
|
135
src/js_sdk/luch-request/luch-request/utils.js
Normal file
135
src/js_sdk/luch-request/luch-request/utils.js
Normal file
@ -0,0 +1,135 @@
|
|||||||
|
'use strict'
|
||||||
|
|
||||||
|
// utils is a library of generic helper functions non-specific to axios
|
||||||
|
|
||||||
|
var toString = Object.prototype.toString
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine if a value is an Array
|
||||||
|
*
|
||||||
|
* @param {Object} val The value to test
|
||||||
|
* @returns {boolean} True if value is an Array, otherwise false
|
||||||
|
*/
|
||||||
|
export function isArray (val) {
|
||||||
|
return toString.call(val) === '[object Array]'
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine if a value is an Object
|
||||||
|
*
|
||||||
|
* @param {Object} val The value to test
|
||||||
|
* @returns {boolean} True if value is an Object, otherwise false
|
||||||
|
*/
|
||||||
|
export function isObject (val) {
|
||||||
|
return val !== null && typeof val === 'object'
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine if a value is a Date
|
||||||
|
*
|
||||||
|
* @param {Object} val The value to test
|
||||||
|
* @returns {boolean} True if value is a Date, otherwise false
|
||||||
|
*/
|
||||||
|
export function isDate (val) {
|
||||||
|
return toString.call(val) === '[object Date]'
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine if a value is a URLSearchParams object
|
||||||
|
*
|
||||||
|
* @param {Object} val The value to test
|
||||||
|
* @returns {boolean} True if value is a URLSearchParams object, otherwise false
|
||||||
|
*/
|
||||||
|
export function isURLSearchParams (val) {
|
||||||
|
return typeof URLSearchParams !== 'undefined' && val instanceof URLSearchParams
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Iterate over an Array or an Object invoking a function for each item.
|
||||||
|
*
|
||||||
|
* If `obj` is an Array callback will be called passing
|
||||||
|
* the value, index, and complete array for each item.
|
||||||
|
*
|
||||||
|
* If 'obj' is an Object callback will be called passing
|
||||||
|
* the value, key, and complete object for each property.
|
||||||
|
*
|
||||||
|
* @param {Object|Array} obj The object to iterate
|
||||||
|
* @param {Function} fn The callback to invoke for each item
|
||||||
|
*/
|
||||||
|
export function forEach (obj, fn) {
|
||||||
|
// Don't bother if no value provided
|
||||||
|
if (obj === null || typeof obj === 'undefined') {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Force an array if not already something iterable
|
||||||
|
if (typeof obj !== 'object') {
|
||||||
|
/*eslint no-param-reassign:0*/
|
||||||
|
obj = [obj]
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isArray(obj)) {
|
||||||
|
// Iterate over array values
|
||||||
|
for (var i = 0, l = obj.length; i < l; i++) {
|
||||||
|
fn.call(null, obj[i], i, obj)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Iterate over object keys
|
||||||
|
for (var key in obj) {
|
||||||
|
if (Object.prototype.hasOwnProperty.call(obj, key)) {
|
||||||
|
fn.call(null, obj[key], key, obj)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否为boolean 值
|
||||||
|
* @param val
|
||||||
|
* @returns {boolean}
|
||||||
|
*/
|
||||||
|
export function isBoolean(val) {
|
||||||
|
return typeof val === 'boolean'
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否为真正的对象{} new Object
|
||||||
|
* @param {any} obj - 检测的对象
|
||||||
|
* @returns {boolean}
|
||||||
|
*/
|
||||||
|
export function isPlainObject(obj) {
|
||||||
|
return Object.prototype.toString.call(obj) === '[object Object]'
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function equal to merge with the difference being that no reference
|
||||||
|
* to original objects is kept.
|
||||||
|
*
|
||||||
|
* @see merge
|
||||||
|
* @param {Object} obj1 Object to merge
|
||||||
|
* @returns {Object} Result of all merge properties
|
||||||
|
*/
|
||||||
|
export function deepMerge(/* obj1, obj2, obj3, ... */) {
|
||||||
|
let result = {}
|
||||||
|
function assignValue(val, key) {
|
||||||
|
if (typeof result[key] === 'object' && typeof val === 'object') {
|
||||||
|
result[key] = deepMerge(result[key], val)
|
||||||
|
} else if (typeof val === 'object') {
|
||||||
|
result[key] = deepMerge({}, val)
|
||||||
|
} else {
|
||||||
|
result[key] = val
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (let i = 0, l = arguments.length; i < l; i++) {
|
||||||
|
forEach(arguments[i], assignValue)
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
export function isUndefined (val) {
|
||||||
|
return typeof val === 'undefined'
|
||||||
|
}
|
264
src/js_sdk/luch-request/luch-request/utils/clone.js
Normal file
264
src/js_sdk/luch-request/luch-request/utils/clone.js
Normal file
@ -0,0 +1,264 @@
|
|||||||
|
/* eslint-disable */
|
||||||
|
var clone = (function() {
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
function _instanceof(obj, type) {
|
||||||
|
return type != null && obj instanceof type;
|
||||||
|
}
|
||||||
|
|
||||||
|
var nativeMap;
|
||||||
|
try {
|
||||||
|
nativeMap = Map;
|
||||||
|
} catch(_) {
|
||||||
|
// maybe a reference error because no `Map`. Give it a dummy value that no
|
||||||
|
// value will ever be an instanceof.
|
||||||
|
nativeMap = function() {};
|
||||||
|
}
|
||||||
|
|
||||||
|
var nativeSet;
|
||||||
|
try {
|
||||||
|
nativeSet = Set;
|
||||||
|
} catch(_) {
|
||||||
|
nativeSet = function() {};
|
||||||
|
}
|
||||||
|
|
||||||
|
var nativePromise;
|
||||||
|
try {
|
||||||
|
nativePromise = Promise;
|
||||||
|
} catch(_) {
|
||||||
|
nativePromise = function() {};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clones (copies) an Object using deep copying.
|
||||||
|
*
|
||||||
|
* This function supports circular references by default, but if you are certain
|
||||||
|
* there are no circular references in your object, you can save some CPU time
|
||||||
|
* by calling clone(obj, false).
|
||||||
|
*
|
||||||
|
* Caution: if `circular` is false and `parent` contains circular references,
|
||||||
|
* your program may enter an infinite loop and crash.
|
||||||
|
*
|
||||||
|
* @param `parent` - the object to be cloned
|
||||||
|
* @param `circular` - set to true if the object to be cloned may contain
|
||||||
|
* circular references. (optional - true by default)
|
||||||
|
* @param `depth` - set to a number if the object is only to be cloned to
|
||||||
|
* a particular depth. (optional - defaults to Infinity)
|
||||||
|
* @param `prototype` - sets the prototype to be used when cloning an object.
|
||||||
|
* (optional - defaults to parent prototype).
|
||||||
|
* @param `includeNonEnumerable` - set to true if the non-enumerable properties
|
||||||
|
* should be cloned as well. Non-enumerable properties on the prototype
|
||||||
|
* chain will be ignored. (optional - false by default)
|
||||||
|
*/
|
||||||
|
function clone(parent, circular, depth, prototype, includeNonEnumerable) {
|
||||||
|
if (typeof circular === 'object') {
|
||||||
|
depth = circular.depth;
|
||||||
|
prototype = circular.prototype;
|
||||||
|
includeNonEnumerable = circular.includeNonEnumerable;
|
||||||
|
circular = circular.circular;
|
||||||
|
}
|
||||||
|
// maintain two arrays for circular references, where corresponding parents
|
||||||
|
// and children have the same index
|
||||||
|
var allParents = [];
|
||||||
|
var allChildren = [];
|
||||||
|
|
||||||
|
var useBuffer = typeof Buffer != 'undefined';
|
||||||
|
|
||||||
|
if (typeof circular == 'undefined')
|
||||||
|
circular = true;
|
||||||
|
|
||||||
|
if (typeof depth == 'undefined')
|
||||||
|
depth = Infinity;
|
||||||
|
|
||||||
|
// recurse this function so we don't reset allParents and allChildren
|
||||||
|
function _clone(parent, depth) {
|
||||||
|
// cloning null always returns null
|
||||||
|
if (parent === null)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
if (depth === 0)
|
||||||
|
return parent;
|
||||||
|
|
||||||
|
var child;
|
||||||
|
var proto;
|
||||||
|
if (typeof parent != 'object') {
|
||||||
|
return parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_instanceof(parent, nativeMap)) {
|
||||||
|
child = new nativeMap();
|
||||||
|
} else if (_instanceof(parent, nativeSet)) {
|
||||||
|
child = new nativeSet();
|
||||||
|
} else if (_instanceof(parent, nativePromise)) {
|
||||||
|
child = new nativePromise(function (resolve, reject) {
|
||||||
|
parent.then(function(value) {
|
||||||
|
resolve(_clone(value, depth - 1));
|
||||||
|
}, function(err) {
|
||||||
|
reject(_clone(err, depth - 1));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
} else if (clone.__isArray(parent)) {
|
||||||
|
child = [];
|
||||||
|
} else if (clone.__isRegExp(parent)) {
|
||||||
|
child = new RegExp(parent.source, __getRegExpFlags(parent));
|
||||||
|
if (parent.lastIndex) child.lastIndex = parent.lastIndex;
|
||||||
|
} else if (clone.__isDate(parent)) {
|
||||||
|
child = new Date(parent.getTime());
|
||||||
|
} else if (useBuffer && Buffer.isBuffer(parent)) {
|
||||||
|
if (Buffer.from) {
|
||||||
|
// Node.js >= 5.10.0
|
||||||
|
child = Buffer.from(parent);
|
||||||
|
} else {
|
||||||
|
// Older Node.js versions
|
||||||
|
child = new Buffer(parent.length);
|
||||||
|
parent.copy(child);
|
||||||
|
}
|
||||||
|
return child;
|
||||||
|
} else if (_instanceof(parent, Error)) {
|
||||||
|
child = Object.create(parent);
|
||||||
|
} else {
|
||||||
|
if (typeof prototype == 'undefined') {
|
||||||
|
proto = Object.getPrototypeOf(parent);
|
||||||
|
child = Object.create(proto);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
child = Object.create(prototype);
|
||||||
|
proto = prototype;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (circular) {
|
||||||
|
var index = allParents.indexOf(parent);
|
||||||
|
|
||||||
|
if (index != -1) {
|
||||||
|
return allChildren[index];
|
||||||
|
}
|
||||||
|
allParents.push(parent);
|
||||||
|
allChildren.push(child);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_instanceof(parent, nativeMap)) {
|
||||||
|
parent.forEach(function(value, key) {
|
||||||
|
var keyChild = _clone(key, depth - 1);
|
||||||
|
var valueChild = _clone(value, depth - 1);
|
||||||
|
child.set(keyChild, valueChild);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (_instanceof(parent, nativeSet)) {
|
||||||
|
parent.forEach(function(value) {
|
||||||
|
var entryChild = _clone(value, depth - 1);
|
||||||
|
child.add(entryChild);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var i in parent) {
|
||||||
|
var attrs = Object.getOwnPropertyDescriptor(parent, i);
|
||||||
|
if (attrs) {
|
||||||
|
child[i] = _clone(parent[i], depth - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
var objProperty = Object.getOwnPropertyDescriptor(parent, i);
|
||||||
|
if (objProperty.set === 'undefined') {
|
||||||
|
// no setter defined. Skip cloning this property
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
child[i] = _clone(parent[i], depth - 1);
|
||||||
|
} catch(e){
|
||||||
|
if (e instanceof TypeError) {
|
||||||
|
// when in strict mode, TypeError will be thrown if child[i] property only has a getter
|
||||||
|
// we can't do anything about this, other than inform the user that this property cannot be set.
|
||||||
|
continue
|
||||||
|
} else if (e instanceof ReferenceError) {
|
||||||
|
//this may happen in non strict mode
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Object.getOwnPropertySymbols) {
|
||||||
|
var symbols = Object.getOwnPropertySymbols(parent);
|
||||||
|
for (var i = 0; i < symbols.length; i++) {
|
||||||
|
// Don't need to worry about cloning a symbol because it is a primitive,
|
||||||
|
// like a number or string.
|
||||||
|
var symbol = symbols[i];
|
||||||
|
var descriptor = Object.getOwnPropertyDescriptor(parent, symbol);
|
||||||
|
if (descriptor && !descriptor.enumerable && !includeNonEnumerable) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
child[symbol] = _clone(parent[symbol], depth - 1);
|
||||||
|
Object.defineProperty(child, symbol, descriptor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (includeNonEnumerable) {
|
||||||
|
var allPropertyNames = Object.getOwnPropertyNames(parent);
|
||||||
|
for (var i = 0; i < allPropertyNames.length; i++) {
|
||||||
|
var propertyName = allPropertyNames[i];
|
||||||
|
var descriptor = Object.getOwnPropertyDescriptor(parent, propertyName);
|
||||||
|
if (descriptor && descriptor.enumerable) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
child[propertyName] = _clone(parent[propertyName], depth - 1);
|
||||||
|
Object.defineProperty(child, propertyName, descriptor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return child;
|
||||||
|
}
|
||||||
|
|
||||||
|
return _clone(parent, depth);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Simple flat clone using prototype, accepts only objects, usefull for property
|
||||||
|
* override on FLAT configuration object (no nested props).
|
||||||
|
*
|
||||||
|
* USE WITH CAUTION! This may not behave as you wish if you do not know how this
|
||||||
|
* works.
|
||||||
|
*/
|
||||||
|
clone.clonePrototype = function clonePrototype(parent) {
|
||||||
|
if (parent === null)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
var c = function () {};
|
||||||
|
c.prototype = parent;
|
||||||
|
return new c();
|
||||||
|
};
|
||||||
|
|
||||||
|
// private utility functions
|
||||||
|
|
||||||
|
function __objToStr(o) {
|
||||||
|
return Object.prototype.toString.call(o);
|
||||||
|
}
|
||||||
|
clone.__objToStr = __objToStr;
|
||||||
|
|
||||||
|
function __isDate(o) {
|
||||||
|
return typeof o === 'object' && __objToStr(o) === '[object Date]';
|
||||||
|
}
|
||||||
|
clone.__isDate = __isDate;
|
||||||
|
|
||||||
|
function __isArray(o) {
|
||||||
|
return typeof o === 'object' && __objToStr(o) === '[object Array]';
|
||||||
|
}
|
||||||
|
clone.__isArray = __isArray;
|
||||||
|
|
||||||
|
function __isRegExp(o) {
|
||||||
|
return typeof o === 'object' && __objToStr(o) === '[object RegExp]';
|
||||||
|
}
|
||||||
|
clone.__isRegExp = __isRegExp;
|
||||||
|
|
||||||
|
function __getRegExpFlags(re) {
|
||||||
|
var flags = '';
|
||||||
|
if (re.global) flags += 'g';
|
||||||
|
if (re.ignoreCase) flags += 'i';
|
||||||
|
if (re.multiline) flags += 'm';
|
||||||
|
return flags;
|
||||||
|
}
|
||||||
|
clone.__getRegExpFlags = __getRegExpFlags;
|
||||||
|
|
||||||
|
return clone;
|
||||||
|
})();
|
||||||
|
|
||||||
|
export default clone
|
20
src/js_sdk/luch-request/package.json
Normal file
20
src/js_sdk/luch-request/package.json
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
{
|
||||||
|
"id": "luch-request",
|
||||||
|
"name": "luch-request",
|
||||||
|
"displayName": "luch-request",
|
||||||
|
"version": "3.1.0",
|
||||||
|
"description": "基于Promise开发的跨平台、项目级别的请求库,它有更小的体积,易用的api,方便简单的自定义能力",
|
||||||
|
"keywords": [
|
||||||
|
"request",
|
||||||
|
"axios",
|
||||||
|
"网络请求",
|
||||||
|
"拦截器",
|
||||||
|
"promise"
|
||||||
|
],
|
||||||
|
"dcloudext": {
|
||||||
|
"category": [
|
||||||
|
"JS SDK",
|
||||||
|
"通用 SDK"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
124
src/locale/en.json
Normal file
124
src/locale/en.json
Normal file
@ -0,0 +1,124 @@
|
|||||||
|
{
|
||||||
|
"common": {
|
||||||
|
"readMore": "READ MORE",
|
||||||
|
"viewDetails": "view details",
|
||||||
|
"truckModel": "Truck Model",
|
||||||
|
"dimension": "Dimension (LxWxH)(mm)",
|
||||||
|
"overhang": "Overhang (front/rear)(mm)",
|
||||||
|
"wheelBase": "Wheelbase (mm)",
|
||||||
|
"maxSpeed": "Max speed (km/h)",
|
||||||
|
"curbWeight": "Curb weight (kg)",
|
||||||
|
"loadingWeight": "Loading weight (kg)",
|
||||||
|
"approachingAngle/Departure": "Approaching angle/Departure angle (º)",
|
||||||
|
"products": "PRODUCTS",
|
||||||
|
"companyProducts": "COMPANY PRODUCTS",
|
||||||
|
"brand": "Brand",
|
||||||
|
"driveWheel": "Drive Wheel",
|
||||||
|
"drivingStyle": "Driving Style",
|
||||||
|
"placeofOrigin": "Place of Origin",
|
||||||
|
"tel": "Tel",
|
||||||
|
"Mob/Whatsapp/Wechat": "Mob/Whatsapp/Wechat",
|
||||||
|
"E-mail": "E-mail",
|
||||||
|
"send": "SEND",
|
||||||
|
"enterEail": "Enter your email here",
|
||||||
|
"addressLabel": "Address",
|
||||||
|
"fax": "Fax",
|
||||||
|
"submit": "SUBMIT",
|
||||||
|
"sendInquiry": "Send Inquiry",
|
||||||
|
"chatNow": "Chat Now",
|
||||||
|
"menu": "Menu",
|
||||||
|
"search": "Search",
|
||||||
|
"next": "Next",
|
||||||
|
"prev": "Prev",
|
||||||
|
"submitSuccess": "Submit success",
|
||||||
|
"fulltextsearch": "Full text search",
|
||||||
|
"language": "Language",
|
||||||
|
"Categories": "Categories",
|
||||||
|
"empty": "No data available at the moment",
|
||||||
|
"Contact": "Contact",
|
||||||
|
"Online": "Online",
|
||||||
|
"Whats": "Whats",
|
||||||
|
"TOP": "TOP"
|
||||||
|
},
|
||||||
|
"menu": {
|
||||||
|
"Home": "Home",
|
||||||
|
"AboutUs": "AboutUs",
|
||||||
|
"Products": "Products",
|
||||||
|
"News": "News",
|
||||||
|
"Exhibition": "Exhibition",
|
||||||
|
"ContactUs": "ContactUs",
|
||||||
|
"Feedback": "Feedback"
|
||||||
|
},
|
||||||
|
"news": {
|
||||||
|
"news": "News",
|
||||||
|
"newsCenter": "NEWS CENTER",
|
||||||
|
"allNews": "ALL NEWS",
|
||||||
|
"relatedNews": "Related News",
|
||||||
|
"relatedProducts": "Related Products"
|
||||||
|
},
|
||||||
|
"exhibition": {
|
||||||
|
"exhibition": "Exhibition",
|
||||||
|
"exhibitionCenter": "EXHIBITION CENTER",
|
||||||
|
"allExhibition": "ALL EXHIBITION",
|
||||||
|
"relatedExhibition": "Related Exhibition",
|
||||||
|
"relatedProducts": "Related Products"
|
||||||
|
},
|
||||||
|
"products": {
|
||||||
|
"products": "PRODUCTS",
|
||||||
|
"allProducts": "ALL PRODUCTS",
|
||||||
|
"productDetails": "Product Details",
|
||||||
|
"inquiry": "Inquiry"
|
||||||
|
},
|
||||||
|
"index": {
|
||||||
|
"companyProfile": "COMPANY PROFILE",
|
||||||
|
"corporateName": "SINOTRUCK HOWO SALES CO.,LTD.",
|
||||||
|
"companyProfileContent": "SINOTRUCK HOWO SALES CO.,LTD.is located in Jinan city, Shandong Province, P.R. China. It is the cradle and leading production base of the heavy-duty truck industry in China. It is famous for developing and manufacturing SINOTRUK HOWO tractor trucks, dump trucks, fuel tanker trucks and concrete mixer truck, water spraying trucks etc.",
|
||||||
|
"highQuality": "HIGH QUALITY",
|
||||||
|
"LEadingbBraNd": "LEADING BRAND",
|
||||||
|
"experiencedStaff": "EXPERIENCED STAFF",
|
||||||
|
"advancedEquipment": "ADVANCED EQUIPMENT",
|
||||||
|
"popularProduct": "POPULAR PRODUCT",
|
||||||
|
"productDesc": "The company's popular products are on display. Welcome to purchase",
|
||||||
|
"pressCenter": "PRESS CENTER",
|
||||||
|
"realTimeNewsReadingOnline": "Real-time news reading online",
|
||||||
|
"joinOurNewsletter": "JOIN OUR NEWSLETTER",
|
||||||
|
"signUpOurNewsletter": "Sign up our newsletter and get more events & promotions!"
|
||||||
|
},
|
||||||
|
"aboutUs": {
|
||||||
|
"AboutUs": "About Us",
|
||||||
|
"company": "Sinotruck Howo Sales Co.,Ltd",
|
||||||
|
"address": "Room 2403, No.1 Yinzuo Jingdu Mansion, Shunhe East Street No.66, District Shizhong, Jinan city, shandong province, China"
|
||||||
|
},
|
||||||
|
"contactUs": {
|
||||||
|
"contactUs": "Contact Us",
|
||||||
|
"contacts": "Alice",
|
||||||
|
"way": "Find us through some contact information",
|
||||||
|
"contact": "Contact",
|
||||||
|
"name": "Your name",
|
||||||
|
"title": "Title",
|
||||||
|
"company": "Company",
|
||||||
|
"mail": "Mail",
|
||||||
|
"contactWay": "Phone/WhatsApp",
|
||||||
|
"desc": "Please fill in the form with details so we can send you a quotation correctly",
|
||||||
|
"address": "Shangang xintiandi No8, 19 floor, Lixia district, jinan, Shandong, China"
|
||||||
|
},
|
||||||
|
"feedback": {
|
||||||
|
"feedback": "Feedback",
|
||||||
|
"way": "Find us through some contact information"
|
||||||
|
},
|
||||||
|
"footer": {
|
||||||
|
"contactUs": "Contact us"
|
||||||
|
},
|
||||||
|
"seo": {
|
||||||
|
"news": {
|
||||||
|
"title": "China National Heavy Duty Truck Group Co., Ltd. - News List",
|
||||||
|
"keywords": "China National Heavy Duty Truck Group (CNHTC) HOWO, HOWO Trucks, Heavy Truck Sales, Commercial Vehicles, Heavy duty Trucks, HOWO News, CNHTC News, Truck Trading, HOWO After sales Service, Large Trucks",
|
||||||
|
"description": "China National Heavy Duty Truck Group Co., Ltd. provides the latest news, product information, and industry trends on HOWO trucks, focusing on heavy-duty truck sales and services. Understand the information of HOWO models, grasp the trends of the heavy-duty truck industry, and help you make wise purchasing decisions."
|
||||||
|
},
|
||||||
|
"product": {
|
||||||
|
"title": "China National Heavy Duty Truck Group HOWO Product Display - HOWO Truck Series",
|
||||||
|
"keywords": "China National Heavy Duty Truck Group (CNHTC) HOWO, HOWO Trucks, Heavy Truck Products, Heavy duty Trucks, Commercial Vehicles, HOWO Models, CNHTC Products, HOWO Truck Series, Large Trucks, Commercial Vehicle Products",
|
||||||
|
"description": "China National Heavy Duty Truck Group Co., Ltd. provides a rich range of HOWO truck products, including various models and configurations. Understand the performance, technical specifications, and industry advantages of our heavy-duty trucks to meet your procurement needs."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
124
src/locale/zh.json
Normal file
124
src/locale/zh.json
Normal file
@ -0,0 +1,124 @@
|
|||||||
|
{
|
||||||
|
"common": {
|
||||||
|
"readMore": "阅读更多",
|
||||||
|
"viewDetails": "查看详情",
|
||||||
|
"truckModel": "卡车型号",
|
||||||
|
"dimension": "尺寸(长x宽x高)(毫米)",
|
||||||
|
"overhang": "悬垂(前/后)(mm)",
|
||||||
|
"wheelBase": "轴距(mm)",
|
||||||
|
"maxSpeed": "最高速度(公里/小时)",
|
||||||
|
"curbWeight": "整备质量(kg)",
|
||||||
|
"loadingWeight": "装载重量(kg)",
|
||||||
|
"approachingAngle/Departure": "接近角/离开角(º)",
|
||||||
|
"products": "产品",
|
||||||
|
"companyProducts": "公司产品",
|
||||||
|
"brand": "品牌",
|
||||||
|
"driveWheel": "驱动轮",
|
||||||
|
"drivingStyle": "驾驶方式",
|
||||||
|
"placeofOrigin": "产地",
|
||||||
|
"tel": "电话",
|
||||||
|
"Mob/Whatsapp/Wechat": "手机/Whatsapp/微信",
|
||||||
|
"E-mail": "电子邮件",
|
||||||
|
"send": "发送",
|
||||||
|
"enterEail": "在此处输入您的电子邮件",
|
||||||
|
"addressLabel": "地址",
|
||||||
|
"fax": "传真",
|
||||||
|
"submit": "提交",
|
||||||
|
"sendInquiry": "发送咨询",
|
||||||
|
"chatNow": "立即聊天",
|
||||||
|
"menu": "菜单",
|
||||||
|
"search": "搜索",
|
||||||
|
"next": "下一个",
|
||||||
|
"prev": "上一个",
|
||||||
|
"submitSuccess": "提交成功",
|
||||||
|
"fulltextsearch": "全站搜索",
|
||||||
|
"language": "语言",
|
||||||
|
"Categories": "分类",
|
||||||
|
"empty": "暂无数据",
|
||||||
|
"Contact": "联系我们",
|
||||||
|
"Online": "在线",
|
||||||
|
"Whats": "Whatsapp",
|
||||||
|
"TOP": "顶部"
|
||||||
|
},
|
||||||
|
"menu": {
|
||||||
|
"Home": "首页",
|
||||||
|
"AboutUs": "关于我们",
|
||||||
|
"Products": "产品",
|
||||||
|
"News": "新闻",
|
||||||
|
"Exhibition": "展览",
|
||||||
|
"ContactUs": "联系我们",
|
||||||
|
"Feedback": "反馈"
|
||||||
|
},
|
||||||
|
"index": {
|
||||||
|
"companyProfile": "公司简介",
|
||||||
|
"corporateName": "中国重汽豪沃销售有限公司",
|
||||||
|
"companyProfileContent": "中国重汽豪沃销售有限公司位于中国山东省济南市。它是中国重型卡车行业的摇篮和领先的生产基地。以开发和制造中国重汽豪沃牵引车、自卸卡车、油罐车和混凝土搅拌车、洒水车等而闻名。",
|
||||||
|
"highQuality": "高品质",
|
||||||
|
"LEadingbBraNd": "领先品牌",
|
||||||
|
"experiencedStaff": "经验丰富的员工",
|
||||||
|
"advancedEquipment": "先进设备",
|
||||||
|
"popularProduct": "热门产品",
|
||||||
|
"productDesc": "该公司的热门产品正在展出。欢迎购买",
|
||||||
|
"pressCenter": "新闻中心",
|
||||||
|
"realTimeNewsReadingOnline": "实时新闻在线阅读",
|
||||||
|
"joinOurNewsletter": "加入我们的实时通讯",
|
||||||
|
"signUpOurNewsletter": "注册我们的实时通讯,获取更多活动和促销!"
|
||||||
|
},
|
||||||
|
"news": {
|
||||||
|
"news": "新闻",
|
||||||
|
"newsCenter": "新闻中心",
|
||||||
|
"allNews": "所有新闻",
|
||||||
|
"relatedNews": "相关新闻",
|
||||||
|
"relatedProducts": "相关产品"
|
||||||
|
},
|
||||||
|
"exhibition": {
|
||||||
|
"exhibition": "展览",
|
||||||
|
"exhibitionCenter": "展览中心",
|
||||||
|
"allExhibition": "所有展览",
|
||||||
|
"relatedExhibition": "相关展览",
|
||||||
|
"relatedProducts": "相关产品"
|
||||||
|
},
|
||||||
|
"products": {
|
||||||
|
"products": "产品",
|
||||||
|
"allProducts": "所有产品",
|
||||||
|
"productDetails": "产品详情",
|
||||||
|
"inquiry": "询价"
|
||||||
|
},
|
||||||
|
"aboutUs": {
|
||||||
|
"AboutUs": "关于我们",
|
||||||
|
"company": "中车豪沃销售有限公司",
|
||||||
|
"address": "中国山东省济南市市中区顺河东街66号银座京都大厦1号2403室"
|
||||||
|
},
|
||||||
|
"contactUs": {
|
||||||
|
"contactUs": "联系我们",
|
||||||
|
"contacts": "艾丽斯",
|
||||||
|
"way": "通过一些联系方式找到我们",
|
||||||
|
"contact": "联系",
|
||||||
|
"name": "你的名字",
|
||||||
|
"title": "你的职位",
|
||||||
|
"company": "你的公司",
|
||||||
|
"mail": "邮件",
|
||||||
|
"contactWay": "电话/WhatsApp",
|
||||||
|
"desc": "请详细填写表格,以便我们正确地向您发送报价",
|
||||||
|
"address": "山东省济南市历下区19楼善港新天地8号"
|
||||||
|
},
|
||||||
|
"feedback": {
|
||||||
|
"feedback": "反馈",
|
||||||
|
"way": "通过一些联系方式找到我们"
|
||||||
|
},
|
||||||
|
"footer": {
|
||||||
|
"contactUs": "联系我们"
|
||||||
|
},
|
||||||
|
"seo": {
|
||||||
|
"news": {
|
||||||
|
"title": "中国重汽豪沃销售有限公司 - 新闻列表",
|
||||||
|
"keywords": "中国重汽豪沃, 豪沃卡车, 重卡销售, 商用车, 重型卡车, 豪沃新闻, 重汽新闻, 卡车交易, 豪沃售后服务, 大型卡车",
|
||||||
|
"description": "中国重汽豪沃销售有限公司提供最新的豪沃卡车新闻、产品信息及行业动态,专注于重卡销售与服务。了解豪沃车型资讯,掌握重型卡车行业趋势,助您做出明智的采购决策。"
|
||||||
|
},
|
||||||
|
"product": {
|
||||||
|
"title": "中国重汽豪沃产品展示 - 豪沃卡车系列",
|
||||||
|
"keywords": "中国重汽豪沃, 豪沃卡车, 重卡产品, 重型卡车, 商用车, 豪沃车型, 重汽产品, 豪沃卡车系列, 大型卡车, 商用车产品",
|
||||||
|
"description": "中国重汽豪沃销售有限公司提供丰富的豪沃卡车产品系列,包括各种车型和配置。了解我们的重型卡车性能、技术参数及行业优势,满足您的采购需求。"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
43
src/main.js
Normal file
43
src/main.js
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
import { createSSRApp,provide,h } from "vue";
|
||||||
|
import App from "./App.vue";
|
||||||
|
import { createPinia } from 'pinia';
|
||||||
|
import { createI18n } from 'vue-i18n';
|
||||||
|
import zh from './locale/zh.json';
|
||||||
|
import en from './locale/en.json';
|
||||||
|
import ConfirmPopup from '@/components/comfirm-popup.vue'; // 全局统一的操作弹窗
|
||||||
|
|
||||||
|
uni.$showTost = function (title='加载失败!',duration=1500,mask=false) {
|
||||||
|
// 变成异步代码,处理一些特殊页面 必须等待消息提示结束后在做操作
|
||||||
|
return new Promise((res,rej) => {
|
||||||
|
uni.showToast({
|
||||||
|
title,
|
||||||
|
mask,
|
||||||
|
icon:'none',
|
||||||
|
duration
|
||||||
|
})
|
||||||
|
setTimeout(() => {
|
||||||
|
res(true)
|
||||||
|
},duration)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const messages = {
|
||||||
|
en,
|
||||||
|
zh,
|
||||||
|
}
|
||||||
|
let i18nConfig = {
|
||||||
|
locale: uni.getLocale(),// 获取已设置的语言
|
||||||
|
messages
|
||||||
|
}
|
||||||
|
|
||||||
|
const i18n = createI18n(i18nConfig)
|
||||||
|
|
||||||
|
export function createApp() {
|
||||||
|
const app = createSSRApp(App);
|
||||||
|
app.use(i18n)
|
||||||
|
app.use(createPinia());
|
||||||
|
app.component('ConfirmPopup', ConfirmPopup)
|
||||||
|
return {
|
||||||
|
app,
|
||||||
|
};
|
||||||
|
}
|
85
src/manifest.json
Normal file
85
src/manifest.json
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
{
|
||||||
|
"name" : "HOWO",
|
||||||
|
"appid" : "__UNI__DADC1D2",
|
||||||
|
"description" : "Sinotruck Howo Sales Co.,Ltd is one of the most professional trailer, truck, trailer parts, truck parts manufacturers in China. Our factory brings here a great selection of truck for sale. Welcome to consult price with us.",
|
||||||
|
"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" : [
|
||||||
|
"<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>",
|
||||||
|
"<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>",
|
||||||
|
"<uses-permission android:name=\"android.permission.VIBRATE\"/>",
|
||||||
|
"<uses-permission android:name=\"android.permission.READ_LOGS\"/>",
|
||||||
|
"<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>",
|
||||||
|
"<uses-feature android:name=\"android.hardware.camera.autofocus\"/>",
|
||||||
|
"<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>",
|
||||||
|
"<uses-permission android:name=\"android.permission.CAMERA\"/>",
|
||||||
|
"<uses-permission android:name=\"android.permission.GET_ACCOUNTS\"/>",
|
||||||
|
"<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>",
|
||||||
|
"<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>",
|
||||||
|
"<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>",
|
||||||
|
"<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>",
|
||||||
|
"<uses-feature android:name=\"android.hardware.camera\"/>",
|
||||||
|
"<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
/* ios打包配置 */
|
||||||
|
"ios" : {},
|
||||||
|
/* SDK配置 */
|
||||||
|
"sdkConfigs" : {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
/* 快应用特有相关 */
|
||||||
|
"quickapp" : {},
|
||||||
|
/* 小程序特有相关 */
|
||||||
|
"mp-weixin" : {
|
||||||
|
"appid" : "wx4cb7d04123386d0e",
|
||||||
|
"setting" : {
|
||||||
|
"urlCheck" : false,
|
||||||
|
"postcss" : true,
|
||||||
|
"es6" : true,
|
||||||
|
"minified" : true
|
||||||
|
},
|
||||||
|
"usingComponents" : true
|
||||||
|
},
|
||||||
|
"mp-alipay" : {
|
||||||
|
"usingComponents" : true
|
||||||
|
},
|
||||||
|
"mp-baidu" : {
|
||||||
|
"usingComponents" : true
|
||||||
|
},
|
||||||
|
"mp-toutiao" : {
|
||||||
|
"usingComponents" : true
|
||||||
|
},
|
||||||
|
"uniStatistics" : {
|
||||||
|
"enable" : false
|
||||||
|
},
|
||||||
|
"vueVersion" : "3",
|
||||||
|
"h5" : {
|
||||||
|
"router" : {
|
||||||
|
"mode" : "history"
|
||||||
|
},
|
||||||
|
"devServer" : {
|
||||||
|
"port" : 5173
|
||||||
|
},
|
||||||
|
"title" : "China Trailer, Truck, Trailer Parts, Truck Parts Manufacturers and Factory - Price - SINOTRUCK"
|
||||||
|
},
|
||||||
|
"locale" : "en"
|
||||||
|
}
|
24
src/pages.json
Normal file
24
src/pages.json
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
{
|
||||||
|
"easycom": {
|
||||||
|
"autoscan": true,
|
||||||
|
"custom": {
|
||||||
|
// uni-ui 规则如下配置
|
||||||
|
"^uni-(.*)": "@dcloudio/uni-ui/lib/uni-$1/uni-$1.vue"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"pages": [ //pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocation/pages
|
||||||
|
{
|
||||||
|
"path": "pages/index/index",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": "China Trailer, Truck, Trailer Parts, Truck Parts Manufacturers and Factory - Price - SINOTRUCK"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"globalStyle": {
|
||||||
|
"navigationStyle": "custom",
|
||||||
|
"navigationBarTextStyle": "black",
|
||||||
|
"navigationBarTitleText": "China Trailer, Truck, Trailer Parts, Truck Parts Manufacturers and Factory - Price - SINOTRUCK",
|
||||||
|
"navigationBarBackgroundColor": "#F8F8F8",
|
||||||
|
"backgroundColor": "#F8F8F8"
|
||||||
|
}
|
||||||
|
}
|
25
src/pages/index/index.vue
Normal file
25
src/pages/index/index.vue
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
<template>
|
||||||
|
<view class="content">
|
||||||
|
{{$t('index.companyProfile')}}
|
||||||
|
<ConfirmPopup ref="comfirmPopupRef" v-if="popupShow" />
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref } from 'vue';
|
||||||
|
import { onLoad } from '@dcloudio/uni-app';
|
||||||
|
import { index } from '@/stores/index.js';
|
||||||
|
import { useComfirmPopup } from '@/hooks/utils.js';
|
||||||
|
import { getFriendLink } from '@/api/index.js';
|
||||||
|
|
||||||
|
const { popupShow,comfirmPopupRef,openPopup } = useComfirmPopup()
|
||||||
|
|
||||||
|
const piniaIndex = index()
|
||||||
|
onLoad(() => {
|
||||||
|
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
|
||||||
|
</style>
|
BIN
src/static/logo.png
Normal file
BIN
src/static/logo.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.9 KiB |
14
src/stores/index.js
Normal file
14
src/stores/index.js
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
import { defineStore } from 'pinia';
|
||||||
|
import { reactive, ref } from 'vue';
|
||||||
|
|
||||||
|
export const index = defineStore('index',()=>{
|
||||||
|
let num = ref(0);
|
||||||
|
|
||||||
|
const countHanderl = () => {
|
||||||
|
num.value += 1
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
num,
|
||||||
|
countHanderl
|
||||||
|
}
|
||||||
|
})
|
76
src/uni.scss
Normal file
76
src/uni.scss
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
/**
|
||||||
|
* 这里是uni-app内置的常用样式变量
|
||||||
|
*
|
||||||
|
* uni-app 官方扩展插件及插件市场(https://ext.dcloud.net.cn)上很多三方插件均使用了这些样式变量
|
||||||
|
* 如果你是插件开发者,建议你使用scss预处理,并在插件代码中直接使用这些变量(无需 import 这个文件),方便用户通过搭积木的方式开发整体风格一致的App
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 如果你是App开发者(插件使用者),你可以通过修改这些变量来定制自己的插件主题,实现自定义主题功能
|
||||||
|
*
|
||||||
|
* 如果你的项目同样使用了scss预处理,你也可以直接在你的 scss 代码中使用如下变量,同时无需 import 这个文件
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* 颜色变量 */
|
||||||
|
|
||||||
|
/* 行为相关颜色 */
|
||||||
|
$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: #fff;
|
||||||
|
$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: #555; // 二级标题颜色
|
||||||
|
$uni-font-size-subtitle: 18px;
|
||||||
|
$uni-color-paragraph: #3f536e; // 文章段落颜色
|
||||||
|
$uni-font-size-paragraph: 15px;
|
352
src/utils/html-parser.js
Normal file
352
src/utils/html-parser.js
Normal file
@ -0,0 +1,352 @@
|
|||||||
|
/*
|
||||||
|
* HTML5 Parser By Sam Blowes
|
||||||
|
*
|
||||||
|
* Designed for HTML5 documents
|
||||||
|
*
|
||||||
|
* Original code by John Resig (ejohn.org)
|
||||||
|
* http://ejohn.org/blog/pure-javascript-html-parser/
|
||||||
|
* Original code by Erik Arvidsson, Mozilla Public License
|
||||||
|
* http://erik.eae.net/simplehtmlparser/simplehtmlparser.js
|
||||||
|
*
|
||||||
|
* ----------------------------------------------------------------------------
|
||||||
|
* License
|
||||||
|
* ----------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* This code is triple licensed using Apache Software License 2.0,
|
||||||
|
* Mozilla Public License or GNU Public License
|
||||||
|
*
|
||||||
|
* ////////////////////////////////////////////////////////////////////////////
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||||
|
* use this file except in compliance with the License. You may obtain a copy
|
||||||
|
* of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* ////////////////////////////////////////////////////////////////////////////
|
||||||
|
*
|
||||||
|
* The contents of this file are subject to the Mozilla Public License
|
||||||
|
* Version 1.1 (the "License"); you may not use this file except in
|
||||||
|
* compliance with the License. You may obtain a copy of the License at
|
||||||
|
* http://www.mozilla.org/MPL/
|
||||||
|
*
|
||||||
|
* Software distributed under the License is distributed on an "AS IS"
|
||||||
|
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
|
||||||
|
* License for the specific language governing rights and limitations
|
||||||
|
* under the License.
|
||||||
|
*
|
||||||
|
* The Original Code is Simple HTML Parser.
|
||||||
|
*
|
||||||
|
* The Initial Developer of the Original Code is Erik Arvidsson.
|
||||||
|
* Portions created by Erik Arvidssson are Copyright (C) 2004. All Rights
|
||||||
|
* Reserved.
|
||||||
|
*
|
||||||
|
* ////////////////////////////////////////////////////////////////////////////
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
* ----------------------------------------------------------------------------
|
||||||
|
* Usage
|
||||||
|
* ----------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* // Use like so:
|
||||||
|
* HTMLParser(htmlString, {
|
||||||
|
* start: function(tag, attrs, unary) {},
|
||||||
|
* end: function(tag) {},
|
||||||
|
* chars: function(text) {},
|
||||||
|
* comment: function(text) {}
|
||||||
|
* });
|
||||||
|
*
|
||||||
|
* // or to get an XML string:
|
||||||
|
* HTMLtoXML(htmlString);
|
||||||
|
*
|
||||||
|
* // or to get an XML DOM Document
|
||||||
|
* HTMLtoDOM(htmlString);
|
||||||
|
*
|
||||||
|
* // or to inject into an existing document/DOM node
|
||||||
|
* HTMLtoDOM(htmlString, document);
|
||||||
|
* HTMLtoDOM(htmlString, document.body);
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
// Regular Expressions for parsing tags and attributes
|
||||||
|
var startTag = /^<([-A-Za-z0-9_]+)((?:\s+[a-zA-Z_:][-a-zA-Z0-9_:.]*(?:\s*=\s*(?:(?:"[^"]*")|(?:'[^']*')|[^>\s]+))?)*)\s*(\/?)>/;
|
||||||
|
var endTag = /^<\/([-A-Za-z0-9_]+)[^>]*>/;
|
||||||
|
var attr = /([a-zA-Z_:][-a-zA-Z0-9_:.]*)(?:\s*=\s*(?:(?:"((?:\\.|[^"])*)")|(?:'((?:\\.|[^'])*)')|([^>\s]+)))?/g; // Empty Elements - HTML 5
|
||||||
|
|
||||||
|
var empty = makeMap('area,base,basefont,br,col,frame,hr,img,input,link,meta,param,embed,command,keygen,source,track,wbr'); // Block Elements - HTML 5
|
||||||
|
// fixed by xxx 将 ins 标签从块级名单中移除
|
||||||
|
|
||||||
|
var block = makeMap('a,address,article,applet,aside,audio,blockquote,button,canvas,center,dd,del,dir,div,dl,dt,fieldset,figcaption,figure,footer,form,frameset,h1,h2,h3,h4,h5,h6,header,hgroup,hr,iframe,isindex,li,map,menu,noframes,noscript,object,ol,output,p,pre,section,script,table,tbody,td,tfoot,th,thead,tr,ul,video'); // Inline Elements - HTML 5
|
||||||
|
|
||||||
|
var inline = makeMap('abbr,acronym,applet,b,basefont,bdo,big,br,button,cite,code,del,dfn,em,font,i,iframe,img,input,ins,kbd,label,map,object,q,s,samp,script,select,small,span,strike,strong,sub,sup,textarea,tt,u,var'); // Elements that you can, intentionally, leave open
|
||||||
|
// (and which close themselves)
|
||||||
|
|
||||||
|
var closeSelf = makeMap('colgroup,dd,dt,li,options,p,td,tfoot,th,thead,tr'); // Attributes that have their values filled in disabled="disabled"
|
||||||
|
|
||||||
|
var fillAttrs = makeMap('checked,compact,declare,defer,disabled,ismap,multiple,nohref,noresize,noshade,nowrap,readonly,selected'); // Special Elements (can contain anything)
|
||||||
|
|
||||||
|
var special = makeMap('script,style');
|
||||||
|
function HTMLParser(html, handler) {
|
||||||
|
var index;
|
||||||
|
var chars;
|
||||||
|
var match;
|
||||||
|
var stack = [];
|
||||||
|
var last = html;
|
||||||
|
|
||||||
|
stack.last = function () {
|
||||||
|
return this[this.length - 1];
|
||||||
|
};
|
||||||
|
|
||||||
|
while (html) {
|
||||||
|
chars = true; // Make sure we're not in a script or style element
|
||||||
|
|
||||||
|
if (!stack.last() || !special[stack.last()]) {
|
||||||
|
// Comment
|
||||||
|
if (html.indexOf('<!--') == 0) {
|
||||||
|
index = html.indexOf('-->');
|
||||||
|
|
||||||
|
if (index >= 0) {
|
||||||
|
if (handler.comment) {
|
||||||
|
handler.comment(html.substring(4, index));
|
||||||
|
}
|
||||||
|
|
||||||
|
html = html.substring(index + 3);
|
||||||
|
chars = false;
|
||||||
|
} // end tag
|
||||||
|
|
||||||
|
} else if (html.indexOf('</') == 0) {
|
||||||
|
match = html.match(endTag);
|
||||||
|
|
||||||
|
if (match) {
|
||||||
|
html = html.substring(match[0].length);
|
||||||
|
match[0].replace(endTag, parseEndTag);
|
||||||
|
chars = false;
|
||||||
|
} // start tag
|
||||||
|
|
||||||
|
} else if (html.indexOf('<') == 0) {
|
||||||
|
match = html.match(startTag);
|
||||||
|
|
||||||
|
if (match) {
|
||||||
|
html = html.substring(match[0].length);
|
||||||
|
match[0].replace(startTag, parseStartTag);
|
||||||
|
chars = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (chars) {
|
||||||
|
index = html.indexOf('<');
|
||||||
|
var text = index < 0 ? html : html.substring(0, index);
|
||||||
|
html = index < 0 ? '' : html.substring(index);
|
||||||
|
|
||||||
|
if (handler.chars) {
|
||||||
|
handler.chars(text);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
html = html.replace(new RegExp('([\\s\\S]*?)<\/' + stack.last() + '[^>]*>'), function (all, text) {
|
||||||
|
text = text.replace(/<!--([\s\S]*?)-->|<!\[CDATA\[([\s\S]*?)]]>/g, '$1$2');
|
||||||
|
|
||||||
|
if (handler.chars) {
|
||||||
|
handler.chars(text);
|
||||||
|
}
|
||||||
|
|
||||||
|
return '';
|
||||||
|
});
|
||||||
|
parseEndTag('', stack.last());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (html == last) {
|
||||||
|
throw 'Parse Error: ' + html;
|
||||||
|
}
|
||||||
|
|
||||||
|
last = html;
|
||||||
|
} // Clean up any remaining tags
|
||||||
|
|
||||||
|
|
||||||
|
parseEndTag();
|
||||||
|
|
||||||
|
function parseStartTag(tag, tagName, rest, unary) {
|
||||||
|
tagName = tagName.toLowerCase();
|
||||||
|
|
||||||
|
if (block[tagName]) {
|
||||||
|
while (stack.last() && inline[stack.last()]) {
|
||||||
|
parseEndTag('', stack.last());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (closeSelf[tagName] && stack.last() == tagName) {
|
||||||
|
parseEndTag('', tagName);
|
||||||
|
}
|
||||||
|
|
||||||
|
unary = empty[tagName] || !!unary;
|
||||||
|
|
||||||
|
if (!unary) {
|
||||||
|
stack.push(tagName);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (handler.start) {
|
||||||
|
var attrs = [];
|
||||||
|
rest.replace(attr, function (match, name) {
|
||||||
|
var value = arguments[2] ? arguments[2] : arguments[3] ? arguments[3] : arguments[4] ? arguments[4] : fillAttrs[name] ? name : '';
|
||||||
|
attrs.push({
|
||||||
|
name: name,
|
||||||
|
value: value,
|
||||||
|
escaped: value.replace(/(^|[^\\])"/g, '$1\\\"') // "
|
||||||
|
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
if (handler.start) {
|
||||||
|
handler.start(tagName, attrs, unary);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function parseEndTag(tag, tagName) {
|
||||||
|
// If no tag name is provided, clean shop
|
||||||
|
if (!tagName) {
|
||||||
|
var pos = 0;
|
||||||
|
} // Find the closest opened tag of the same type
|
||||||
|
else {
|
||||||
|
for (var pos = stack.length - 1; pos >= 0; pos--) {
|
||||||
|
if (stack[pos] == tagName) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pos >= 0) {
|
||||||
|
// Close all the open elements, up the stack
|
||||||
|
for (var i = stack.length - 1; i >= pos; i--) {
|
||||||
|
if (handler.end) {
|
||||||
|
handler.end(stack[i]);
|
||||||
|
}
|
||||||
|
} // Remove the open elements from the stack
|
||||||
|
|
||||||
|
|
||||||
|
stack.length = pos;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function makeMap(str) {
|
||||||
|
var obj = {};
|
||||||
|
var items = str.split(',');
|
||||||
|
|
||||||
|
for (var i = 0; i < items.length; i++) {
|
||||||
|
obj[items[i]] = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
function removeDOCTYPE(html) {
|
||||||
|
return html.replace(/<\?xml.*\?>\n/, '').replace(/<!doctype.*>\n/, '').replace(/<!DOCTYPE.*>\n/, '');
|
||||||
|
}
|
||||||
|
|
||||||
|
function parseAttrs(attrs) {
|
||||||
|
return attrs.reduce(function (pre, attr) {
|
||||||
|
var value = attr.value;
|
||||||
|
var name = attr.name;
|
||||||
|
|
||||||
|
if (pre[name]) {
|
||||||
|
pre[name] = pre[name] + " " + value;
|
||||||
|
} else {
|
||||||
|
pre[name] = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
return pre;
|
||||||
|
}, {});
|
||||||
|
}
|
||||||
|
|
||||||
|
function parseHtml(html) {
|
||||||
|
html = removeDOCTYPE(html);
|
||||||
|
var stacks = [];
|
||||||
|
var results = {
|
||||||
|
node: 'root',
|
||||||
|
children: []
|
||||||
|
};
|
||||||
|
HTMLParser(html, {
|
||||||
|
start: function start(tag, attrs, unary) {
|
||||||
|
var node = {
|
||||||
|
name: tag
|
||||||
|
};
|
||||||
|
|
||||||
|
if (attrs.length !== 0) {
|
||||||
|
node.attrs = parseAttrs(attrs);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (unary) {
|
||||||
|
var parent = stacks[0] || results;
|
||||||
|
|
||||||
|
if (!parent.children) {
|
||||||
|
parent.children = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
parent.children.push(node);
|
||||||
|
} else {
|
||||||
|
stacks.unshift(node);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
end: function end(tag) {
|
||||||
|
var node = stacks.shift();
|
||||||
|
if (node.name !== tag) console.error('invalid state: mismatch end tag');
|
||||||
|
|
||||||
|
if (stacks.length === 0) {
|
||||||
|
results.children.push(node);
|
||||||
|
} else {
|
||||||
|
var parent = stacks[0];
|
||||||
|
|
||||||
|
if (!parent.children) {
|
||||||
|
parent.children = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
parent.children.push(node);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
chars: function chars(text) {
|
||||||
|
var node = {
|
||||||
|
type: 'text',
|
||||||
|
text: text
|
||||||
|
};
|
||||||
|
|
||||||
|
if (stacks.length === 0) {
|
||||||
|
results.children.push(node);
|
||||||
|
} else {
|
||||||
|
var parent = stacks[0];
|
||||||
|
|
||||||
|
if (!parent.children) {
|
||||||
|
parent.children = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
parent.children.push(node);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
comment: function comment(text) {
|
||||||
|
var node = {
|
||||||
|
node: 'comment',
|
||||||
|
text: text
|
||||||
|
};
|
||||||
|
var parent = stacks[0];
|
||||||
|
|
||||||
|
if (!parent.children) {
|
||||||
|
parent.children = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
parent.children.push(node);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return results.children;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default parseHtml;
|
49
src/utils/request.js
Normal file
49
src/utils/request.js
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
import Request from '@/js_sdk/luch-request/luch-request/index.js';
|
||||||
|
|
||||||
|
let $http = new Request()
|
||||||
|
|
||||||
|
$http.config = {
|
||||||
|
baseURL: import.meta.env.VITE_APP_BASE_API
|
||||||
|
}
|
||||||
|
|
||||||
|
// 请求拦截器
|
||||||
|
// web运行端口默认5173;可在manifest进行修改默认端口号
|
||||||
|
$http.interceptors.request.use(async (config) => { // 可使用async await 做异步操作
|
||||||
|
config.header = {
|
||||||
|
...config.header,
|
||||||
|
'Token': uni.getStorageSync('annualTicketToken'),
|
||||||
|
}
|
||||||
|
uni.showLoading({
|
||||||
|
title: '加载中...',
|
||||||
|
mask: true
|
||||||
|
})
|
||||||
|
return config
|
||||||
|
|
||||||
|
}, config => { // 可使用async await 做异步操作
|
||||||
|
return Promise.reject(config)
|
||||||
|
})
|
||||||
|
|
||||||
|
// 响应拦截器
|
||||||
|
$http.interceptors.response.use((response) => {
|
||||||
|
uni.hideLoading()
|
||||||
|
switch(response.data.code) {
|
||||||
|
case 0:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// 加入到messageBoxUrl的请求url可触发弹窗形式的提示
|
||||||
|
let messageBoxUrl = []
|
||||||
|
if (messageBoxUrl.indexOf(response.config.url) !== -1) {
|
||||||
|
uni.$showModal('提示',response.data.msg)
|
||||||
|
} else {
|
||||||
|
if (response.data.msg) {
|
||||||
|
uni.$showTost(response.data.msg)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Promise.reject(response)
|
||||||
|
}
|
||||||
|
return response
|
||||||
|
}, (response) => {
|
||||||
|
return Promise.reject(response)
|
||||||
|
})
|
||||||
|
|
||||||
|
export default $http
|
87
src/utils/tool.js
Normal file
87
src/utils/tool.js
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
/**
|
||||||
|
* @function 获取uuid
|
||||||
|
* @return {string} 返回uuid
|
||||||
|
**/
|
||||||
|
export const getUuid = () => {
|
||||||
|
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => {
|
||||||
|
return (c === 'x' ? (Math.random() * 16 | 0) : ('r&0x3' | '0x8')).toString(16)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 实现rich-text富文本中图片宽度最大100%
|
||||||
|
export function formatContent(html) {
|
||||||
|
// 去掉img标签里的style、width、height属性
|
||||||
|
let content_data = html.replace(/<img[^>]*>/gi, function(match, capture) {
|
||||||
|
match = match.replace(/style="[^"]+"/gi, '').replace(/style='[^']+'/gi, '');
|
||||||
|
match = match.replace(/width="[^"]+"/gi, '').replace(/width='[^']+'/gi, '');
|
||||||
|
match = match.replace(/height="[^"]+"/gi, '').replace(/height='[^']+'/gi, '');
|
||||||
|
return match;
|
||||||
|
});
|
||||||
|
// 修改所有style里的width属性为max-width:100%
|
||||||
|
content_data = content_data.replace(/style="[^"]+"/gi, function(match, capture) {
|
||||||
|
match = match.replace(/width:[^;]+;/gi, 'max-width:100%;').replace(/width:[^;]+;/gi, 'max-width:100%;');
|
||||||
|
return match;
|
||||||
|
});
|
||||||
|
// 去掉<br/>标签
|
||||||
|
content_data = content_data.replace(/<br[^>]*\/>/gi, '');
|
||||||
|
// img标签添加style属性:max-width:100%;height:auto
|
||||||
|
content_data = content_data.replace(/\<img/gi,
|
||||||
|
'<img style="max-width:100%;height:auto;display:block;margin:0px auto;"');
|
||||||
|
return content_data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @function 保存图片
|
||||||
|
* @param {string} url 下载地址
|
||||||
|
**/
|
||||||
|
export const downloadFile = (url, type='img') => {
|
||||||
|
if (!url) {
|
||||||
|
return uni.$showTost('请传入下载地址!')
|
||||||
|
}
|
||||||
|
url = url.replace(/http:\/\//g, 'https://')
|
||||||
|
uni.showLoading({
|
||||||
|
title: '保存中...',
|
||||||
|
mask: true
|
||||||
|
})
|
||||||
|
uni.downloadFile({
|
||||||
|
url: url,
|
||||||
|
success: async (res) => {
|
||||||
|
if (type==='img') {
|
||||||
|
uni.saveImageToPhotosAlbum({
|
||||||
|
filePath: res.tempFilePath,
|
||||||
|
success: () => {
|
||||||
|
uni.$showTost('保存成功!')
|
||||||
|
},
|
||||||
|
fail: (err) => {
|
||||||
|
uni.$showTost('保存失败,请手动截屏保存!')
|
||||||
|
},
|
||||||
|
complete: () => {
|
||||||
|
uni.hideLoading()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
await uni.$showTost('即将打开文件,点击文件预览下拉保存文件!', 2000)
|
||||||
|
uni.openDocument({
|
||||||
|
filePath: res.tempFilePath,
|
||||||
|
fileType: 'pdf',
|
||||||
|
complete: () => {
|
||||||
|
uni.hideLoading()
|
||||||
|
},
|
||||||
|
fail:() => {
|
||||||
|
uni.setClipboardData({
|
||||||
|
data: url,
|
||||||
|
success: () => {
|
||||||
|
uni.$showTost('已复制到系统剪切板,请前往浏览器进行下载')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
},
|
||||||
|
fail: err => {
|
||||||
|
uni.hideLoading()
|
||||||
|
uni.$showTost('保存失败')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
29
vite.config.js
Normal file
29
vite.config.js
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
import uni from "@dcloudio/vite-plugin-uni";
|
||||||
|
import { defineConfig, loadEnv } from 'vite';
|
||||||
|
|
||||||
|
export default defineConfig(({ command, mode }) => {
|
||||||
|
// 根据当前工作目录中的 `mode` 加载 .env 文件
|
||||||
|
// 设置第三个参数为 '' 来加载所有环境变量,而不管是否有 `VITE_` 前缀。
|
||||||
|
const env = loadEnv(mode, process.cwd(), '')
|
||||||
|
return {
|
||||||
|
// vite 配置
|
||||||
|
plugins: [uni()],
|
||||||
|
base: './',
|
||||||
|
define: {
|
||||||
|
__APP_ENV__: env.APP_ENV,
|
||||||
|
MY_APP_CONFIG: {
|
||||||
|
|
||||||
|
},
|
||||||
|
},
|
||||||
|
// 产生跨域请求打开
|
||||||
|
// server: {
|
||||||
|
// proxy: {
|
||||||
|
// '/dev': {
|
||||||
|
// target: '', // 代理地址
|
||||||
|
// changeOrigin: true, //支持跨域
|
||||||
|
// rewrite: (path) => path.replace(/^\/dev/, ""),
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
})
|
Loading…
Reference in New Issue
Block a user