同步代码到仓库
This commit is contained in:
commit
5586573ff1
|
|
@ -0,0 +1,5 @@
|
||||||
|
# 忽略提交文件
|
||||||
|
/unpackage
|
||||||
|
node_modules/
|
||||||
|
.vscode/
|
||||||
|
.hbuilderx/
|
||||||
|
|
@ -0,0 +1,23 @@
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
onLaunch: function() {
|
||||||
|
console.log('App Launch')
|
||||||
|
},
|
||||||
|
onShow: function() {
|
||||||
|
console.log('App Show')
|
||||||
|
},
|
||||||
|
onHide: function() {
|
||||||
|
console.log('App Hide')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
/*每个页面公共css */
|
||||||
|
/* #ifdef H5 */
|
||||||
|
uni-page-head
|
||||||
|
{
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
/* #endif */
|
||||||
|
</style>
|
||||||
|
|
@ -0,0 +1,194 @@
|
||||||
|
/**
|
||||||
|
* HTTP的封装, 基于uni.request
|
||||||
|
* 包括: 通用响应结果的处理 和 业务的增删改查函数
|
||||||
|
*
|
||||||
|
* @author terrfly
|
||||||
|
* @site https://www.jeequan.com
|
||||||
|
* @date 2021/12/16 18:35
|
||||||
|
*/
|
||||||
|
|
||||||
|
// 导入全局属性
|
||||||
|
import appConfig from '@/config/appConfig.js'
|
||||||
|
import storageManage from '@/commons/utils/storageManage.js'
|
||||||
|
import {
|
||||||
|
sm4DecryptByResData
|
||||||
|
} from '@/commons/utils/encryptUtil.js'
|
||||||
|
import infoBox from "@/commons/utils/infoBox.js"
|
||||||
|
// let baseUrl = ''
|
||||||
|
let baseUrl = 'https://cashier-client.sxczgkj.cn/cashier-client'
|
||||||
|
// 多少 ms 以内, 不提示loading
|
||||||
|
const loadingShowTime = 200
|
||||||
|
|
||||||
|
|
||||||
|
function getHeader(){
|
||||||
|
const headerObject={}
|
||||||
|
headerObject["Authorization"] = storageManage.token()
|
||||||
|
headerObject["Content-Type"] = 'application/json'
|
||||||
|
headerObject["loginname"] = 'admin'
|
||||||
|
headerObject["token"] = 'eyJhbGciOiJIUzI1NiJ9.eyJ1c2VyVHlwZSI6Ik1HIiwiZXhwIjoxNjkwMTgwNzE2LCJ1c2VySWQiOiIyNDQiLCJpYXQiOjE2ODg3MDk0ODcsImxvZ2luTmFtZSI6ImFkbWluIn0.lqxxvv2-FcecQngMBorz4MpkB3mIJQDG-IUULQyV-KQ'
|
||||||
|
headerObject["userId"] = '244'
|
||||||
|
return headerObject
|
||||||
|
}
|
||||||
|
|
||||||
|
// 通用处理逻辑
|
||||||
|
function commonsProcess(showLoading, httpReqCallback) {
|
||||||
|
|
||||||
|
// 判断是否请求完成(用作 是否loading )
|
||||||
|
// 包括: 'ing', 'ingLoading', 'finish'
|
||||||
|
let reqState = 'ing'
|
||||||
|
|
||||||
|
// 是否已经提示的错误信息
|
||||||
|
let isShowErrorToast = false
|
||||||
|
|
||||||
|
|
||||||
|
// 请求完成, 需要处理的动作
|
||||||
|
let reqFinishFunc = () => {
|
||||||
|
|
||||||
|
if (reqState == 'ingLoading') { // 关闭loading弹层
|
||||||
|
infoBox.hideLoading()
|
||||||
|
}
|
||||||
|
reqState = 'finish' // 请求完毕
|
||||||
|
}
|
||||||
|
|
||||||
|
// 明确显示loading
|
||||||
|
if (showLoading) {
|
||||||
|
// xx ms内响应完成,不提示loading
|
||||||
|
setTimeout(() => {
|
||||||
|
if (reqState == 'ing') {
|
||||||
|
reqState = 'ingLoading'
|
||||||
|
infoBox.showLoading()
|
||||||
|
}
|
||||||
|
}, loadingShowTime)
|
||||||
|
}
|
||||||
|
|
||||||
|
return httpReqCallback().then((httpData) => {
|
||||||
|
reqFinishFunc(); // 请求完毕的动作
|
||||||
|
|
||||||
|
// 从http响应数据中解构响应数据 [ 响应码、 bodyData ]
|
||||||
|
let {
|
||||||
|
statusCode,
|
||||||
|
data
|
||||||
|
} = httpData
|
||||||
|
// 避免混淆重新命名
|
||||||
|
let bodyData = data
|
||||||
|
if (statusCode == 500) {
|
||||||
|
isShowErrorToast = true
|
||||||
|
return Promise.reject(bodyData) // 跳转到catch函数
|
||||||
|
}
|
||||||
|
if (statusCode == 401) {
|
||||||
|
// storageManage.token(null, true)
|
||||||
|
// 提示信息
|
||||||
|
isShowErrorToast = true
|
||||||
|
// infoBox.showErrorToast('请登录').then(() => {
|
||||||
|
// go.to("PAGES_LOGIN", {}, go.GO_TYPE_RELAUNCH)
|
||||||
|
// })
|
||||||
|
return Promise.reject(bodyData) // 跳转到catch函数
|
||||||
|
}
|
||||||
|
// http响应码不正确
|
||||||
|
if (statusCode != 200 && statusCode != 204 && statusCode != 201) {
|
||||||
|
isShowErrorToast = true
|
||||||
|
infoBox.showErrorToast(data.message || '服务器异常')
|
||||||
|
return Promise.reject(bodyData) // 跳转到catch函数
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 构造请求成功的响应数据
|
||||||
|
return Promise.resolve(bodyData)
|
||||||
|
|
||||||
|
}).catch(res => {
|
||||||
|
if(res.status==401){
|
||||||
|
infoBox.showToast(`登录失效`)
|
||||||
|
}
|
||||||
|
if(res.status==500){
|
||||||
|
infoBox.showToast(`网络异常`)
|
||||||
|
}
|
||||||
|
// if(res&&res.msg){
|
||||||
|
// infoBox.showErrorToast(res.msg)
|
||||||
|
// }
|
||||||
|
reqFinishFunc(); // 请求完毕的动作
|
||||||
|
|
||||||
|
// 如果没有提示错误, 那么此处提示 异常。
|
||||||
|
if (!isShowErrorToast) {
|
||||||
|
infoBox.showErrorToast(`请求网络异常`)
|
||||||
|
}
|
||||||
|
|
||||||
|
return Promise.reject(res)
|
||||||
|
|
||||||
|
}).finally(() => { // finally 是 then结束后再执行, 此处不适用。 需要在请求完成后立马调用: reqFinishFunc()
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 默认 显示loading(控制 xxs 内 不提示loading )
|
||||||
|
function req(uri, data, method = "GET", showLoading = true, extParams = {}) {
|
||||||
|
// headerObject[appConfig.tokenKey] = storageManage.token()
|
||||||
|
return commonsProcess(showLoading, () => {
|
||||||
|
return uni.request(
|
||||||
|
Object.assign({
|
||||||
|
url: baseUrl + uri,
|
||||||
|
data: data,
|
||||||
|
method: method,
|
||||||
|
header: getHeader()
|
||||||
|
}, extParams)
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 默认 显示loading(控制 xxs 内 不提示loading )
|
||||||
|
function request(args) {
|
||||||
|
const {
|
||||||
|
url,
|
||||||
|
data,
|
||||||
|
params,
|
||||||
|
method = "GET",
|
||||||
|
showLoading = true,
|
||||||
|
extParams = {}
|
||||||
|
} = args
|
||||||
|
let headerObject = {}
|
||||||
|
// headerObject[appConfig.tokenKey] = storageManage.token()
|
||||||
|
|
||||||
|
return commonsProcess(showLoading, () => {
|
||||||
|
return uni.request(
|
||||||
|
Object.assign({
|
||||||
|
url: baseUrl + url,
|
||||||
|
data: params||data,
|
||||||
|
method: method,
|
||||||
|
header: getHeader()
|
||||||
|
}, extParams)
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// 上传
|
||||||
|
function upload(uri, data, file, showLoading = true, extParams = {}) {
|
||||||
|
// 放置token
|
||||||
|
let headerObject = {}
|
||||||
|
// headerObject[appConfig.tokenKey] = storageManage.token()
|
||||||
|
|
||||||
|
return commonsProcess(showLoading, () => {
|
||||||
|
return uni.uploadFile(
|
||||||
|
Object.assign({
|
||||||
|
url: baseUrl + uri,
|
||||||
|
formData: data,
|
||||||
|
name: "file",
|
||||||
|
filePath: file.path,
|
||||||
|
header: getHeader()
|
||||||
|
}, extParams)
|
||||||
|
).then((httpData) => {
|
||||||
|
// uni.upload 返回bodyData 的是 string类型。 需要解析。
|
||||||
|
httpData.data = JSON.parse(httpData.data)
|
||||||
|
return Promise.resolve(httpData)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export default {
|
||||||
|
req: req,
|
||||||
|
request,
|
||||||
|
upload: upload
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,51 @@
|
||||||
|
import http from './http.js'
|
||||||
|
const request=http.request
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 店铺二维码支付
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export function createOrder(data) {
|
||||||
|
return request({
|
||||||
|
url: `/pay/createOrder`,
|
||||||
|
method: 'post',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取支付宝userId 或 微信openId
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export function getOpenId(params) {
|
||||||
|
return request({
|
||||||
|
url: `/pay/openId`,
|
||||||
|
method: 'get',
|
||||||
|
params
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取订单信息
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export function orderorderInfo(params) {
|
||||||
|
return request({
|
||||||
|
url: `/pay/noToken/queryOrderInfo`,
|
||||||
|
method: 'get',
|
||||||
|
params
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 取消支付
|
||||||
|
* @param {Object} data
|
||||||
|
*/
|
||||||
|
export function cancelOrderPay(data) {
|
||||||
|
return request({
|
||||||
|
url: `/notify/cancel`,
|
||||||
|
method: 'post',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,14 @@
|
||||||
|
该文件夹内放置: 项目自建资源, 比如 公共样式文件, 和 工具包等文件。
|
||||||
|
|
||||||
|
|
||||||
|
目录结构:
|
||||||
|
commons
|
||||||
|
style
|
||||||
|
utils
|
||||||
|
|
||||||
|
知识点: 样式文件不应该放置到 static文件夹内(css、less/scss 等资源不要放在 static 目录下,建议这些公用的资源放在自建的 common 目录下。), 详见:
|
||||||
|
https://uniapp.dcloud.net.cn/tutorial/project.html
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -0,0 +1,378 @@
|
||||||
|
.u-relative,
|
||||||
|
.u-rela {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.u-absolute,
|
||||||
|
.u-abso {
|
||||||
|
position: absolute;
|
||||||
|
}
|
||||||
|
.u-fixed,.u-fix{
|
||||||
|
position: fixed;
|
||||||
|
}
|
||||||
|
.left-top{
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
}
|
||||||
|
.u-overflow-hide{
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
// nvue不能用标签命名样式,不能放在微信组件中,否则微信开发工具会报警告,无法使用标签名当做选择器
|
||||||
|
/* #ifndef APP-NVUE */
|
||||||
|
image {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 在weex,也即nvue中,所有元素默认为border-box
|
||||||
|
view,
|
||||||
|
text {
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
/* #endif */
|
||||||
|
|
||||||
|
.u-font-xs {
|
||||||
|
font-size: 22rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.u-font-sm {
|
||||||
|
font-size: 26rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.u-font-md {
|
||||||
|
font-size: 28rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.u-font-lg {
|
||||||
|
font-size: 30rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.u-font-xl {
|
||||||
|
font-size: 34rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.u-flex {
|
||||||
|
/* #ifndef APP-NVUE */
|
||||||
|
display: flex;
|
||||||
|
/* #endif */
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.u-flex-wrap {
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.u-flex-nowrap {
|
||||||
|
flex-wrap: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.u-col-center {
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.u-col-top {
|
||||||
|
align-items: flex-start;
|
||||||
|
}
|
||||||
|
|
||||||
|
.u-col-bottom {
|
||||||
|
align-items: flex-end;
|
||||||
|
}
|
||||||
|
|
||||||
|
.u-row-center {
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.u-row-left {
|
||||||
|
justify-content: flex-start;
|
||||||
|
}
|
||||||
|
|
||||||
|
.u-row-right {
|
||||||
|
justify-content: flex-end;
|
||||||
|
}
|
||||||
|
|
||||||
|
.u-row-between {
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
|
||||||
|
.u-row-around {
|
||||||
|
justify-content: space-around;
|
||||||
|
}
|
||||||
|
|
||||||
|
.u-text-left {
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.u-text-center {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.u-text-right {
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.u-flex-col {
|
||||||
|
/* #ifndef APP-NVUE */
|
||||||
|
display: flex!important;
|
||||||
|
/* #endif */
|
||||||
|
flex-direction: column!important;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 定义flex等分
|
||||||
|
@for $i from 0 through 12 {
|
||||||
|
.u-flex-#{$i} {
|
||||||
|
flex: $i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 定义字体(px)单位,小于20都为px单位字体
|
||||||
|
@for $i from 9 to 20 {
|
||||||
|
.u-font-#{$i} {
|
||||||
|
font-size: $i + px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 定义字体(rpx)单位,大于或等于20的都为rpx单位字体
|
||||||
|
@for $i from 20 through 40 {
|
||||||
|
.u-font-#{$i} {
|
||||||
|
font-size: $i + rpx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 定义内外边距,历遍1-80
|
||||||
|
@for $i from 0 through 80 {
|
||||||
|
// 只要双数和能被5除尽的数
|
||||||
|
@if $i % 2 == 0 or $i % 5 == 0 {
|
||||||
|
// 得出:u-margin-30或者u-m-30
|
||||||
|
.u-margin-#{$i}, .u-m-#{$i} {
|
||||||
|
margin: $i + rpx!important;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 得出:u-padding-30或者u-p-30
|
||||||
|
.u-padding-#{$i}, .u-p-#{$i} {
|
||||||
|
padding: $i + rpx!important;
|
||||||
|
}
|
||||||
|
|
||||||
|
@each $short, $long in l left, t top, r right, b bottom {
|
||||||
|
// 缩写版,结果如: u-m-l-30
|
||||||
|
// 定义外边距
|
||||||
|
.u-m-#{$short}-#{$i} {
|
||||||
|
margin-#{$long}: $i + rpx!important;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 定义内边距
|
||||||
|
.u-p-#{$short}-#{$i} {
|
||||||
|
padding-#{$long}: $i + rpx!important;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 完整版,结果如:u-margin-left-30
|
||||||
|
// 定义外边距
|
||||||
|
.u-margin-#{$long}-#{$i} {
|
||||||
|
margin-#{$long}: $i + rpx!important;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 定义内边距
|
||||||
|
.u-padding-#{$long}-#{$i} {
|
||||||
|
padding-#{$long}: $i + rpx!important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 重置nvue的默认关于flex的样式
|
||||||
|
.u-reset-nvue {
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* start--文本行数限制--start */
|
||||||
|
.u-line-1 {
|
||||||
|
overflow: hidden;
|
||||||
|
white-space: nowrap;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
}
|
||||||
|
|
||||||
|
.u-line-2 {
|
||||||
|
-webkit-line-clamp: 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.u-line-3 {
|
||||||
|
-webkit-line-clamp: 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
.u-line-4 {
|
||||||
|
-webkit-line-clamp: 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
.u-line-5 {
|
||||||
|
-webkit-line-clamp: 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.u-line-2, .u-line-3, .u-line-4, .u-line-5 {
|
||||||
|
overflow: hidden;
|
||||||
|
word-break: break-all;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
display: -webkit-box; // 弹性伸缩盒
|
||||||
|
-webkit-box-orient: vertical; // 设置伸缩盒子元素排列方式
|
||||||
|
}
|
||||||
|
|
||||||
|
/* end--文本行数限制--end */
|
||||||
|
|
||||||
|
|
||||||
|
/* start--不同颜色文字--start */
|
||||||
|
.color-333{
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
.color-666{
|
||||||
|
color: #666;
|
||||||
|
}
|
||||||
|
.color-999{
|
||||||
|
color: #999;
|
||||||
|
}
|
||||||
|
.color-red{
|
||||||
|
color: $my-red-color;
|
||||||
|
}
|
||||||
|
.color-main{
|
||||||
|
color:$my-main-color
|
||||||
|
}
|
||||||
|
|
||||||
|
/* end--不同颜色文字--end */
|
||||||
|
|
||||||
|
|
||||||
|
.tranistion{
|
||||||
|
transition: all .3s ease-in-out;
|
||||||
|
}
|
||||||
|
.tranistion-1{
|
||||||
|
transition: all .1s ease-in-out;
|
||||||
|
}
|
||||||
|
.tranistion-2{
|
||||||
|
transition: all .2s ease-in-out;
|
||||||
|
}
|
||||||
|
.font-bold{
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* start--不同颜色背景--start */
|
||||||
|
.my-bg-main{
|
||||||
|
background-color:$my-main-color
|
||||||
|
}
|
||||||
|
|
||||||
|
/* end--不同颜色背景--end */
|
||||||
|
|
||||||
|
.safe-page{
|
||||||
|
padding-bottom: 60rpx!important;
|
||||||
|
}
|
||||||
|
::v-deep .uni-switch-input.uni-switch-input-checked{
|
||||||
|
border-color: $my-main-color;
|
||||||
|
background-color: $my-main-color;
|
||||||
|
}
|
||||||
|
.min-page{
|
||||||
|
/* #ifdef H5 */
|
||||||
|
min-height: calc(100vh - 44px);
|
||||||
|
/* #endif */
|
||||||
|
/* #ifndef H5 */
|
||||||
|
min-height: 100vh;
|
||||||
|
/* #endif */
|
||||||
|
}
|
||||||
|
.w-full{
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
.gap-20{
|
||||||
|
gap: 20rpx;
|
||||||
|
}
|
||||||
|
.color-000{
|
||||||
|
color: #000;
|
||||||
|
}
|
||||||
|
.color-fff{
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
.bg-fff{
|
||||||
|
background-color: #fff;
|
||||||
|
}
|
||||||
|
.bg-gray{
|
||||||
|
background-color: #F9F9F9;
|
||||||
|
}
|
||||||
|
.overflow-hide{
|
||||||
|
/* #ifdef H5 */
|
||||||
|
height: calc(100vh - 44px);
|
||||||
|
/* #endif */
|
||||||
|
/* #ifndef H5 */
|
||||||
|
height: 100vh;
|
||||||
|
/* #endif */
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
.no-wrap{
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
.border-r-12{
|
||||||
|
border-radius: 12rpx;
|
||||||
|
}
|
||||||
|
.border-r-18{
|
||||||
|
border-radius: 18rpx;
|
||||||
|
}
|
||||||
|
.border-top{
|
||||||
|
border-top: 1px solid #E5E5E5;
|
||||||
|
}
|
||||||
|
.border-bottom{
|
||||||
|
border-bottom: 1px solid #E5E5E5;
|
||||||
|
}
|
||||||
|
.scale7{
|
||||||
|
transform: scale(0.7);
|
||||||
|
}
|
||||||
|
.page-gray {
|
||||||
|
min-height: calc(100vh);
|
||||||
|
/* #ifdef H5 */
|
||||||
|
min-height: calc(100vh - var(--window-top));
|
||||||
|
/* #endif */
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
background: #F9F9F9;
|
||||||
|
}
|
||||||
|
|
||||||
|
.safe-bottom{
|
||||||
|
padding-bottom: env(safe-area-inset-bottom);
|
||||||
|
/* #ifdef H5 */
|
||||||
|
padding-bottom: 28rpx;
|
||||||
|
/* #endif */
|
||||||
|
}
|
||||||
|
.position-all{
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
top: 0;
|
||||||
|
bottom: 0;
|
||||||
|
}
|
||||||
|
.fixed-top{
|
||||||
|
position: fixed;
|
||||||
|
/* #ifdef H5 */
|
||||||
|
top: 44px;
|
||||||
|
/* #endif */
|
||||||
|
/* #ifndef H5 */
|
||||||
|
top: 0;
|
||||||
|
/* #endif */
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
}
|
||||||
|
.lh30 {
|
||||||
|
line-height: 30px;
|
||||||
|
}
|
||||||
|
.default-box-padding{
|
||||||
|
padding: 32rpx 28rpx;
|
||||||
|
}
|
||||||
|
.icon-arrow-down-fill {
|
||||||
|
width: 16rpx;
|
||||||
|
height: 10rpx;
|
||||||
|
}
|
||||||
|
.zIndex-999{
|
||||||
|
z-index: 999;
|
||||||
|
}
|
||||||
|
.icon-default-size{
|
||||||
|
width: 28rpx;
|
||||||
|
height: 28rpx;
|
||||||
|
}
|
||||||
|
::v-deep.uni-easyinput__placeholder-class{
|
||||||
|
font-size: 28rpx!important;
|
||||||
|
}
|
||||||
|
.filter-gray{
|
||||||
|
filter: grayscale(1);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,230 @@
|
||||||
|
/**
|
||||||
|
* 系统级别: 全局样式
|
||||||
|
*
|
||||||
|
* @site https://www.jeequan.com
|
||||||
|
* @date 2022/11/22 07:29
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** 已整理 **/
|
||||||
|
|
||||||
|
|
||||||
|
// 通用 列表页样式
|
||||||
|
.page-wrapper {
|
||||||
|
min-height: calc(100vh - 70rpx); /** 最小高度 **/
|
||||||
|
padding-bottom: 70rpx; /** 安全距离(防止home条遮挡文字) **/
|
||||||
|
background-color: $v-color-bgrey; /** 全局背景灰 **/
|
||||||
|
}
|
||||||
|
|
||||||
|
// 底部 固定的按钮, 比如: 创建门店, 创建员工等按钮。
|
||||||
|
.list-footer{
|
||||||
|
height: 100rpx;
|
||||||
|
background: transparent;
|
||||||
|
.button-wrapper {
|
||||||
|
border-top: 1rpx solid rgba(0,0,0, 0.07);
|
||||||
|
background-color: rgba(252, 252, 252, 0.85);
|
||||||
|
backdrop-filter: blur(20rpx);
|
||||||
|
position: fixed;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
padding: 30rpx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** 详情页 覆写:list-item */
|
||||||
|
.list-item-by-detail {
|
||||||
|
padding: 60rpx 60rpx 10rpx 60rpx !important;
|
||||||
|
background-color: transparent !important; /** 背景透明 **/
|
||||||
|
.list-title{
|
||||||
|
color: #fff !important;
|
||||||
|
}
|
||||||
|
.list-subtitle{
|
||||||
|
color: rgba(251,252,253,0.7) !important;
|
||||||
|
}
|
||||||
|
.list-info {
|
||||||
|
image {
|
||||||
|
margin-right: 0 !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**列表条目渲染, 比如: 头像、 主标题, **/
|
||||||
|
.list-item {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
padding: 0 40rpx;
|
||||||
|
height: 170rpx;
|
||||||
|
background-color: #FFF; /** 背景 白色 **/
|
||||||
|
image {
|
||||||
|
flex-shrink: 0;
|
||||||
|
flex-grow: 0;
|
||||||
|
width: 100rpx;
|
||||||
|
height: 100rpx;
|
||||||
|
margin-right: 30rpx;
|
||||||
|
}
|
||||||
|
.list-info {
|
||||||
|
flex: 1;
|
||||||
|
.list-title {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
height: 40rpx;
|
||||||
|
color: rgba(77,77,77,1);
|
||||||
|
.list-name {
|
||||||
|
width: auto;
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
font-size: 30rpx;
|
||||||
|
font-weight: 400;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.list-subtitle {
|
||||||
|
color: rgba(153, 153, 153, 1);
|
||||||
|
margin-top: 25rpx;
|
||||||
|
font-size: 26rpx;
|
||||||
|
font-weight: 400;
|
||||||
|
width: 430rpx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** 状态小圆点 **/
|
||||||
|
.state-dot {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
font-size: 30rpx;
|
||||||
|
font-weight: 400;
|
||||||
|
&::after {
|
||||||
|
content: '';
|
||||||
|
display: block;
|
||||||
|
margin-left: 20rpx;
|
||||||
|
width: 20rpx;
|
||||||
|
height: 20rpx;
|
||||||
|
border-radius: 50%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 状态小圆点 **/
|
||||||
|
.state-dot-enable {
|
||||||
|
&::after {
|
||||||
|
background-color: #168FFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 状态小圆点 **/
|
||||||
|
.state-dot-disable {
|
||||||
|
&::after {
|
||||||
|
background-color: #D9D9D9;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 状态小圆点 **/
|
||||||
|
.state-dot-error {
|
||||||
|
&::after {
|
||||||
|
background-color: red;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 描述预览图, 参考: app详情
|
||||||
|
* 第一个最后一个距离上下 40rpx, 中间间距20rpx
|
||||||
|
*/
|
||||||
|
.desc-view {
|
||||||
|
.desc-view-item {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
padding: 20rpx 40rpx;
|
||||||
|
font-size: 30rpx;
|
||||||
|
font-weight: 400;
|
||||||
|
|
||||||
|
.title {
|
||||||
|
color: #808080;
|
||||||
|
}
|
||||||
|
.desc {
|
||||||
|
color: #000;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:first-child {
|
||||||
|
margin-top: 20rpx;
|
||||||
|
}
|
||||||
|
&:last-child {
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 已整理 **/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//容器内部元素上下左右居中
|
||||||
|
.flex-center {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
// 触摸反馈样式
|
||||||
|
.touch-hover {
|
||||||
|
background-color: #f7f8fa !important ;
|
||||||
|
}
|
||||||
|
.touch-button {
|
||||||
|
opacity: 0.5;
|
||||||
|
}
|
||||||
|
/* 单行文本超出省略号 */
|
||||||
|
.single-text-beyond {
|
||||||
|
overflow: hidden; /*超出部分隐藏*/
|
||||||
|
white-space: nowrap; /*禁止换行*/
|
||||||
|
text-overflow: ellipsis; /*省略号*/
|
||||||
|
}
|
||||||
|
// 按钮背景样式
|
||||||
|
.footer-button-style {
|
||||||
|
border-top: 1rpx solid #fcfcfc;
|
||||||
|
background-color: rgba(252, 252, 252, 0.85);
|
||||||
|
backdrop-filter: blur(20rpx);
|
||||||
|
}
|
||||||
|
// 搜素框 提示语样式
|
||||||
|
.input-placeholder {
|
||||||
|
font-size: 32rpx;
|
||||||
|
color: rgba(0, 0, 0, 0.35);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 表单分割线
|
||||||
|
.line {
|
||||||
|
height: 20rpx;
|
||||||
|
background-color: $v-color-bgrey;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* jeepay-btn 通用btn样式。
|
||||||
|
* 用法: <button class='jeepay-btn' hover-class="hover-button" @tap="loginFunc">登录</button>
|
||||||
|
*/
|
||||||
|
.jeepay-btn {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
height: 110rpx;
|
||||||
|
font-size: 33rpx;
|
||||||
|
font-weight: 500;
|
||||||
|
color: $J-color-tff;
|
||||||
|
border-radius: 20rpx;
|
||||||
|
background: linear-gradient(270deg, rgba(35,143,252,1) 0%, rgba(26,102,255,1) 100%);
|
||||||
|
box-shadow: 0 20rpx 60rpx -20rpx rgba(0,84,210,0.5);
|
||||||
|
&.hover-button {
|
||||||
|
opacity: 0.5;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 输入框icon **/
|
||||||
|
.input-icon{
|
||||||
|
width: 36rpx;
|
||||||
|
height: 36rpx;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,181 @@
|
||||||
|
/**
|
||||||
|
* 系统级别:覆写 uni样式
|
||||||
|
*
|
||||||
|
* @site https://www.jeequan.com
|
||||||
|
* @date 2022/11/22 07:29
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* 去除开关右侧边距 */
|
||||||
|
.uni-switch-input {
|
||||||
|
margin-right: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* .uni-navbar {
|
||||||
|
position: relative;
|
||||||
|
z-index: 10;
|
||||||
|
} */
|
||||||
|
.uni-popup{
|
||||||
|
z-index: 998 !important;
|
||||||
|
}
|
||||||
|
// 表单组件样式 覆写
|
||||||
|
.uni-forms-item {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
min-height: 120rpx;
|
||||||
|
background-color: $J-bg-ff;
|
||||||
|
font-size: 32rpx;
|
||||||
|
font-weight: 400;
|
||||||
|
}
|
||||||
|
.uni-forms-item ::v-deep .uni-forms-item__label {
|
||||||
|
font-size: 32rpx !important;
|
||||||
|
font-weight: 400;
|
||||||
|
text-indent: 40rpx;
|
||||||
|
color: #4d4d4d;
|
||||||
|
height: auto !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
// uni-form-item 表单校验, 如果校验不通过, 显示的文字占位, 并且添加下边距。
|
||||||
|
.uni-forms-item__error.msg--active{
|
||||||
|
position: relative !important;
|
||||||
|
margin-bottom: 30rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.is-input-error-border .uni-easyinput__placeholder-class{
|
||||||
|
color: #f56c6c !important
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 去掉按钮边框
|
||||||
|
button:after {
|
||||||
|
border: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 去点导航栏组件center&right
|
||||||
|
::v-deep.uni-navbar__header {
|
||||||
|
.uni-navbar__header-container,
|
||||||
|
.uni-navbar__header-btns-right {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 修改 uuni-easyinput
|
||||||
|
// form 外层必须包裹一个 view class="jeepay-form"
|
||||||
|
.jeepay-form {
|
||||||
|
.uni-easyinput {
|
||||||
|
.uni-easyinput__content {
|
||||||
|
border: 2px solid transparent !important;
|
||||||
|
height: 110rpx;
|
||||||
|
padding: 0 30rpx;
|
||||||
|
margin-bottom: 50rpx;
|
||||||
|
box-sizing: border-box !important;
|
||||||
|
border-radius: 20rpx !important;
|
||||||
|
background-color: rgba(247, 247, 247, 1) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-easyinput__content-input {
|
||||||
|
color: rgba(0, 0, 0, 1);
|
||||||
|
font-size: 32rpx !important;
|
||||||
|
font-weight: 400;
|
||||||
|
}
|
||||||
|
|
||||||
|
.is-foucs {
|
||||||
|
border: 2px solid #1d79fd !important;
|
||||||
|
background-color: white !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-input-placeholder
|
||||||
|
/* #ifdef MP-WEIXIN */
|
||||||
|
,.uni-easyinput__placeholder-class
|
||||||
|
/* #endif */ {
|
||||||
|
font-size: 32rpx !important;
|
||||||
|
color: #B3B3B3 !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.jeepay-edit-form .uni-easyinput__content-input {
|
||||||
|
padding-left: 0 !important;
|
||||||
|
.uni-input-placeholder {
|
||||||
|
font-size: 32rpx !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置新密码覆盖form默认样式
|
||||||
|
.new-password {
|
||||||
|
.uni-forms-item.is-direction-left {
|
||||||
|
padding: 0 40rpx;
|
||||||
|
.uni-forms-item__label {
|
||||||
|
width: 190rpx !important;
|
||||||
|
font-size: 32rpx !important;
|
||||||
|
font-weight: 400;
|
||||||
|
white-space: nowrap;
|
||||||
|
color: rgba(102, 102, 102, 1);
|
||||||
|
text-indent: 0 !important;
|
||||||
|
}
|
||||||
|
.uni-easyinput__placeholder-class {
|
||||||
|
font-size: 32rpx !important;
|
||||||
|
font-weight: 400 !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 搜索栏覆盖默认样式
|
||||||
|
/* #ifdef MP-WEIXIN */
|
||||||
|
.input-main {
|
||||||
|
button {
|
||||||
|
font-size: 32rpx;
|
||||||
|
color: rgba(29,121,253,1);
|
||||||
|
background: rgba(255,255,255,1);
|
||||||
|
}
|
||||||
|
.uni-easyinput {
|
||||||
|
.uni-easyinput__content {
|
||||||
|
background-color: $J-bg-f5 !important;
|
||||||
|
border-radius: $J-b-r12;
|
||||||
|
.uni-easyinput__content-input {
|
||||||
|
padding-left: 0 !important;
|
||||||
|
.uni-input-input {
|
||||||
|
border-radius: $J-b-r12 !important;
|
||||||
|
overflow: hidden !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.uni-input-placeholder {
|
||||||
|
font-size: 27rpx;
|
||||||
|
}
|
||||||
|
.uni-icons {
|
||||||
|
color: rgba(230,230,230,1) !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* #endif */
|
||||||
|
|
||||||
|
// 搜索栏覆盖默认样式
|
||||||
|
/* #ifdef MP-WEIXIN */
|
||||||
|
button[is="components/Button/Button"] {
|
||||||
|
padding: 0;
|
||||||
|
background-color: transparent !important;
|
||||||
|
}
|
||||||
|
/* #endif */
|
||||||
|
|
||||||
|
// 修改时间选择器按钮颜色
|
||||||
|
.xp-button--confirm {
|
||||||
|
background: $jeepay-bg-primary;
|
||||||
|
}
|
||||||
|
.xp-button--cancel {
|
||||||
|
color: rgba(0, 0, 0, 0.5) !important;
|
||||||
|
}
|
||||||
|
// label 样式
|
||||||
|
.f-label{
|
||||||
|
width: 280rpx;
|
||||||
|
align-self: start;
|
||||||
|
padding-top: 40rpx;
|
||||||
|
font-size: 32rpx ;
|
||||||
|
font-weight: 400;
|
||||||
|
text-indent: 40rpx;
|
||||||
|
color: #4d4d4d;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -0,0 +1,77 @@
|
||||||
|
/**
|
||||||
|
* 系统级别: 自定义变量
|
||||||
|
*
|
||||||
|
* @site https://www.jeequan.com
|
||||||
|
* @date 2022/11/22 07:29
|
||||||
|
*/
|
||||||
|
|
||||||
|
// $v : 表示: variables简写。 uni的默认都有特殊开头, 一般不会重复。
|
||||||
|
$v-color-t21: #217dfe;
|
||||||
|
|
||||||
|
// 全局通用: 背景灰 background grey
|
||||||
|
$v-color-bgrey: #F7F7F7;
|
||||||
|
|
||||||
|
// 背景色
|
||||||
|
$J-bg-f7: #f7f7f7; //页面背景色
|
||||||
|
$J-bg-ff: #fff;
|
||||||
|
$J-bg-f5: #f5f5f5; //输入框背景色
|
||||||
|
|
||||||
|
// 文字颜色
|
||||||
|
$J-color-t80: #808080; //常用于 未选中文字颜色
|
||||||
|
$J-color-t21: #217dfe; //卡片文字选中 统计报表
|
||||||
|
$J-color-tff: #fff;
|
||||||
|
$J-color-tSff: rgba(255, 255, 255, 0.7);
|
||||||
|
$J-color-t29: #2980fd; //选中 文字颜色 搜索
|
||||||
|
$J-color-ta6: #a6a6a6;
|
||||||
|
$J-color-t4d: #4d4d4d; //标题颜色
|
||||||
|
$J-color-t99: #999;
|
||||||
|
$J-color-t8c: #8c8c8c; // 卡片列表 标题文字颜色
|
||||||
|
//圆角相关变量
|
||||||
|
$J-b-r32: 32rpx;
|
||||||
|
$J-b-r12: 12rpx;
|
||||||
|
$J-b-r10: 10rpx;
|
||||||
|
$v-b-r20: 20rpx;
|
||||||
|
|
||||||
|
// 文字大小
|
||||||
|
$J-f-size30: 30rpx;
|
||||||
|
|
||||||
|
// 常用边框颜色
|
||||||
|
$v-b-color-ed: #ededed;
|
||||||
|
|
||||||
|
//common.scss 分包页面以及组件里所用的颜色
|
||||||
|
$my-main-color:#318AFE;
|
||||||
|
$my-red-color:#F02C45;
|
||||||
|
|
||||||
|
//my-components
|
||||||
|
$u-main-color: #303133;
|
||||||
|
$u-content-color: #606266;
|
||||||
|
$u-tips-color: #909193;
|
||||||
|
$u-light-color: #c0c4cc;
|
||||||
|
$u-border-color: #dadbde;
|
||||||
|
$u-bg-color: #f3f4f6;
|
||||||
|
$u-disabled-color: #c8c9cc;
|
||||||
|
|
||||||
|
$u-primary: #3c9cff;
|
||||||
|
$u-primary-dark: #398ade;
|
||||||
|
$u-primary-disabled: #9acafc;
|
||||||
|
$u-primary-light: #ecf5ff;
|
||||||
|
|
||||||
|
$u-warning: #f9ae3d;
|
||||||
|
$u-warning-dark: #f1a532;
|
||||||
|
$u-warning-disabled: #f9d39b;
|
||||||
|
$u-warning-light: #fdf6ec;
|
||||||
|
|
||||||
|
$u-success: #5ac725;
|
||||||
|
$u-success-dark: #53c21d;
|
||||||
|
$u-success-disabled: #a9e08f;
|
||||||
|
$u-success-light: #f5fff0;
|
||||||
|
|
||||||
|
$u-error: #f56c6c;
|
||||||
|
$u-error-dark: #e45656;
|
||||||
|
$u-error-disabled: #f7b2b2;
|
||||||
|
$u-error-light: #fef0f0;
|
||||||
|
|
||||||
|
$u-info: #909399;
|
||||||
|
$u-info-dark: #767a82;
|
||||||
|
$u-info-disabled: #c4c6c9;
|
||||||
|
$u-info-light: #f4f4f5;
|
||||||
|
|
@ -0,0 +1,37 @@
|
||||||
|
/**
|
||||||
|
* 数字, 计算相关函数
|
||||||
|
*
|
||||||
|
* @author terrfly
|
||||||
|
* @site https://www.jeepay.vip
|
||||||
|
* @date 2022/11/22 10:38
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 保留小数n位,不进行四舍五入
|
||||||
|
* num你传递过来的数字,
|
||||||
|
* decimal你保留的几位,默认保留小数后两位
|
||||||
|
*/
|
||||||
|
const formatDecimal = function(num, decimal = 2) {
|
||||||
|
num = num.toString()
|
||||||
|
const index = num.indexOf('.')
|
||||||
|
if (index !== -1) {
|
||||||
|
num = num.substring(0, decimal + index + 1)
|
||||||
|
} else {
|
||||||
|
num = num.substring(0)
|
||||||
|
}
|
||||||
|
//截取后保留两位小数
|
||||||
|
return parseFloat(num).toFixed(decimal)
|
||||||
|
}
|
||||||
|
|
||||||
|
const model = {
|
||||||
|
// 分转元
|
||||||
|
// amount - 金额 parseFloat - 是否转换为数字格式, 默认String
|
||||||
|
cert2Dollar(amount, needParseFloat = false) {
|
||||||
|
if (needParseFloat) { // parseFlot
|
||||||
|
return formatDecimal(amount / 100)
|
||||||
|
}
|
||||||
|
return formatDecimal(amount / 100)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default model
|
||||||
|
|
@ -0,0 +1,38 @@
|
||||||
|
/**
|
||||||
|
* 数据 工具类
|
||||||
|
*
|
||||||
|
* @author terrfly
|
||||||
|
* @site https://www.jeepay.vip
|
||||||
|
* @date 2022/11/30 14:18
|
||||||
|
*/
|
||||||
|
|
||||||
|
const model = {
|
||||||
|
|
||||||
|
// 递归遍历树状结构数据 matchFunc 匹配结果, true表示匹配成功, 否则继续匹配。
|
||||||
|
// pnode 可不传入
|
||||||
|
// 返回结构: [当前数据, 上级数据 ]
|
||||||
|
recursionTreeData: (treeData, matchFunc, childrenName = 'children', pnode = null ) => {
|
||||||
|
|
||||||
|
for (let i = 0; i < treeData.length; i++) {
|
||||||
|
|
||||||
|
const item = treeData[i]
|
||||||
|
|
||||||
|
// 匹配成功
|
||||||
|
if(matchFunc(item)){
|
||||||
|
return [item, pnode]
|
||||||
|
}
|
||||||
|
|
||||||
|
if (item[childrenName] && item[childrenName].length > 0) {
|
||||||
|
let res = model.recursionTreeData(item[childrenName], matchFunc, childrenName, item)
|
||||||
|
if(res){
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export default model
|
||||||
|
|
||||||
|
|
@ -0,0 +1,72 @@
|
||||||
|
/**
|
||||||
|
* 加解密工具包
|
||||||
|
*
|
||||||
|
* @author terrfly
|
||||||
|
* @site https://www.jeepay.vip
|
||||||
|
* @date 2021/5/16 17:35
|
||||||
|
*/
|
||||||
|
import { SM4 } from 'gm-crypto'
|
||||||
|
import appConfig from '@/config/appConfig.js'
|
||||||
|
|
||||||
|
let HEX_KEY = null
|
||||||
|
|
||||||
|
// 字符串转16进制
|
||||||
|
function str2hex(str) {
|
||||||
|
var val = ''
|
||||||
|
for (var i = 0; i < str.length; i++) {
|
||||||
|
if (val == '')
|
||||||
|
val = str.charCodeAt(i).toString(16)
|
||||||
|
else
|
||||||
|
val += str.charCodeAt(i).toString(16)
|
||||||
|
}
|
||||||
|
val += ''
|
||||||
|
return val
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取hex秘钥
|
||||||
|
function getHexKey(){
|
||||||
|
|
||||||
|
if(!HEX_KEY){
|
||||||
|
|
||||||
|
HEX_KEY = str2hex(appConfig.encryptKey)
|
||||||
|
|
||||||
|
}
|
||||||
|
return HEX_KEY
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 解密 (http响应数据, 做通用处理)
|
||||||
|
export function sm4DecryptByResData(data){
|
||||||
|
|
||||||
|
if(!data){
|
||||||
|
return data
|
||||||
|
}
|
||||||
|
|
||||||
|
let res = SM4.decrypt(data, getHexKey(), {
|
||||||
|
inputEncoding: 'base64',
|
||||||
|
outputEncoding: 'utf8'
|
||||||
|
})
|
||||||
|
|
||||||
|
if(!res){
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
return JSON.parse(res)['originData']
|
||||||
|
}
|
||||||
|
|
||||||
|
// 加密 (http响应数据, 做通用处理)
|
||||||
|
export function sm4EncryptByReqData(data){
|
||||||
|
|
||||||
|
if(!data){
|
||||||
|
return data
|
||||||
|
}
|
||||||
|
|
||||||
|
// 加密处理
|
||||||
|
let encryptData = SM4.encrypt(JSON.stringify(data), getHexKey(), {
|
||||||
|
inputEncoding: 'utf8',
|
||||||
|
outputEncoding: 'base64'
|
||||||
|
})
|
||||||
|
|
||||||
|
return {encryptData : encryptData}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -0,0 +1,101 @@
|
||||||
|
/**
|
||||||
|
* form 验证 工具类
|
||||||
|
*
|
||||||
|
* @author terrfly
|
||||||
|
* @site https://www.jeepay.vip
|
||||||
|
* @date 2022/11/25 10:58
|
||||||
|
*/
|
||||||
|
|
||||||
|
import infoBox from '@/commons/utils/infoBox.js'
|
||||||
|
|
||||||
|
const model = {
|
||||||
|
|
||||||
|
|
||||||
|
// 正则表达式
|
||||||
|
regexp: {
|
||||||
|
|
||||||
|
// 手机号验证规则
|
||||||
|
mobile: /^1\d{10}$/,
|
||||||
|
|
||||||
|
// 登录用户名: 字母开头 6 -18位。
|
||||||
|
loginUsername: /^[a-zA-Z][a-zA-Z0-9]{5,17}$/,
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
// 验证规则:
|
||||||
|
rules: {
|
||||||
|
|
||||||
|
// showText 为空, 说明是 input的placeHoloder 直接飘红,
|
||||||
|
// showText 有值: 在文本框下方提示。
|
||||||
|
// 只有input 才有这种特殊判断。
|
||||||
|
requiredInput: (showText, type = 'string') => {
|
||||||
|
return {format: type, required: true, errorMessage: showText ? ('请输入' + showText) : ' ' }
|
||||||
|
},
|
||||||
|
|
||||||
|
requiredSelect: (showText, type = 'string') => {
|
||||||
|
return {format: type, required: true, errorMessage: '请选择' + showText }
|
||||||
|
},
|
||||||
|
|
||||||
|
requiredUpload: (showText, type = 'string') => {
|
||||||
|
return {format: type, required: true, errorMessage: '请上传' + showText }
|
||||||
|
},
|
||||||
|
|
||||||
|
// 正则验证 , 请注意: 该规则需要在required后面, 此处不可包含required
|
||||||
|
patternRule: (showText, p) => {
|
||||||
|
return {pattern: p, errorMessage: '请输入正确的' + showText }
|
||||||
|
},
|
||||||
|
|
||||||
|
requiredInputShowToast: (showText, type = 'string') => {
|
||||||
|
return {format: type, required: true, errorMessage:' ', toastErrorMessage: '请输入' + showText }
|
||||||
|
},
|
||||||
|
|
||||||
|
requiredSelectShowToast: (showText, type = 'string') => {
|
||||||
|
return {format: type, required: true, errorMessage:' ', toastErrorMessage: '请选择' + showText }
|
||||||
|
},
|
||||||
|
|
||||||
|
requiredUploadShowToast: (showText, type = 'string') => {
|
||||||
|
return {format: type, required: true, errorMessage:' ', toastErrorMessage: '请上传' + showText }
|
||||||
|
},
|
||||||
|
|
||||||
|
patternRuleShowToast: (showText, p) => {
|
||||||
|
return {pattern: p, errorMessage:' ', toastErrorMessage: '请输入正确的' + showText }
|
||||||
|
},
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
// 支持 提示信息
|
||||||
|
// 类型如下:
|
||||||
|
// {
|
||||||
|
// required: true,
|
||||||
|
// toastErrorMessage: "请输入去去去去群",
|
||||||
|
// errorMessage: ' ', // 不会显示在下部, 需要空格占位
|
||||||
|
// }
|
||||||
|
validate: (form) => {
|
||||||
|
|
||||||
|
return form.validate().catch(e => {
|
||||||
|
|
||||||
|
if(!e || e.length <= 0){
|
||||||
|
return Promise.reject()
|
||||||
|
}
|
||||||
|
|
||||||
|
for(let i = 0; i < e.length; i++){
|
||||||
|
let k = e[i].key
|
||||||
|
let rules = form.rules[k].rules
|
||||||
|
for(let j = 0; j < rules.length; j++){
|
||||||
|
if(rules[j].toastErrorMessage && rules[j].required){
|
||||||
|
infoBox.showToast(rules[j].toastErrorMessage) // 仅提示一次即可
|
||||||
|
return Promise.reject(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Promise.reject(e)
|
||||||
|
})
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export default model
|
||||||
|
|
||||||
|
|
@ -0,0 +1,54 @@
|
||||||
|
/**
|
||||||
|
* 格式化价格函数,将价格限定在指定的最小值和最大值范围内,并保留两位小数。
|
||||||
|
*
|
||||||
|
* @param {number} price - 需要格式化的价格。
|
||||||
|
* @param {number} min - 价格的最小值。
|
||||||
|
* @param {number} max - 价格的最大值,默认为100000000。
|
||||||
|
* @param {Boolean} returnIsArea - 是否返回值符合范围区间,默认为false。
|
||||||
|
* @returns {number} - 返回格式化后的价格,如果超出范围则返回最小值或最大值。
|
||||||
|
*/
|
||||||
|
export const formatPrice = (price,min=-Infinity, max = 100000000,returnIsArea=false ) => {
|
||||||
|
if(price === undefined || price === null||price===''){
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
// 将价格转换为浮点数并保留两位小数
|
||||||
|
const newval = parseFloat((Math.floor(price * 100) / 100).toFixed(2))
|
||||||
|
// 如果价格大于最大值,返回最大值
|
||||||
|
if (newval > max) {
|
||||||
|
return returnIsArea?{value:max,error:true}:max
|
||||||
|
}
|
||||||
|
// 如果价格小于最小值,返回最小值
|
||||||
|
if (newval < min) {
|
||||||
|
return returnIsArea?{value:min,error:true}:min
|
||||||
|
}
|
||||||
|
// 如果价格小于最小值,返回最小值
|
||||||
|
if (newval < min) {
|
||||||
|
return min
|
||||||
|
}
|
||||||
|
// 返回格式化后的价格
|
||||||
|
return newval
|
||||||
|
}
|
||||||
|
export function returnReverseVal(val, isReturnString = true) {
|
||||||
|
const isBol = typeof val === "boolean";
|
||||||
|
const isString = typeof val === "string";
|
||||||
|
let reverseNewval = "";
|
||||||
|
if (isBol) {
|
||||||
|
reverseNewval = !val;
|
||||||
|
}
|
||||||
|
if (isString) {
|
||||||
|
reverseNewval = val === "true" ? "false" : "true";
|
||||||
|
}
|
||||||
|
return reverseNewval;
|
||||||
|
}
|
||||||
|
export function returnBoolean(val) {
|
||||||
|
const isBol = typeof val === "boolean";
|
||||||
|
const isString = typeof val === "string";
|
||||||
|
let newval = "";
|
||||||
|
if (isBol) {
|
||||||
|
newval = val;
|
||||||
|
}
|
||||||
|
if (isString) {
|
||||||
|
newval = val === "true" ? true : false;
|
||||||
|
}
|
||||||
|
return newval;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,32 @@
|
||||||
|
function getDayArea(date = new Date(), type) {
|
||||||
|
const now = date
|
||||||
|
if (type === 'start') {
|
||||||
|
const startOfDay = new Date(now.getFullYear(), now.getMonth(), now.getDate());
|
||||||
|
return startOfDay
|
||||||
|
}
|
||||||
|
if (type === 'end') {
|
||||||
|
const endOfDay = new Date(now.getFullYear(), now.getMonth(), now.getDate(), 23, 59, 59, 999);
|
||||||
|
return endOfDay;
|
||||||
|
}
|
||||||
|
return `${startOfDay}-${endOfDay}`
|
||||||
|
}
|
||||||
|
function getMonthArea(date = new Date(), type) {
|
||||||
|
let now = date
|
||||||
|
let currentMonthStart = new Date(now.getFullYear(), now.getMonth(), 1);
|
||||||
|
let currentMonthEnd = new Date(now.getFullYear(), now.getMonth() + 1, 0 , 23, 59, 59, 999);
|
||||||
|
if (type === 'start') {
|
||||||
|
return currentMonthStart
|
||||||
|
}
|
||||||
|
if (type === 'end') {
|
||||||
|
return currentMonthEnd;
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
start: currentMonthStart,
|
||||||
|
end: currentMonthEnd
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export default {
|
||||||
|
getDayArea, getMonthArea
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,13 @@
|
||||||
|
/**
|
||||||
|
* 获取url链接参数
|
||||||
|
* @param {Object} url
|
||||||
|
* @param {Object} name
|
||||||
|
*/
|
||||||
|
export function getQueryString(url, name) {
|
||||||
|
var reg = new RegExp('(^|&|/?)' + name + '=([^&|/?]*)(&|/?|$)', 'i')
|
||||||
|
var r = url.substr(1).match(reg)
|
||||||
|
if (r != null) {
|
||||||
|
return r[2]
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,62 @@
|
||||||
|
/**
|
||||||
|
* 提示信息公共文件
|
||||||
|
*
|
||||||
|
* @author terrfly
|
||||||
|
* @site https://www.jeequan.com
|
||||||
|
* @date 2022/11/14 15:29
|
||||||
|
*/
|
||||||
|
|
||||||
|
const model = {
|
||||||
|
|
||||||
|
// uni.showToast的封装
|
||||||
|
// 参数: 标题、 显示时长(单位: 秒), 扩展参数
|
||||||
|
// 返回: promise对象, 当提示消失后调用 resolve()
|
||||||
|
showToast: (title, duration = 1.5, extObject) => {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
uni.showToast(Object.assign({ title: title, icon: 'none', mask: true, duration: (duration * 1000) }, extObject))
|
||||||
|
setTimeout(resolve, (duration * 1000));
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
// success类型的提示
|
||||||
|
showSuccessToast: (title, duration) => {
|
||||||
|
return model.showToast(title, duration, {icon: 'success'})
|
||||||
|
},
|
||||||
|
|
||||||
|
// error类型的提示
|
||||||
|
showErrorToast: (title, duration) => {
|
||||||
|
return model.showToast(title, duration, {icon: 'error'})
|
||||||
|
},
|
||||||
|
|
||||||
|
showLoading: (title = '请稍后' ) => {
|
||||||
|
return uni.showLoading({ title: title, mask: true })
|
||||||
|
},
|
||||||
|
|
||||||
|
hideLoading: () => {
|
||||||
|
return uni.hideLoading()
|
||||||
|
},
|
||||||
|
|
||||||
|
// 返回 Promise 点击确定和取消
|
||||||
|
// APP安卓原生提示(比较丑), APP 不推荐使用该函数 。
|
||||||
|
showModal: (title, confirmText = '确定', cancalText = '取消', extObject) => {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
uni.showModal( Object.assign({
|
||||||
|
title: title,
|
||||||
|
confirmText: confirmText,
|
||||||
|
showCancel: cancalText ? true : false,
|
||||||
|
cancelText: cancalText,
|
||||||
|
success: function(r) {
|
||||||
|
if (r.confirm) {
|
||||||
|
resolve()
|
||||||
|
}else if (r.cancel) {
|
||||||
|
reject()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, extObject ));
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export default model
|
||||||
|
|
@ -0,0 +1,143 @@
|
||||||
|
import { $getBaiduToken } from '@/http/apiManager.js';
|
||||||
|
const audioTeam = [];
|
||||||
|
let audioStartSwitch = false;
|
||||||
|
const getAudioUrl = 'https://tsn.baidu.com/text2audio';
|
||||||
|
|
||||||
|
export default function openVoice(objs) { // 传入需转为语音的文本内容
|
||||||
|
let lineUp = false;
|
||||||
|
let returnAudio = false;
|
||||||
|
if (typeof(objs) !== 'string') {
|
||||||
|
if (objs && objs.lineUp === true) {
|
||||||
|
lineUp = true;
|
||||||
|
}
|
||||||
|
if (objs && objs.returnAudio === true) {
|
||||||
|
returnAudio = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(returnAudio) {
|
||||||
|
return new Promise((resolve, reject)=>{
|
||||||
|
openVoiceFc(objs, returnAudio).then(res=>{
|
||||||
|
resolve(res);
|
||||||
|
}).catch(err=>{
|
||||||
|
reject(err)
|
||||||
|
});
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!audioStartSwitch || lineUp) {
|
||||||
|
audioStartSwitch = true;
|
||||||
|
openVoiceFc(objs);
|
||||||
|
} else {
|
||||||
|
audioTeam.push(objs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function openVoiceFc(objs, returnAudio) {
|
||||||
|
if(returnAudio) {
|
||||||
|
return new Promise((resolve, reject)=>{
|
||||||
|
$getBaiduToken().then(({bizData}) => {
|
||||||
|
if (bizData) {
|
||||||
|
resolve(tts(objs, bizData, returnAudio));
|
||||||
|
} else {
|
||||||
|
reject('获取语音tok接口为空');
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}else{
|
||||||
|
$getBaiduToken().then(({bizData}) => {
|
||||||
|
if (bizData) {
|
||||||
|
tts(objs, bizData);
|
||||||
|
} else {
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function tts(objs, tok, returnAudio) {
|
||||||
|
if(typeof(objs)=='string')
|
||||||
|
objs = {voiceSet: {tex: objs}};
|
||||||
|
const data = {
|
||||||
|
tok,
|
||||||
|
cuid: tok,
|
||||||
|
ctp: 1,
|
||||||
|
lan: 'zh',
|
||||||
|
...objs.voiceSet
|
||||||
|
}
|
||||||
|
if(returnAudio)
|
||||||
|
return btts( data, objs.audioSet, objs.audioCallback, objs.lineUp, returnAudio);
|
||||||
|
btts( data, objs.audioSet, objs.audioCallback, objs.lineUp, returnAudio);
|
||||||
|
}
|
||||||
|
|
||||||
|
function setAudioSet(options, audio) {
|
||||||
|
if (options) {
|
||||||
|
audio.volume = options.volume || 1;
|
||||||
|
audio.startTime = options.startTime || 0;
|
||||||
|
audio.loop = options.loop || false;
|
||||||
|
audio.obeyMuteSwitch = options.obeyMuteSwitch && typeof(options.obeyMuteSwitch) == 'boolean' ? options.obeyMuteSwitch :
|
||||||
|
true; //支持微信小程序、百度小程序、头条小程序
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function btts(param, options, audioCallback, lineUp, returnAudio) {
|
||||||
|
let audio = uni.createInnerAudioContext();
|
||||||
|
setAudioSet(options, audio);
|
||||||
|
// 序列化参数列表
|
||||||
|
let fd = [];
|
||||||
|
for (let k in param) {
|
||||||
|
fd.push(k + '=' + encodeURIComponent(encodeURIComponent(param[k])));
|
||||||
|
}
|
||||||
|
audio.src = `${getAudioUrl}?${fd.join('&')}`;
|
||||||
|
|
||||||
|
if(returnAudio) {
|
||||||
|
audio.onEnded(() => {
|
||||||
|
audio.destroy(); //销毁音频实例
|
||||||
|
audio = null;
|
||||||
|
})
|
||||||
|
audio.onError((e)=>{
|
||||||
|
if (audioCallback && audioCallback.onError && typeof(audioCallback.onError) == 'function') audioCallback.onError(e);
|
||||||
|
audio.destroy(); //销毁音频实例
|
||||||
|
audio = null;
|
||||||
|
})
|
||||||
|
return audio;
|
||||||
|
}
|
||||||
|
audio.onPlay(() => {
|
||||||
|
if (audioCallback && audioCallback.onPlay && typeof(audioCallback.onPlay) == 'function') audioCallback.onPlay();
|
||||||
|
})
|
||||||
|
audio.onPause(()=>{
|
||||||
|
if (audioCallback && audioCallback.onPause && typeof(audioCallback.onPause) == 'function') audioCallback.onPause();
|
||||||
|
})
|
||||||
|
audio.onWaiting(()=>{
|
||||||
|
if (audioCallback && audioCallback.onWaiting && typeof(audioCallback.onWaiting) == 'function') audioCallback.onWaiting();
|
||||||
|
})
|
||||||
|
audio.onStop(()=>{
|
||||||
|
if (audioCallback && audioCallback.onStop && typeof(audioCallback.onStop) == 'function') audioCallback.onStop();
|
||||||
|
})
|
||||||
|
audio.onTimeUpdate(()=>{
|
||||||
|
if (audioCallback && audioCallback.onTimeUpdate && typeof(audioCallback.onTimeUpdate) == 'function') audioCallback.onTimeUpdate();
|
||||||
|
})
|
||||||
|
audio.onSeeking(()=>{
|
||||||
|
if (audioCallback && audioCallback.onSeeking && typeof(audioCallback.onSeeking) == 'function') audioCallback.onSeeking();
|
||||||
|
})
|
||||||
|
audio.onSeeked(()=>{
|
||||||
|
if (audioCallback && audioCallback.onSeeked && typeof(audioCallback.onSeeked) == 'function') audioCallback.onSeeked();
|
||||||
|
})
|
||||||
|
audio.onEnded(() => {
|
||||||
|
audio.destroy(); //销毁音频实例
|
||||||
|
audio = null;
|
||||||
|
if (audioCallback && audioCallback.onEnded && typeof(audioCallback.onEnded) == 'function') audioCallback.onEnded();
|
||||||
|
if (lineUp !== false) {
|
||||||
|
if (audioTeam.length > 0) {
|
||||||
|
openVoiceFc(audioTeam[0]);
|
||||||
|
audioTeam.splice(0, 1);
|
||||||
|
} else {
|
||||||
|
audioStartSwitch = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
audio.onError((e)=>{
|
||||||
|
if (audioCallback && audioCallback.onError && typeof(audioCallback.onError) == 'function') audioCallback.onError(e);
|
||||||
|
audio.destroy(); //销毁音频实例
|
||||||
|
audio = null;
|
||||||
|
})
|
||||||
|
audio.play();
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,71 @@
|
||||||
|
import storageManage from '@/commons/utils/storageManage.js'
|
||||||
|
import dayjs from 'dayjs'
|
||||||
|
import baiduyy from './QS-baiduyy.js'; // 百度语音合成
|
||||||
|
|
||||||
|
// #ifdef MP-WEIXIN
|
||||||
|
import wxTextToSpeach from './wxTextToSpeach.js'; // 微信小程序插件语音合成
|
||||||
|
// #endif
|
||||||
|
|
||||||
|
|
||||||
|
const model = {
|
||||||
|
// 监听推送通知
|
||||||
|
addPushMsgEventListener: function(){
|
||||||
|
|
||||||
|
console.log("监听推送")
|
||||||
|
|
||||||
|
// #ifdef APP-PLUS
|
||||||
|
// unipush1.0监听消息
|
||||||
|
if(plus && plus.push) {
|
||||||
|
plus.push.addEventListener('receive', model.handlePush)
|
||||||
|
}
|
||||||
|
// #endif
|
||||||
|
// unipush2.0监听消息
|
||||||
|
model.uniPushListener2()
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
// uniPush2.0 接收推送消息
|
||||||
|
uniPushListener2: function() {
|
||||||
|
uni.onPushMessage((res) => {
|
||||||
|
console.log("uniPush2.0 收到推送消息:", res.data) //监听推送消息
|
||||||
|
model.handlePush(res.data)
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
// 语音播报
|
||||||
|
handlePush: function(message) {
|
||||||
|
|
||||||
|
// 没有token信息
|
||||||
|
if(!storageManage.token()){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 信息不存在
|
||||||
|
if(!message || !message.content) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const content = JSON.parse(message.content)
|
||||||
|
console.log("消息内容:", content)
|
||||||
|
|
||||||
|
// 支付成功
|
||||||
|
if (content && content.type == 'paySuccess') {
|
||||||
|
// 在过期时间之内, 则调起语音播报。
|
||||||
|
if( dayjs(content.expiredTime).isAfter(dayjs()) ){
|
||||||
|
console.log('执行消息播报');
|
||||||
|
// #ifdef MP-WEIXIN
|
||||||
|
wxTextToSpeach(content.msg)
|
||||||
|
// #endif
|
||||||
|
|
||||||
|
// #ifndef MP-WEIXIN
|
||||||
|
baiduyy(content.msg)
|
||||||
|
// #endif
|
||||||
|
uni.vibrateLong({});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export default model
|
||||||
|
|
@ -0,0 +1,50 @@
|
||||||
|
import {
|
||||||
|
$pushInfoRegister
|
||||||
|
} from '@/http/apiManager.js'
|
||||||
|
import storageManage from '@/commons/utils/storageManage.js'
|
||||||
|
// 默认导出 方法 注册 push连接
|
||||||
|
export default async function() {
|
||||||
|
let cid1 = undefined // unipush1.0 客户端CID
|
||||||
|
let cid2 = undefined // unipush2.0 客户端CID
|
||||||
|
let orgCid = undefined // 原始cid如果获取的cid和新的cid不相同赋值原始cid后端会根据原始cid更新
|
||||||
|
let cidType = undefined //传递类型 是 app 还是 微信
|
||||||
|
// #ifdef APP-PLUS
|
||||||
|
cidType = 'app_plus'
|
||||||
|
// #endif
|
||||||
|
|
||||||
|
// #ifdef MP-WEIXIN
|
||||||
|
cidType = 'mp_weixin'
|
||||||
|
// #endif
|
||||||
|
|
||||||
|
// #ifdef APP-PLUS
|
||||||
|
if (!plus) {
|
||||||
|
cid1 = plus.push.getClientInfo().clientid
|
||||||
|
}
|
||||||
|
// #endif
|
||||||
|
const data = await uni.getPushClientId()
|
||||||
|
console.log('客户端推送标识:', data.cid)
|
||||||
|
cid2 = data.cid
|
||||||
|
// 如果不存 cid 本地存储 写入 cid
|
||||||
|
if (!storageManage.uniPush2Cid()) {
|
||||||
|
storageManage.uniPush2Cid(data.cid)
|
||||||
|
} else if (cid2 !== storageManage.uniPush2Cid()) { // 否则进行 cid 对比 判断 是否相等 不相等 赋值 orgCid
|
||||||
|
orgCid = storageManage.uniPush2Cid() //赋值原始cid
|
||||||
|
storageManage.uniPush2Cid(data.cid) //重新写入 cid
|
||||||
|
}
|
||||||
|
if (cid1) {
|
||||||
|
pushInfoRegister(cid1)
|
||||||
|
} else {
|
||||||
|
pushInfoRegister(cid1, cid2, orgCid, cidType)
|
||||||
|
}
|
||||||
|
|
||||||
|
function pushInfoRegister(cid1 = '', cid2 = '', org = '', cidType = '') {
|
||||||
|
$pushInfoRegister({
|
||||||
|
cid1,
|
||||||
|
cid2,
|
||||||
|
orgCid: org,
|
||||||
|
cidType
|
||||||
|
}).then(res => {
|
||||||
|
orgCid = '' //重置 数据
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,87 @@
|
||||||
|
import { $mchConfig } from "@/http/apiManager"
|
||||||
|
import storageManage from '@/commons/utils/storageManage.js'
|
||||||
|
let num = 0 //计算错误此时 超过5次错误 不在出触发
|
||||||
|
const plugin = requirePlugin("WechatSI")
|
||||||
|
const pushMsgArr = [] //维护一个消息队列
|
||||||
|
let backgroundAudioManager = undefined //获取背景音频实例
|
||||||
|
let audioMp3 = ''
|
||||||
|
console.log('执行创建 语音播报逻辑');
|
||||||
|
// 获取配置项 判断是否 开启 小程序 语音推送
|
||||||
|
export function getPushStatus () {
|
||||||
|
if (!storageManage.token()) return //未登录 不播放
|
||||||
|
$mchConfig('orderConfig').then(({ bizData = [] }) => {
|
||||||
|
const weChat = bizData.find(v => v.configKey == "weChatVoice")
|
||||||
|
if (weChat && weChat?.configVal == 1) {
|
||||||
|
createBgMusice()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
// getPushStatus()
|
||||||
|
// 创建 背景音乐
|
||||||
|
function createBgMusice (file) {
|
||||||
|
backgroundAudioManager = wx.getBackgroundAudioManager()
|
||||||
|
backgroundAudioManager.title = '订单通知'
|
||||||
|
if (!audioMp3) {
|
||||||
|
createFile()
|
||||||
|
} else {
|
||||||
|
backgroundAudioManager.src = audioMp3
|
||||||
|
}
|
||||||
|
|
||||||
|
// 监听 音频播放失败事件
|
||||||
|
backgroundAudioManager.onError(function (res) {
|
||||||
|
console.log('音频播放失败', res, num);
|
||||||
|
if (num >= 5) return
|
||||||
|
createFile()
|
||||||
|
num++
|
||||||
|
})
|
||||||
|
// 监听 音频播放结束事件
|
||||||
|
onBgMusiceEnd()
|
||||||
|
}
|
||||||
|
// 监听bei背景音乐播放状态
|
||||||
|
export function onBgMusiceEnd () {
|
||||||
|
backgroundAudioManager.onEnded(() => {
|
||||||
|
if (pushMsgArr.length > 0) return broadcast(pushMsgArr.pop()) //如果有消息 则继续播放
|
||||||
|
backgroundAudioManager.src = audioMp3 //否则播放默认背景音乐
|
||||||
|
})
|
||||||
|
}
|
||||||
|
export function startOrEndMusice (flag) {
|
||||||
|
if (!flag && !!backgroundAudioManager) return backgroundAudioManager.stop() //关闭背景音乐 地址指向空即可
|
||||||
|
if (!backgroundAudioManager) return createBgMusice() // 如果一开始是关闭状态 则创建背景音乐实例
|
||||||
|
backgroundAudioManager.src = audioMp3 // 否则重新赋值背景音地址即可
|
||||||
|
}
|
||||||
|
export default function (message) {
|
||||||
|
if (!backgroundAudioManager) return
|
||||||
|
pushMsgArr.unshift(message) //将消息添加到消息队列头部 背景音乐播放结束后 会对消息队列 进行校验 如果消息队列有消息 会进行播放 否则继续循环背景音乐
|
||||||
|
}
|
||||||
|
// 播放订单
|
||||||
|
function broadcast (msg) {
|
||||||
|
plugin.textToSpeech({
|
||||||
|
lang: "zh_CN",
|
||||||
|
tts: true,
|
||||||
|
content: msg,
|
||||||
|
success: function (res) {
|
||||||
|
backgroundAudioManager.src = res.filename;
|
||||||
|
onBgMusiceEnd()
|
||||||
|
},
|
||||||
|
fail: function (res) {
|
||||||
|
console.log("fail tts", res)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 创建文件
|
||||||
|
export function createFile (file) {
|
||||||
|
const fs = wx.getFileSystemManager()
|
||||||
|
fs.copyFile({
|
||||||
|
srcPath: `static/noiseless.mp3`,
|
||||||
|
destPath: `${wx.env.USER_DATA_PATH}/noiseless.mp3`,
|
||||||
|
success (res) {
|
||||||
|
console.log(res, `${wx.env.USER_DATA_PATH}/noiseless.mp3`)
|
||||||
|
audioMp3 = `${wx.env.USER_DATA_PATH}/noiseless.mp3`
|
||||||
|
backgroundAudioManager.src = audioMp3
|
||||||
|
},
|
||||||
|
fail (res) {
|
||||||
|
console.error(res)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,10 @@
|
||||||
|
创建 云空间 上传云函数 云函数 url化 运营平台 配置云函数地址
|
||||||
|
|
||||||
|
打包时 勾选云push 2.0 push1.0 仅支持 app 推送
|
||||||
|
|
||||||
|
注意配置 百度语音相关参数
|
||||||
|
|
||||||
|
使用push2.0 请将 static\noiseless.mp3 文件 配置到运营平台 系统 配置 通知配置 push2.0 uniPush语音播报音频文件(小程序播报必填) 下
|
||||||
|
|
||||||
|
注意:扩展库依赖3张opendb表:opendb-tempdata,opendb-device,uni-id-device。公测版uniCloud,执行扩展库会自动创建。如果你使用的是uniCloud正式版需要自己创建这3张表。
|
||||||
|
|
||||||
|
|
@ -0,0 +1,202 @@
|
||||||
|
/**
|
||||||
|
* 存储管理对象
|
||||||
|
* 目标:将现有系统的所有需要存储的数据,统一管理
|
||||||
|
*
|
||||||
|
* @author terrfly
|
||||||
|
* @site https://www.jeequan.com
|
||||||
|
* @date 2022/04/13 07:18
|
||||||
|
*/
|
||||||
|
|
||||||
|
import appConfig from "@/config/appConfig.js"
|
||||||
|
|
||||||
|
// 应用级(vue级别)缓存, 当存在时则读取此值, 否则读取storage中的值。( vue线程内的缓存,不必要每次读取应用数据,影响性能)
|
||||||
|
const appCache = {
|
||||||
|
tokenVal: null, // token取值
|
||||||
|
currentUser: null, // 当前商户信息
|
||||||
|
}
|
||||||
|
|
||||||
|
const model = {
|
||||||
|
|
||||||
|
setLogin(res){
|
||||||
|
uni.setStorageSync('logoutHandle',false)
|
||||||
|
uni.setStorageSync('shopId', res.shopId)
|
||||||
|
uni.setStorageSync('shopName',res.shopName)
|
||||||
|
uni.setStorageSync('logo',res.logo)
|
||||||
|
uni.setStorageSync('loginType',res.loginType)
|
||||||
|
},
|
||||||
|
// 退出清空所有的缓存数据。 (不包含 环境相关)
|
||||||
|
cleanByLogout: () => {
|
||||||
|
|
||||||
|
// 1. 清空app级别缓存。
|
||||||
|
Object.keys(appCache).forEach(k => appCache[k] = null)
|
||||||
|
|
||||||
|
let envName = model.env() // 获取到当前的环境变量
|
||||||
|
uni.clearStorageSync() // 清除所有的缓存信息
|
||||||
|
model.env(envName) // 重置env
|
||||||
|
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
// 获取和放置token
|
||||||
|
token: (val, isDelete = false) => {
|
||||||
|
if (isDelete) {
|
||||||
|
appCache.tokenVal = ""
|
||||||
|
return uni.removeStorageSync(appConfig.tokenKey)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (val) {
|
||||||
|
// 有值,为放置
|
||||||
|
appCache.tokenVal = val
|
||||||
|
uni.setStorageSync(appConfig.tokenKey, val)
|
||||||
|
} else {
|
||||||
|
// 否则为获取
|
||||||
|
|
||||||
|
if (!appCache.tokenVal) {
|
||||||
|
//缓存取不到,获取应用本地信息
|
||||||
|
appCache.tokenVal = uni.getStorageSync(appConfig.tokenKey)
|
||||||
|
}
|
||||||
|
return appCache.tokenVal
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 获取和放置shopId
|
||||||
|
shopId: (val, isDelete = false) => {
|
||||||
|
if (isDelete) {
|
||||||
|
appCache.shopId = ""
|
||||||
|
return uni.removeStorageSync('shopId')
|
||||||
|
}
|
||||||
|
|
||||||
|
if (val) {
|
||||||
|
// 有值,为放置
|
||||||
|
appCache.shopId = val
|
||||||
|
uni.setStorageSync('shopId', val)
|
||||||
|
} else {
|
||||||
|
// 否则为获取
|
||||||
|
|
||||||
|
if (!appCache.shopId) {
|
||||||
|
//缓存取不到,获取应用本地信息
|
||||||
|
appCache.shopId = uni.getStorageSync('shopId')
|
||||||
|
}
|
||||||
|
return appCache.shopId
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// 已经登录的用户记录
|
||||||
|
loggedInUser: (addUserName = null, removeUserName = null) => {
|
||||||
|
let key = "loggedInUserList"
|
||||||
|
|
||||||
|
// 删除
|
||||||
|
if (removeUserName) {
|
||||||
|
let nameList = uni.getStorageSync(key) || []
|
||||||
|
if (nameList.length <= 0) {
|
||||||
|
//不存在数据
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
let hasUserIndex = nameList.indexOf(removeUserName)
|
||||||
|
if (hasUserIndex >= 0) {
|
||||||
|
nameList.splice(hasUserIndex, 1) //删除
|
||||||
|
uni.setStorageSync(key, nameList)
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// 有新插入的记录
|
||||||
|
if (addUserName) {
|
||||||
|
let nameList = uni.getStorageSync(key) || []
|
||||||
|
|
||||||
|
let hasUser = false
|
||||||
|
for (let i = 0; i < nameList.length; i++) {
|
||||||
|
if (nameList[i] == addUserName) {
|
||||||
|
hasUser = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 包含记录
|
||||||
|
if (hasUser) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// 最多存储 5 个
|
||||||
|
if (nameList.length >= 5) {
|
||||||
|
nameList.splice(0, 1) //删除第一个
|
||||||
|
}
|
||||||
|
nameList.push(addUserName)
|
||||||
|
uni.setStorageSync(key, nameList)
|
||||||
|
|
||||||
|
//获取
|
||||||
|
} else {
|
||||||
|
return uni.getStorageSync(key) || [] //默认空数组
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// 用户信息
|
||||||
|
userInfo: (currentUserInfo) => {
|
||||||
|
if (currentUserInfo) {
|
||||||
|
// 仅保存基础数据
|
||||||
|
let saveUser = {
|
||||||
|
|
||||||
|
sysUserId: currentUserInfo.sysUserId, // 用户ID
|
||||||
|
realname: currentUserInfo.realname, // 用户姓名
|
||||||
|
avatarUrl: currentUserInfo.avatarUrl, // 头像
|
||||||
|
telphone: currentUserInfo.telphone, // 手机号
|
||||||
|
userType: currentUserInfo.userType, // 用户类型
|
||||||
|
|
||||||
|
mchNo: currentUserInfo.userNo, // 商户No
|
||||||
|
mchShortName: currentUserInfo.shortName, // 商户简称
|
||||||
|
mchType: currentUserInfo.mchType, // 商户类型
|
||||||
|
mchLevel: currentUserInfo.mchLevel, // 商户级别
|
||||||
|
isHasMemberEnt:currentUserInfo.isHasMemberEnt,// 是否购买会员模块
|
||||||
|
entIdList: currentUserInfo.entIdList, // 权限集合List
|
||||||
|
|
||||||
|
}
|
||||||
|
uni.setStorageSync("currentUserInfo", saveUser) // 改变存储
|
||||||
|
appCache.currentUser = null
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!appCache.currentUser){ // 获取缓存数据
|
||||||
|
appCache.currentUser = uni.getStorageSync("currentUserInfo")
|
||||||
|
}
|
||||||
|
|
||||||
|
return appCache.currentUser
|
||||||
|
},
|
||||||
|
|
||||||
|
// 项目环境变量:(测试、 生产的切换)
|
||||||
|
env: (envMode) => {
|
||||||
|
if (envMode) {
|
||||||
|
uni.setStorageSync(appConfig.storeEnvEnumKey, envMode) // 改变存储
|
||||||
|
}
|
||||||
|
return uni.getStorageSync(appConfig.storeEnvEnumKey)
|
||||||
|
},
|
||||||
|
|
||||||
|
// push 状态是否开启
|
||||||
|
pushIsOpen: (pushFlag) => {
|
||||||
|
if (pushFlag) {
|
||||||
|
uni.setStorageSync('pushFlag', pushFlag) // 改变存储
|
||||||
|
}
|
||||||
|
return uni.getStorageSync('pushFlag')
|
||||||
|
},
|
||||||
|
// 网站信息
|
||||||
|
siteInfos: (siteInfos) => {
|
||||||
|
if (siteInfos) {
|
||||||
|
uni.setStorageSync("siteInfos", siteInfos) // 改变存储
|
||||||
|
}
|
||||||
|
return uni.getStorageSync("siteInfos")
|
||||||
|
},
|
||||||
|
|
||||||
|
// unipush2 cid
|
||||||
|
uniPush2Cid: (uniPush2Cid) => {
|
||||||
|
if (uniPush2Cid) {
|
||||||
|
uni.setStorageSync("uniPush2Cid", uniPush2Cid) // 改变存储
|
||||||
|
}
|
||||||
|
return uni.getStorageSync("uniPush2Cid")
|
||||||
|
},
|
||||||
|
uploadImgSize: (uploadImgSize) => {
|
||||||
|
if (uploadImgSize) {
|
||||||
|
uni.setStorageSync("uploadImgSize", uploadImgSize) // 存储 上传 图片大小限制
|
||||||
|
}
|
||||||
|
return uni.getStorageSync("uploadImgSize")
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
export default model
|
||||||
|
|
@ -0,0 +1,27 @@
|
||||||
|
const appConfig = {
|
||||||
|
|
||||||
|
// 项目名称
|
||||||
|
appName: '银收客',
|
||||||
|
|
||||||
|
// token取值key
|
||||||
|
tokenKey: 'iToken',
|
||||||
|
// tokenKey: 'satoken',
|
||||||
|
|
||||||
|
// 环境变量相关
|
||||||
|
env: {},
|
||||||
|
|
||||||
|
// 环境变量常量
|
||||||
|
ENV_ENUM: {
|
||||||
|
DEVELOPMENT: 'development', // 本地调试地址
|
||||||
|
TEST: 'test', // 测试地址
|
||||||
|
DEMO: 'demo', // 演示环境
|
||||||
|
PRODUCTION: 'production' // 生产环境
|
||||||
|
},
|
||||||
|
|
||||||
|
storeEnvEnumKey: 'currentEnvEnum', // 本地存储的envkey的值
|
||||||
|
|
||||||
|
encryptKey: '1234567890123456' // http数据加解密的key
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export default appConfig;
|
||||||
|
|
@ -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="/main.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
@ -0,0 +1,24 @@
|
||||||
|
import App from './App'
|
||||||
|
|
||||||
|
// #ifndef VUE3
|
||||||
|
import Vue from 'vue'
|
||||||
|
|
||||||
|
|
||||||
|
import './uni.promisify.adaptor'
|
||||||
|
Vue.config.productionTip = false
|
||||||
|
App.mpType = 'app'
|
||||||
|
const app = new Vue({
|
||||||
|
...App
|
||||||
|
})
|
||||||
|
app.$mount(); //为了兼容小程序及app端必须这样写才有效果
|
||||||
|
// #endif
|
||||||
|
|
||||||
|
// #ifdef VUE3
|
||||||
|
import { createSSRApp } from 'vue'
|
||||||
|
export function createApp() {
|
||||||
|
const app = createSSRApp(App)
|
||||||
|
return {
|
||||||
|
app
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// #endif
|
||||||
|
|
@ -0,0 +1,101 @@
|
||||||
|
{
|
||||||
|
"name" : "payH5",
|
||||||
|
"appid" : "__UNI__A285A50",
|
||||||
|
"description" : "",
|
||||||
|
"versionName" : "1.0.0",
|
||||||
|
"versionCode" : "100",
|
||||||
|
"transformPx" : false,
|
||||||
|
/* 5+App特有相关 */
|
||||||
|
"app-plus" : {
|
||||||
|
"usingComponents" : true,
|
||||||
|
"nvueStyleCompiler" : "uni-app",
|
||||||
|
"compilerVersion" : 3,
|
||||||
|
"splashscreen" : {
|
||||||
|
"alwaysShowBeforeRender" : true,
|
||||||
|
"waiting" : true,
|
||||||
|
"autoclose" : true,
|
||||||
|
"delay" : 0
|
||||||
|
},
|
||||||
|
/* 模块配置 */
|
||||||
|
"modules" : {
|
||||||
|
"Payment" : {}
|
||||||
|
},
|
||||||
|
/* 应用发布信息 */
|
||||||
|
"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" : {
|
||||||
|
"payment" : {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"h5" : {
|
||||||
|
"unipush" : {
|
||||||
|
"enable" : true
|
||||||
|
},
|
||||||
|
"router" : {
|
||||||
|
"mode" : "history", //采用history模式URL的路径才跟配置的对应上,不然URL是先加/#再追加配置的地
|
||||||
|
"base" : "/pay" //在页面路由上加上该前缀
|
||||||
|
},
|
||||||
|
"devServer" : {
|
||||||
|
"port" : 80,
|
||||||
|
"disableHostCheck" : true,
|
||||||
|
"proxy" : {
|
||||||
|
"/api" : {
|
||||||
|
// 需要被代理的后台地址
|
||||||
|
"target" : "https://cashier-client.sxczgkj.cn/cashier-client",
|
||||||
|
"changeOrigin" : true,
|
||||||
|
"secure" : false,
|
||||||
|
"pathRewrite" : {
|
||||||
|
"/api" : ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
/* 快应用特有相关 */
|
||||||
|
"quickapp" : {},
|
||||||
|
/* 小程序特有相关 */
|
||||||
|
"mp-weixin" : {
|
||||||
|
"appid" : "",
|
||||||
|
"setting" : {
|
||||||
|
"urlCheck" : false
|
||||||
|
},
|
||||||
|
"usingComponents" : true
|
||||||
|
},
|
||||||
|
"mp-alipay" : {
|
||||||
|
"usingComponents" : true
|
||||||
|
},
|
||||||
|
"mp-baidu" : {
|
||||||
|
"usingComponents" : true
|
||||||
|
},
|
||||||
|
"mp-toutiao" : {
|
||||||
|
"usingComponents" : true
|
||||||
|
},
|
||||||
|
"uniStatistics" : {
|
||||||
|
"enable" : false
|
||||||
|
},
|
||||||
|
"vueVersion" : "2"
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
{
|
||||||
|
"format": 2
|
||||||
|
}
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,10 @@
|
||||||
|
{
|
||||||
|
"dependencies": {
|
||||||
|
"alipay-sdk": "^4.13.0",
|
||||||
|
"copy-webpack-plugin": "^12.0.2",
|
||||||
|
"gm-crypto": "^0.1.12",
|
||||||
|
"jweixin-module": "^1.6.0",
|
||||||
|
"uni-simple-router": "^2.0.8-beta.4",
|
||||||
|
"vue-router": "^4.4.5"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,16 @@
|
||||||
|
{
|
||||||
|
"pages": [ //pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocation/pages
|
||||||
|
{
|
||||||
|
"path": "pages/index/index",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": "支付",
|
||||||
|
"navigationStyle": "custom"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"globalStyle": {
|
||||||
|
|
||||||
|
},
|
||||||
|
"uniIdRouter": {}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -0,0 +1,389 @@
|
||||||
|
<template>
|
||||||
|
<view class="content">
|
||||||
|
<view class="info">
|
||||||
|
<image class="shopImage" :src="shopImage"></image>
|
||||||
|
<view class="shopName">{{shopName}}</view>
|
||||||
|
</view>
|
||||||
|
<view class="input">
|
||||||
|
<view class="payAmount">¥<input :disabled="disabled" @input="formatAmount" class="amount" v-model="payAmount" type="digit"></view>
|
||||||
|
<input class="remark" v-model="remark" type="text" placeholder="添加付款备注(最多10个字)">
|
||||||
|
</view>
|
||||||
|
<view class="btn" @click="createOrder">立即付款</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
|
||||||
|
import { getOpenId , createOrder , cancelOrderPay } from '@/api/index.js'
|
||||||
|
export default {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
payAmount: "",
|
||||||
|
openId: null,
|
||||||
|
shopImage: null,
|
||||||
|
shopName: null,
|
||||||
|
shopId: null,
|
||||||
|
orderId: null,
|
||||||
|
remark: "",
|
||||||
|
payType: "",
|
||||||
|
disabled: false,
|
||||||
|
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onLoad() {
|
||||||
|
},
|
||||||
|
onShow () {
|
||||||
|
this.shopId = this.getUrlParam("shopId");
|
||||||
|
this.orderId = this.getUrlParam("orderId");
|
||||||
|
if ( this.getUrlParam("payAmount") ) {
|
||||||
|
this.payAmount = this.getUrlParam("payAmount");
|
||||||
|
this.disabled = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
document.body.addEventListener('touchmove', function (e) {
|
||||||
|
e.preventDefault(); //阻止默认的处理方式(阻止下拉滑动的效果)
|
||||||
|
}, {passive: false}); //passive 参数不能省略,用来兼容ios和android
|
||||||
|
this.login()
|
||||||
|
},
|
||||||
|
|
||||||
|
mounted() {
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
|
||||||
|
formatAmount(event) {
|
||||||
|
// 必须在nextTick中
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.payAmount = event.target.value.match(/^\d*(\.?\d{0,2})/g)[0]
|
||||||
|
})
|
||||||
|
|
||||||
|
// e.detail.value = (e.detail.value.match(/^\d*(.?\d{0,2})/g)[0]) || ""
|
||||||
|
// this.$nextTick(() => {
|
||||||
|
// this.payAmount = e.detail.value
|
||||||
|
// })
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 判断是否为微信环境
|
||||||
|
*/
|
||||||
|
isWechat (){
|
||||||
|
var ua = navigator.userAgent.toLowerCase();
|
||||||
|
var isWXWork = ua.match(/wxwork/i) == 'wxwork';
|
||||||
|
var isWeixin = !isWXWork && ua.match(/MicroMessenger/i) == 'micromessenger';
|
||||||
|
return isWeixin;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 判断是否为支付宝环境
|
||||||
|
*/
|
||||||
|
isAlipay() {
|
||||||
|
let userAgent = navigator.userAgent;
|
||||||
|
return /AlipayClient/.test(userAgent);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取微信/支付宝code
|
||||||
|
*/
|
||||||
|
login () {
|
||||||
|
|
||||||
|
// 获取微信code
|
||||||
|
if ( this.isWechat() ) {
|
||||||
|
let _code = this.getUrlParam("code");
|
||||||
|
uni.setStorageSync("code",_code)
|
||||||
|
if (_code == null || _code === "") {
|
||||||
|
// 传当前页面的URL(微信授权完之后返回到的页面)和 登录方式
|
||||||
|
this.getWXCode(window.location.href, 'snsapi_userinfo');
|
||||||
|
} else {
|
||||||
|
|
||||||
|
this.payType = "WECHAT";
|
||||||
|
// this.getOpenId(_code,"wx212769170d2c6b2a"); //微信 WECHAT; 支付宝 ALIPAY;
|
||||||
|
this.getOpenId(uni.getStorageSync("code"),"wx212769170d2c6b2a"); //微信 WECHAT; 支付宝 ALIPAY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取支付宝code
|
||||||
|
if ( this.isAlipay() ) {
|
||||||
|
let _code = this.getUrlParam("auth_code");
|
||||||
|
if (_code == null || _code === "") {
|
||||||
|
// 传当前页面的URL(支付宝授权完之后返回到的页面)和 登录方式
|
||||||
|
this.getAlipayCode(window.location.href, 'auth_user');
|
||||||
|
} else {
|
||||||
|
this.payType = "ALIPAY";
|
||||||
|
this.getOpenId(_code,"2021004174605036"); //微信 WECHAT; 支付宝 ALIPAY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取微信/支付宝openid
|
||||||
|
* @param {Object} code
|
||||||
|
* @param {Object} payType
|
||||||
|
*/
|
||||||
|
getOpenId (code,appId) {
|
||||||
|
let params = {
|
||||||
|
code : code,
|
||||||
|
payType : this.payType, //微信 WECHAT; 支付宝 ALIPAY;
|
||||||
|
appId : appId, //微信 WECHAT; 支付宝 ALIPAY;
|
||||||
|
shopId : this.getUrlParam("shopId"), //微信 WECHAT; 支付宝 ALIPAY;
|
||||||
|
}
|
||||||
|
getOpenId(params).then((res) => {
|
||||||
|
if ( res.code == 0 ) {
|
||||||
|
this.openId = res.data.openId;
|
||||||
|
this.shopImage = res.data.shopImage;
|
||||||
|
this.shopName = res.data.shopName;
|
||||||
|
// this.createOrder(res.data,payType);
|
||||||
|
} else {
|
||||||
|
uni.showToast({
|
||||||
|
title: res.msg,
|
||||||
|
icon: 'none'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取code并登录
|
||||||
|
*/
|
||||||
|
getWXCode: async (url, snsapi) => {
|
||||||
|
let appid = 'wx212769170d2c6b2a' //公众号的唯一标识
|
||||||
|
let secrete = '8492a7e8d55bbb1b57f5c8276ea1add0' //
|
||||||
|
// let redirect_uri = "https://pcweb.sxczgkj.cn/cashier/pay"
|
||||||
|
let redirect_uri = encodeURIComponent(url); //授权后重定向的回调链接地址
|
||||||
|
let time = +new Date(); //时间戳
|
||||||
|
|
||||||
|
window.location.href =
|
||||||
|
`https://open.weixin.qq.com/connect/oauth2/authorize?
|
||||||
|
appid=${appid}&
|
||||||
|
redirect_uri=${redirect_uri}&
|
||||||
|
response_type=code&
|
||||||
|
scope=${snsapi}&
|
||||||
|
state=1&
|
||||||
|
time=${time}#wechat_redirect`;
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取支付宝code
|
||||||
|
* @param {Object} url
|
||||||
|
* @param {Object} snsapi
|
||||||
|
*/
|
||||||
|
getAlipayCode (url, snsapi) {
|
||||||
|
let appid = '2021004174605036' //公众号的唯一标识
|
||||||
|
// let redirect_uri = "https://pcweb.sxczgkj.cn/cashier/pay"
|
||||||
|
let redirect_uri = encodeURIComponent(url); //授权后重定向的回调链接地址
|
||||||
|
window.location.href =
|
||||||
|
`https://openauth.alipay.com/oauth2/publicAppAuthorize.htm?
|
||||||
|
app_id=${appid}&
|
||||||
|
redirect_uri=${redirect_uri}&
|
||||||
|
scope=${snsapi}&
|
||||||
|
state=1`;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建订单
|
||||||
|
*/
|
||||||
|
createOrder () {
|
||||||
|
if ( this.payAmount == "") {
|
||||||
|
uni.showToast({
|
||||||
|
title: '请输入支付金额',
|
||||||
|
icon: 'none'
|
||||||
|
})
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let params = {
|
||||||
|
userId : this.openId,
|
||||||
|
shopId : this.shopId,
|
||||||
|
payType : this.payType,
|
||||||
|
payAmount : this.payAmount,
|
||||||
|
remark: this.remark,
|
||||||
|
}
|
||||||
|
if ( this.orderId ) {
|
||||||
|
params.orderId = this.orderId;
|
||||||
|
}
|
||||||
|
createOrder(params).then((res) => {
|
||||||
|
// alert("创建订单=="+JSON.stringify(res))
|
||||||
|
if ( res.code == '100015' ) {
|
||||||
|
this.orderId = res.data.orderInfo.id;
|
||||||
|
if ( this.isWechat() ) {
|
||||||
|
this.wxH5Pay(res)
|
||||||
|
}
|
||||||
|
if ( this.isAlipay() ) {
|
||||||
|
this.alipay(res)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
uni.showToast({
|
||||||
|
title: res.msg,
|
||||||
|
icon: 'none'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 微信支付
|
||||||
|
* @param {Object} res
|
||||||
|
*/
|
||||||
|
wxH5Pay (res) {
|
||||||
|
WeixinJSBridge.invoke('getBrandWCPayRequest', {
|
||||||
|
debug: true,
|
||||||
|
appId: res.data.payInfo.appId,
|
||||||
|
timeStamp: res.data.payInfo.timeStamp,
|
||||||
|
nonceStr: res.data.payInfo.nonceStr,
|
||||||
|
package: res.data.payInfo.package,
|
||||||
|
paySign: res.data.payInfo.paySign,
|
||||||
|
signType: res.data.payInfo.signType,
|
||||||
|
}, function(res) {
|
||||||
|
console.log(res)
|
||||||
|
if (res.err_msg === 'get_brand_wcpay_request:ok') {
|
||||||
|
// 支付成功的处理逻辑
|
||||||
|
uni.showToast({
|
||||||
|
title: '微信支付成功',
|
||||||
|
icon: 'none'
|
||||||
|
})
|
||||||
|
setTimeout(function (){
|
||||||
|
WeixinJSBridge.invoke('closeWindow');
|
||||||
|
|
||||||
|
},500)
|
||||||
|
} else if (res.err_msg == "get_brand_wcpay_request:cancel") {
|
||||||
|
// 支付过程中取消支付
|
||||||
|
cancelOrderPay({ orderId: this.orderId, })
|
||||||
|
uni.showToast({
|
||||||
|
title: '取消支付',
|
||||||
|
icon: 'none'
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
cancelOrderPay({ orderId: this.orderId, })
|
||||||
|
uni.showToast({
|
||||||
|
title: '支付失败',
|
||||||
|
icon: 'none'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 支付宝支付
|
||||||
|
* @param {Object} res
|
||||||
|
*/
|
||||||
|
alipay (res) {
|
||||||
|
|
||||||
|
// 判断是否存在支付宝的JSBridge
|
||||||
|
if (window.AlipayJSBridge) {
|
||||||
|
// 调用支付宝客户端接口,执行支付操作
|
||||||
|
AlipayJSBridge.call('tradePay', {
|
||||||
|
tradeNO: res.data.payInfo.tradeNo
|
||||||
|
}, function(result) {
|
||||||
|
if (result.resultCode === '9000') {
|
||||||
|
// 支付成功
|
||||||
|
uni.showToast({
|
||||||
|
title: '支付成功',
|
||||||
|
icon: 'none'
|
||||||
|
})
|
||||||
|
setTimeout(() => {
|
||||||
|
window.AlipayJSBridge.call('closeWebview')
|
||||||
|
}, 500);
|
||||||
|
} else {
|
||||||
|
cancelOrderPay({ orderId: this.orderId, })
|
||||||
|
// 支付失败
|
||||||
|
uni.showToast({
|
||||||
|
title: '支付失败',
|
||||||
|
icon: 'none'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// 如果支付宝的JSBridge尚未准备好,在文档中添加AlipayJSBridgeReady事件监听器
|
||||||
|
document.addEventListener('AlipayJSBridgeReady', () => {
|
||||||
|
// 准备就绪后再次调用支付函数,传入支付数据paymentData
|
||||||
|
this.alipay(paymentData);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 截取code
|
||||||
|
*/
|
||||||
|
getUrlParam: (name) => {
|
||||||
|
let reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)");
|
||||||
|
let r = window.location.search.substr(1).match(reg);
|
||||||
|
if (r != null) {
|
||||||
|
return unescape(r[2]);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
|
||||||
|
|
||||||
|
.content {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
padding: 48rpx 28rpx;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
.info{
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
.shopImage{
|
||||||
|
width: 80rpx;
|
||||||
|
height: 80rpx;
|
||||||
|
margin-right: 32rpx;
|
||||||
|
border-radius: 50%;
|
||||||
|
}
|
||||||
|
.shopName{
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 32rpx;
|
||||||
|
color: #333333;
|
||||||
|
}
|
||||||
|
.input{
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
padding: 0 16rpx;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
.payAmount{
|
||||||
|
border-bottom: 2rpx solid #E5E5E5;
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 36rpx;
|
||||||
|
color: #333333;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
padding: 24rpx 0;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
.amount{
|
||||||
|
width: 100%;
|
||||||
|
font-weight: 400;
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #333;
|
||||||
|
padding-left: 10rpx;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
.remark{
|
||||||
|
width: 100%;
|
||||||
|
margin-top: 28rpx;
|
||||||
|
font-weight: 400;
|
||||||
|
font-size: 24rpx;
|
||||||
|
color: #999999;
|
||||||
|
}
|
||||||
|
.btn{
|
||||||
|
width: 100%;
|
||||||
|
height: 64rpx;
|
||||||
|
line-height: 64rpx;
|
||||||
|
text-align: center;
|
||||||
|
background-color: #F1CB66;
|
||||||
|
border-radius: 10rpx;
|
||||||
|
color: #fff;
|
||||||
|
font-size: 28rpx;
|
||||||
|
margin-top: 40rpx;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 3.9 KiB |
|
|
@ -0,0 +1,10 @@
|
||||||
|
uni.addInterceptor({
|
||||||
|
returnValue (res) {
|
||||||
|
if (!(!!res && (typeof res === "object" || typeof res === "function") && typeof res.then === "function")) {
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
res.then((res) => res[0] ? reject(res[0]) : resolve(res[1]));
|
||||||
|
});
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
@ -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:#ffffff;
|
||||||
|
$uni-bg-color-grey:#f8f8f8;
|
||||||
|
$uni-bg-color-hover:#f1f1f1;//点击状态颜色
|
||||||
|
$uni-bg-color-mask:rgba(0, 0, 0, 0.4);//遮罩颜色
|
||||||
|
|
||||||
|
/* 边框颜色 */
|
||||||
|
$uni-border-color:#c8c7cc;
|
||||||
|
|
||||||
|
/* 尺寸变量 */
|
||||||
|
|
||||||
|
/* 文字尺寸 */
|
||||||
|
$uni-font-size-sm:12px;
|
||||||
|
$uni-font-size-base:14px;
|
||||||
|
$uni-font-size-lg:16px;
|
||||||
|
|
||||||
|
/* 图片尺寸 */
|
||||||
|
$uni-img-size-sm:20px;
|
||||||
|
$uni-img-size-base:26px;
|
||||||
|
$uni-img-size-lg:40px;
|
||||||
|
|
||||||
|
/* Border Radius */
|
||||||
|
$uni-border-radius-sm: 2px;
|
||||||
|
$uni-border-radius-base: 3px;
|
||||||
|
$uni-border-radius-lg: 6px;
|
||||||
|
$uni-border-radius-circle: 50%;
|
||||||
|
|
||||||
|
/* 水平间距 */
|
||||||
|
$uni-spacing-row-sm: 5px;
|
||||||
|
$uni-spacing-row-base: 10px;
|
||||||
|
$uni-spacing-row-lg: 15px;
|
||||||
|
|
||||||
|
/* 垂直间距 */
|
||||||
|
$uni-spacing-col-sm: 4px;
|
||||||
|
$uni-spacing-col-base: 8px;
|
||||||
|
$uni-spacing-col-lg: 12px;
|
||||||
|
|
||||||
|
/* 透明度 */
|
||||||
|
$uni-opacity-disabled: 0.3; // 组件禁用态的透明度
|
||||||
|
|
||||||
|
/* 文章场景相关 */
|
||||||
|
$uni-color-title: #2C405A; // 文章标题颜色
|
||||||
|
$uni-font-size-title:20px;
|
||||||
|
$uni-color-subtitle: #555555; // 二级标题颜色
|
||||||
|
$uni-font-size-subtitle:26px;
|
||||||
|
$uni-color-paragraph: #3F536E; // 文章段落颜色
|
||||||
|
$uni-font-size-paragraph:15px;
|
||||||
|
|
@ -0,0 +1,19 @@
|
||||||
|
import { defineConfig } from 'vite'
|
||||||
|
import uni from '@dcloudio/vite-plugin-uni'
|
||||||
|
|
||||||
|
export default defineConfig({
|
||||||
|
plugins: [
|
||||||
|
uni()
|
||||||
|
],
|
||||||
|
server: {
|
||||||
|
host: "0.0.0.0",
|
||||||
|
port:80
|
||||||
|
proxy: {
|
||||||
|
'/api': {
|
||||||
|
target: "https://cashier-client.sxczgkj.cn/cashier-client",
|
||||||
|
changeOrigin: true,
|
||||||
|
rewrite: path => path.replace(/^\/api/, ''),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
@ -0,0 +1,46 @@
|
||||||
|
// 将图片放入分包中,最后使用图片时 /分包名称/.../*/图片名称
|
||||||
|
|
||||||
|
const path = require('path')
|
||||||
|
const CopyWebpackPlugin = require('copy-webpack-plugin')
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
|
||||||
|
// devServer: {
|
||||||
|
// proxy: {
|
||||||
|
// '/shopApi': {
|
||||||
|
// target: 'https://wxcashiertest.sxczgkj.cn/cashierService',
|
||||||
|
// changeOrigin: true,
|
||||||
|
// pathRewrite: {
|
||||||
|
// '^/shopApi': ''
|
||||||
|
// },
|
||||||
|
// bypass(req, res, options) {
|
||||||
|
// const proxyURL = options.target + options.rewrite(req.url);
|
||||||
|
// req.headers['x-req-proxyURL'] = proxyURL; // 设置未生效
|
||||||
|
// res.setHeader('x-req-proxyURL', proxyURL); // 设置响应头可以看到
|
||||||
|
// },
|
||||||
|
// onProxyRes(proxyRes, req, res) {
|
||||||
|
// const realUrl = process.env.BASEURL + req.url || ''; // 真实请求网址
|
||||||
|
// console.log(realUrl); // 在终端显示
|
||||||
|
// proxyRes.headers['A-Real-Url'] = realUrl; // 添加响应标头(A-Real-Url为自定义命名),在浏览器中显示
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// },
|
||||||
|
devServer: {
|
||||||
|
port:'80',
|
||||||
|
proxy: {
|
||||||
|
"/api": {
|
||||||
|
// 需要被代理的后台地址
|
||||||
|
"target": "https://cashier-client.sxczgkj.cn/cashier-client",
|
||||||
|
"changeOrigin": true,
|
||||||
|
"secure": false,
|
||||||
|
"pathRewrite": {
|
||||||
|
"/api": ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
configureWebpack: {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue