初始化仓库
This commit is contained in:
90
utils/audio.ts
Normal file
90
utils/audio.ts
Normal file
@@ -0,0 +1,90 @@
|
||||
/**
|
||||
* 这是Fnaudio方法的必选参数约束
|
||||
*/
|
||||
type FunTypeAudioRequired = {
|
||||
/**
|
||||
* 音频的数据链接,用于直接播放。
|
||||
*/
|
||||
readonly src : string,
|
||||
/**
|
||||
* 是否自动开始播放,默认 true
|
||||
*/
|
||||
readonly autoplay ?:boolean ,
|
||||
/**
|
||||
* 是否遵循系统静音开关,
|
||||
* 当此参数为 false 时,即使用户打开了静音开关,也能继续发出声音,
|
||||
* 默认值 true
|
||||
*/
|
||||
readonly obeyMuteSwitch ?:boolean,
|
||||
/**
|
||||
* 开始播放的位置(单位:s),默认 0
|
||||
*/
|
||||
readonly startTime ?: number,
|
||||
/**
|
||||
* 是否循环播放,默认 false
|
||||
*/
|
||||
readonly loop ?: boolean,
|
||||
/**
|
||||
* 音量。范围 0~1
|
||||
*/
|
||||
readonly volume ?: number,
|
||||
/**
|
||||
* 播放的倍率。可取值:0.5/0.8/1.0/1.25/1.5/2.0,默认值为1.0
|
||||
*/
|
||||
readonly playbackRate ?: 0.5|0.8|1.0|1.25|1.5|2.0
|
||||
}
|
||||
|
||||
/**
|
||||
* 封装提示音的方法类
|
||||
*/
|
||||
class Audio {
|
||||
constructor(required : FunTypeAudioRequired ){
|
||||
if (required?.volume != undefined && (required.volume < 0 || required.volume > 1)) {
|
||||
throw new Error('提供的volume值不符合规范');
|
||||
}
|
||||
let innerAudioContext = uni.createInnerAudioContext();
|
||||
innerAudioContext = Object.assign(innerAudioContext,required)
|
||||
innerAudioContext.onPlay(() => {
|
||||
console.log('开始播放');
|
||||
});
|
||||
setTimeout(() => {
|
||||
innerAudioContext.stop()
|
||||
innerAudioContext.destroy()
|
||||
console.log(',销毁实例')
|
||||
}, 900);
|
||||
innerAudioContext.onError((res) => {
|
||||
console.error(res.errMsg);
|
||||
console.error(res.errCode);
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 成功提示音
|
||||
* @return
|
||||
*/
|
||||
export function autioSuccess():void {
|
||||
let audio = null;
|
||||
audio = new Audio({
|
||||
src:'/static/audio/success.mp3',
|
||||
playbackRate:2,
|
||||
autoplay : true,
|
||||
volume : 1,
|
||||
})
|
||||
audio = null
|
||||
}
|
||||
/**
|
||||
* 失败提示音
|
||||
* @return
|
||||
*/
|
||||
export function autioError():void {
|
||||
let audio = null;
|
||||
audio = new Audio({
|
||||
src:'/static/audio/error.mp3',
|
||||
playbackRate:2,
|
||||
autoplay : true,
|
||||
volume : 1,
|
||||
})
|
||||
audio = null
|
||||
}
|
||||
13
utils/auth.js
Normal file
13
utils/auth.js
Normal file
@@ -0,0 +1,13 @@
|
||||
const TokenKey = 'App-Token'
|
||||
|
||||
export function getToken() {
|
||||
return uni.getStorageSync(TokenKey)
|
||||
}
|
||||
|
||||
export function setToken(token) {
|
||||
return uni.setStorageSync(TokenKey, token)
|
||||
}
|
||||
|
||||
export function removeToken() {
|
||||
return uni.removeStorageSync(TokenKey)
|
||||
}
|
||||
55
utils/common.js
Normal file
55
utils/common.js
Normal file
@@ -0,0 +1,55 @@
|
||||
/**
|
||||
* 显示消息提示框
|
||||
* @param content 提示的标题
|
||||
*/
|
||||
export function toast(content) {
|
||||
uni.showToast({
|
||||
icon: 'none',
|
||||
title: content,
|
||||
duration: 2000,
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 显示模态弹窗
|
||||
* @param content 提示的标题
|
||||
*/
|
||||
export function showConfirm(content) {
|
||||
return new Promise((resolve, reject) => {
|
||||
uni.showModal({
|
||||
title: '提示',
|
||||
content: content,
|
||||
cancelText: '取消',
|
||||
confirmText: '确定',
|
||||
success: function(res) {
|
||||
resolve(res)
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 参数处理
|
||||
* @param params 参数
|
||||
*/
|
||||
export function tansParams(params) {
|
||||
let result = ''
|
||||
for (const propName of Object.keys(params)) {
|
||||
const value = params[propName]
|
||||
var part = encodeURIComponent(propName) + "="
|
||||
if (value !== null && value !== "" && typeof (value) !== "undefined") {
|
||||
if (typeof value === 'object') {
|
||||
for (const key of Object.keys(value)) {
|
||||
if (value[key] !== null && value[key] !== "" && typeof (value[key]) !== 'undefined') {
|
||||
let params = propName + '[' + key + ']'
|
||||
var subPart = encodeURIComponent(params) + "="
|
||||
result += subPart + encodeURIComponent(value[key]) + "&"
|
||||
}
|
||||
}
|
||||
} else {
|
||||
result += part + encodeURIComponent(value) + "&"
|
||||
}
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
14
utils/constant.js
Normal file
14
utils/constant.js
Normal file
@@ -0,0 +1,14 @@
|
||||
const constant = {
|
||||
avatar: 'vuex_avatar',
|
||||
name: 'vuex_name',
|
||||
code: 'vuex_code',
|
||||
roles: 'vuex_roles',
|
||||
permissions: 'vuex_permissions',
|
||||
empId: 'vuex_emp_id',
|
||||
empName: 'vuex_emp_name',
|
||||
empCode: 'vuex_emp_code',
|
||||
empDeptId: 'vuex_emp_dept_id',
|
||||
empDeptName: 'vuex_emp_dept_name',
|
||||
}
|
||||
|
||||
export default constant
|
||||
6
utils/errorCode.js
Normal file
6
utils/errorCode.js
Normal file
@@ -0,0 +1,6 @@
|
||||
export default {
|
||||
'401': '认证失败,无法访问系统资源',
|
||||
'403': '当前操作没有权限',
|
||||
'404': '访问资源不存在',
|
||||
'default': '系统未知错误,请反馈给管理员'
|
||||
}
|
||||
28
utils/judge.ts
Normal file
28
utils/judge.ts
Normal file
@@ -0,0 +1,28 @@
|
||||
/**
|
||||
* 判断传入的值是否有值(不为null,'',undefined)
|
||||
* 有则返回true,没有则返回false
|
||||
* @param {number | string | object} value
|
||||
* @return boolean
|
||||
*/
|
||||
export function hasValue(value : number | string | { [key: string]: any}):boolean{
|
||||
if(typeof value == 'number' || typeof value == 'string'){
|
||||
if(value != null && value != '' && value != undefined) return true
|
||||
}
|
||||
if(typeof value === 'object'){
|
||||
for(let i in value){
|
||||
if(value[i] != null && value[i] != '' && value[i] != undefined) return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前北京时间
|
||||
* @return
|
||||
*/
|
||||
export function getBeijingTime():string{
|
||||
//获取当前北京时间的时间戳(单位为毫秒)
|
||||
const stamp= new Date().getTime() + 8 * 60 * 60 * 1000;
|
||||
const beijingTime = new Date(stamp).toISOString().replace(/T/, ' ').replace(/\..+/, '').substring(0, 19);
|
||||
return beijingTime
|
||||
}
|
||||
94
utils/loding/loding.vue
Normal file
94
utils/loding/loding.vue
Normal file
@@ -0,0 +1,94 @@
|
||||
<template>
|
||||
<div class="ring">
|
||||
加载中
|
||||
<span></span>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
</script>
|
||||
|
||||
<style>
|
||||
body{
|
||||
margin:0;
|
||||
padding:0;
|
||||
background:#262626;
|
||||
font-family:sans-serif;
|
||||
font-size:20px;
|
||||
}
|
||||
|
||||
.ring{
|
||||
position:absolute;
|
||||
top:50%;
|
||||
left:50%;
|
||||
transform:translate(-50%, -50%);
|
||||
width:150px;
|
||||
height:150px;
|
||||
border:3px solid #3d3d3d;
|
||||
border-radius:50%;
|
||||
text-align:center;
|
||||
line-height:150px;
|
||||
letter-spacing:4px;
|
||||
text-transform:uppercase;
|
||||
color:#fff000;
|
||||
text-shadow:0 0 15px #fff000;
|
||||
box-shadow:0 0 20px rgba(0,0,0,.5);
|
||||
}
|
||||
.ring:before{
|
||||
content:'';
|
||||
display:block;
|
||||
position:absolute;
|
||||
top:-3px;
|
||||
left:-3px;
|
||||
width:100%;
|
||||
height:100%;
|
||||
border:3px solid transparent;
|
||||
border-top:3px solid #fff000;
|
||||
border-left:3px solid transparent;
|
||||
border-right:3px solid #fff000;
|
||||
border-radius:50%;
|
||||
animation:ani-cyle 2s linear infinite;
|
||||
}
|
||||
span{
|
||||
position:absolute;
|
||||
width:50%;
|
||||
height:4px;
|
||||
display:block;
|
||||
top:calc(50% - 2px);
|
||||
left:50%;
|
||||
background:none;
|
||||
animation:animate 2s linear infinite;
|
||||
transform-origin:left;
|
||||
}
|
||||
span:after{
|
||||
content:'';
|
||||
width:16px;
|
||||
height:16px;
|
||||
background:#fff000;
|
||||
border-radius:50%;
|
||||
box-shadow: 0 0 20px #fff000;
|
||||
position:absolute;
|
||||
right:-8px;
|
||||
top:calc(50% - 8px);
|
||||
}
|
||||
|
||||
@keyframes ani-cyle{
|
||||
0%{
|
||||
transform:rotate(0deg);
|
||||
}
|
||||
100%{
|
||||
transform:rotate(360deg);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@keyframes animate{
|
||||
0%{
|
||||
transform:rotate(45deg);
|
||||
}
|
||||
100%{
|
||||
transform:rotate(405deg);
|
||||
}
|
||||
|
||||
}
|
||||
</style>
|
||||
109
utils/parseRelease.js
Normal file
109
utils/parseRelease.js
Normal file
@@ -0,0 +1,109 @@
|
||||
function getBeijingTime(date = new Date()) {
|
||||
const f = n => String(n).padStart(2, '0');
|
||||
const t = new Date(date.toLocaleString('en-US', { timeZone: 'Asia/Shanghai' }));
|
||||
return `${t.getFullYear()}-${f(t.getMonth()+1)}-${f(t.getDate())} ${f(t.getHours())}:${f(t.getMinutes())}:${f(t.getSeconds())}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取最新发布版本信息
|
||||
* @param {Array} releases - 发布版本数组
|
||||
* @param {Object} options - 配置项
|
||||
* @param {boolean} options.includePrerelease - 是否包含预发布版(默认 true)
|
||||
* @returns {Object|null} 最新版本信息
|
||||
*/
|
||||
export function getLatestRelease(releases, options = {}) {
|
||||
const { includePrerelease = true } = options;
|
||||
|
||||
try {
|
||||
if (!Array.isArray(releases)) {
|
||||
throw new Error("参数错误:releases 必须是数组");
|
||||
}
|
||||
if (releases.length === 0) {
|
||||
throw new Error("没有可用的版本数据");
|
||||
}
|
||||
|
||||
// 过滤掉预发布(如果不包含)
|
||||
let filtered = releases;
|
||||
if (!includePrerelease) {
|
||||
filtered = releases.filter(r => !r.prerelease);
|
||||
if (filtered.length === 0) {
|
||||
throw new Error("没有找到正式版版本数据");
|
||||
}
|
||||
}
|
||||
|
||||
// 按发布时间排序,取最新的
|
||||
const latest = filtered.sort((a, b) =>
|
||||
new Date(b.published_at) - new Date(a.published_at)
|
||||
)[0];
|
||||
|
||||
if (!latest) {
|
||||
throw new Error("无法找到最新版本");
|
||||
}
|
||||
|
||||
return {
|
||||
latestVersion: latest.tag_name.replace('v', '') || null,
|
||||
download_url: latest.assets?.[0]?.browser_download_url.replace('192.168.1.132:3000', '223.94.45.156:10830') ||
|
||||
null,
|
||||
prerelease: latest.prerelease,
|
||||
published_at: latest.published_at || null,
|
||||
title: latest.name || "",
|
||||
description: latest.body || ""
|
||||
};
|
||||
|
||||
} catch (error) {
|
||||
console.error("获取最新版本出错:", error.message);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
export function getReleases(releases, options = {}) {
|
||||
const { includePrerelease = true } = options;
|
||||
|
||||
try {
|
||||
if (!Array.isArray(releases)) {
|
||||
throw new Error("参数错误:releases 必须是数组");
|
||||
}
|
||||
if (releases.length === 0) {
|
||||
throw new Error("没有可用的版本数据");
|
||||
}
|
||||
|
||||
// 过滤掉预发布(如果不包含)
|
||||
let filtered = releases;
|
||||
if (!includePrerelease) {
|
||||
filtered = releases.filter(r => !r.prerelease);
|
||||
if (filtered.length === 0) {
|
||||
throw new Error("没有找到正式版版本数据");
|
||||
}
|
||||
}
|
||||
|
||||
// 按发布时间排序
|
||||
filtered.sort((a, b) =>
|
||||
new Date(b.published_at) - new Date(a.published_at)
|
||||
);
|
||||
|
||||
let renderedReleases = [];
|
||||
filtered.forEach(item => {
|
||||
renderedReleases.push({
|
||||
version: item.tag_name.replace('v', '') || null,
|
||||
download_url: item.assets?.[0]?.browser_download_url.replace('192.168.1.132:3000',
|
||||
'223.94.45.156:10830') ||
|
||||
null,
|
||||
prerelease: item.prerelease,
|
||||
published_at: getBeijingTime(new Date(item.published_at || null)) || null,
|
||||
title: item.name || "",
|
||||
description: item.body || ""
|
||||
})
|
||||
});
|
||||
console.log(filtered);
|
||||
console.log(renderedReleases);
|
||||
return renderedReleases;
|
||||
|
||||
} catch (error) {
|
||||
uni.showToast({
|
||||
title: "获取版本列表出错",
|
||||
icon: 'none'
|
||||
});
|
||||
console.error("获取版本列表出错:", error);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
50
utils/permission.js
Normal file
50
utils/permission.js
Normal file
@@ -0,0 +1,50 @@
|
||||
import store from '@/store'
|
||||
|
||||
/**
|
||||
* 字符权限校验
|
||||
* @param {Array} value 校验值
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
export function checkPermi(value) {
|
||||
if (value && value instanceof Array && value.length > 0) {
|
||||
const permissions = store.getters && store.getters.permissions
|
||||
const permissionDatas = value
|
||||
const all_permission = "*:*:*"
|
||||
|
||||
const hasPermission = permissions.some(permission => {
|
||||
return all_permission === permission || permissionDatas.includes(permission)
|
||||
})
|
||||
if (!hasPermission) {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
} else {
|
||||
console.error(`need roles! Like checkPermi="['system:user:add','system:user:edit']"`)
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 角色权限校验
|
||||
* @param {Array} value 校验值
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
export function checkRole(value) {
|
||||
if (value && value instanceof Array && value.length > 0) {
|
||||
const roles = store.getters && store.getters.roles
|
||||
const permissionRoles = value
|
||||
const super_admin = "admin"
|
||||
|
||||
const hasRole = roles.some(role => {
|
||||
return super_admin === role || permissionRoles.includes(role)
|
||||
})
|
||||
|
||||
if (!hasRole) {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
} else {
|
||||
console.error(`need roles! Like checkRole="['admin','editor']"`)
|
||||
return false
|
||||
}
|
||||
}
|
||||
91
utils/request.js
Normal file
91
utils/request.js
Normal file
@@ -0,0 +1,91 @@
|
||||
import store from '@/store'
|
||||
import config from '@/config'
|
||||
import {
|
||||
getToken
|
||||
} from '@/utils/auth'
|
||||
import errorCode from '@/utils/errorCode'
|
||||
import {
|
||||
toast,
|
||||
showConfirm,
|
||||
tansParams
|
||||
} from '@/utils/common'
|
||||
|
||||
let timeout = 60 * 2 * 1000
|
||||
const baseUrl = config.baseUrl
|
||||
|
||||
const request = config => {
|
||||
|
||||
// let baseUrlTemp = (uni.getStorageSync("base_url") || config.baseUrl || baseUrl)
|
||||
//双菱
|
||||
let baseUrlTemp = (uni.getStorageSync("base_url") || config.baseUrl || baseUrl) + '/wc-mes'
|
||||
|
||||
// 是否需要设置 token
|
||||
const isToken = (config.headers || {}).isToken === false
|
||||
config.header = config.header || {}
|
||||
if (getToken() && !isToken) {
|
||||
config.header['Authorization'] = 'Bearer ' + getToken()
|
||||
}
|
||||
// get请求映射params参数
|
||||
if (config.params) {
|
||||
let url = config.url + '?' + tansParams(config.params)
|
||||
url = url.slice(0, -1)
|
||||
config.url = url
|
||||
}
|
||||
return new Promise((resolve, reject) => {
|
||||
uni.request({
|
||||
method: config.method || 'get',
|
||||
timeout: config.timeout || timeout,
|
||||
url: baseUrlTemp + config.url,
|
||||
data: config.data,
|
||||
header: config.header,
|
||||
dataType: 'json'
|
||||
}).then(response => {
|
||||
let [error, res] = response
|
||||
if (error) {
|
||||
toast('后端接口连接异常')
|
||||
reject('后端接口连接异常')
|
||||
return
|
||||
}
|
||||
const code = res.data.code || 200
|
||||
const msg = errorCode[code] || res.data.msg || errorCode['default']
|
||||
if (code === 401) {
|
||||
showConfirm('登录状态已过期,您可以继续留在该页面,或者重新登录?').then(res => {
|
||||
if (res.confirm) {
|
||||
store.dispatch('LogOut').then(res => {
|
||||
uni.reLaunch({
|
||||
url: '/pages/login'
|
||||
})
|
||||
})
|
||||
}
|
||||
})
|
||||
reject('无效的会话,或者会话已过期,请重新登录。')
|
||||
} else if (code === 500) {
|
||||
toast(msg)
|
||||
reject({
|
||||
code: 500,
|
||||
msg
|
||||
})
|
||||
} else if (code !== 200) {
|
||||
toast(msg)
|
||||
reject(code)
|
||||
}
|
||||
resolve(res.data)
|
||||
})
|
||||
.catch(error => {
|
||||
let {
|
||||
message
|
||||
} = error
|
||||
if (message === 'Network Error') {
|
||||
message = '后端接口连接异常'
|
||||
} else if (message.includes('timeout')) {
|
||||
message = '系统接口请求超时'
|
||||
} else if (message.includes('Request failed with status code')) {
|
||||
message = '系统接口' + message.substr(message.length - 3) + '异常'
|
||||
}
|
||||
toast(message)
|
||||
reject(error)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
export default request
|
||||
44
utils/storage.js
Normal file
44
utils/storage.js
Normal file
@@ -0,0 +1,44 @@
|
||||
import constant from './constant'
|
||||
|
||||
// 存储变量名
|
||||
let storageKey = 'storage_data'
|
||||
|
||||
// 存储节点变量名
|
||||
let storageNodeKeys = [
|
||||
constant.avatar,
|
||||
constant.name,
|
||||
constant.code,
|
||||
constant.roles,
|
||||
constant.permissions,
|
||||
constant.empId,
|
||||
constant.empName,
|
||||
constant.empCode,
|
||||
constant.empDeptId,
|
||||
constant.empDeptName,
|
||||
]
|
||||
|
||||
// 存储的数据
|
||||
let storageData = uni.getStorageSync(storageKey) || {}
|
||||
|
||||
const storage = {
|
||||
set: function(key, value) {
|
||||
if (storageNodeKeys.indexOf(key) != -1) {
|
||||
let tmp = uni.getStorageSync(storageKey)
|
||||
tmp = tmp ? tmp : {}
|
||||
tmp[key] = value
|
||||
uni.setStorageSync(storageKey, tmp)
|
||||
}
|
||||
},
|
||||
get: function(key) {
|
||||
return storageData[key] || ""
|
||||
},
|
||||
remove: function(key) {
|
||||
delete storageData[key]
|
||||
uni.setStorageSync(storageKey, storageData)
|
||||
},
|
||||
clean: function() {
|
||||
uni.removeStorageSync(storageKey)
|
||||
}
|
||||
}
|
||||
|
||||
export default storage
|
||||
278
utils/uniapp/utils-uni-popup-dialog.vue
Normal file
278
utils/uniapp/utils-uni-popup-dialog.vue
Normal file
@@ -0,0 +1,278 @@
|
||||
<template>
|
||||
<view class="uni-popup-dialog">
|
||||
<view class="uni-dialog-title">
|
||||
<text class="uni-dialog-title-text" :class="['uni-popup__'+dialogType]">{{titleText}}</text>
|
||||
</view>
|
||||
<view v-if="mode === 'base'" class="uni-dialog-content">
|
||||
<slot>
|
||||
<text class="uni-dialog-content-text">{{content}}</text>
|
||||
</slot>
|
||||
</view>
|
||||
<view v-else class="uni-dialog-content">
|
||||
<slot>
|
||||
<input class="uni-dialog-input" v-model="val" type="text" :placeholder="placeholderText" :focus="focus">
|
||||
</slot>
|
||||
</view>
|
||||
<view class="uni-dialog-button-group">
|
||||
<view class="uni-dialog-button" @click="closeDialog" v-if="showClose">
|
||||
<text class="uni-dialog-button-text">{{closeText}}</text>
|
||||
</view>
|
||||
<view class="uni-dialog-button uni-border-left" @click="onOk">
|
||||
<text class="uni-dialog-button-text uni-button-color">{{okText}}</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
initVueI18n
|
||||
} from '@dcloudio/uni-i18n'
|
||||
import popup from '@/uni_modules/uni-popup/components/uni-popup/popup.js'
|
||||
import messages from '@/uni_modules/uni-popup/components/uni-popup/i18n/index.js'
|
||||
const {
|
||||
t
|
||||
} = initVueI18n(messages)
|
||||
/**
|
||||
* PopUp 弹出层-对话框样式
|
||||
* @description 弹出层-对话框样式
|
||||
* @tutorial https://ext.dcloud.net.cn/plugin?id=329
|
||||
* @property {String} value input 模式下的默认值
|
||||
* @property {String} placeholder input 模式下输入提示
|
||||
* @property {String} type = [success|warning|info|error] 主题样式
|
||||
* @value success 成功
|
||||
* @value warning 提示
|
||||
* @value info 消息
|
||||
* @value error 错误
|
||||
* @property {String} mode = [base|input] 模式、
|
||||
* @value base 基础对话框
|
||||
* @value input 可输入对话框
|
||||
* @property {String} content 对话框内容
|
||||
* @property {Boolean} beforeClose 是否拦截取消事件
|
||||
* @event {Function} confirm 点击确认按钮触发
|
||||
* @event {Function} close 点击取消按钮触发
|
||||
* @event {Boolean} showClose 是否显示取消按钮
|
||||
*/
|
||||
|
||||
export default {
|
||||
name: "uniPopupDialog",
|
||||
mixins: [popup],
|
||||
emits: ['confirm', 'close'],
|
||||
props: {
|
||||
value: {
|
||||
type: [String, Number],
|
||||
default: ''
|
||||
},
|
||||
placeholder: {
|
||||
type: [String, Number],
|
||||
default: ''
|
||||
},
|
||||
type: {
|
||||
type: String,
|
||||
default: 'error'
|
||||
},
|
||||
mode: {
|
||||
type: String,
|
||||
default: 'base'
|
||||
},
|
||||
title: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
content: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
beforeClose: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
cancelText: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
confirmText: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
showClose:{
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
dialogType: 'error',
|
||||
focus: false,
|
||||
val: ""
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
okText() {
|
||||
return this.confirmText || t("uni-popup.ok")
|
||||
},
|
||||
closeText() {
|
||||
return this.cancelText || t("uni-popup.cancel")
|
||||
},
|
||||
placeholderText() {
|
||||
return this.placeholder || t("uni-popup.placeholder")
|
||||
},
|
||||
titleText() {
|
||||
return this.title || t("uni-popup.title")
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
type(val) {
|
||||
this.dialogType = val
|
||||
},
|
||||
mode(val) {
|
||||
if (val === 'input') {
|
||||
this.dialogType = 'info'
|
||||
}
|
||||
},
|
||||
value(val) {
|
||||
this.val = val
|
||||
}
|
||||
},
|
||||
created() {
|
||||
// 对话框遮罩不可点击
|
||||
this.popup.disableMask()
|
||||
// this.popup.closeMask()
|
||||
if (this.mode === 'input') {
|
||||
this.dialogType = 'info'
|
||||
this.val = this.value
|
||||
} else {
|
||||
this.dialogType = this.type
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.focus = true
|
||||
},
|
||||
methods: {
|
||||
/**
|
||||
* 点击确认按钮
|
||||
*/
|
||||
onOk() {
|
||||
if (this.mode === 'input') {
|
||||
this.$emit('confirm', this.val)
|
||||
} else {
|
||||
this.$emit('confirm')
|
||||
}
|
||||
if (this.beforeClose) return
|
||||
// this.popup.close()
|
||||
},
|
||||
/**
|
||||
* 点击取消按钮
|
||||
*/
|
||||
closeDialog() {
|
||||
this.$emit('close')
|
||||
if (this.beforeClose) return
|
||||
this.popup.close()
|
||||
},
|
||||
close() {
|
||||
this.popup.close()
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.uni-popup-dialog {
|
||||
width: 300px;
|
||||
border-radius: 11px;
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
.uni-dialog-title {
|
||||
/* #ifndef APP-NVUE */
|
||||
display: flex;
|
||||
/* #endif */
|
||||
flex-direction: row;
|
||||
justify-content: center;
|
||||
padding-top: 25px;
|
||||
}
|
||||
|
||||
.uni-dialog-title-text {
|
||||
font-size: 16px;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.uni-dialog-content {
|
||||
/* #ifndef APP-NVUE */
|
||||
display: flex;
|
||||
/* #endif */
|
||||
flex-direction: row;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.uni-dialog-content-text {
|
||||
font-size: 14px;
|
||||
color: #6C6C6C;
|
||||
}
|
||||
|
||||
.uni-dialog-button-group {
|
||||
/* #ifndef APP-NVUE */
|
||||
display: flex;
|
||||
/* #endif */
|
||||
flex-direction: row;
|
||||
border-top-color: #f5f5f5;
|
||||
border-top-style: solid;
|
||||
border-top-width: 1px;
|
||||
}
|
||||
|
||||
.uni-dialog-button {
|
||||
/* #ifndef APP-NVUE */
|
||||
display: flex;
|
||||
/* #endif */
|
||||
|
||||
flex: 1;
|
||||
flex-direction: row;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 45px;
|
||||
}
|
||||
|
||||
.uni-border-left {
|
||||
border-left-color: #f0f0f0;
|
||||
border-left-style: solid;
|
||||
border-left-width: 1px;
|
||||
}
|
||||
|
||||
.uni-dialog-button-text {
|
||||
font-size: 16px;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.uni-button-color {
|
||||
color: #007aff;
|
||||
}
|
||||
|
||||
.uni-dialog-input {
|
||||
flex: 1;
|
||||
font-size: 14px;
|
||||
border: 1px #eee solid;
|
||||
height: 40px;
|
||||
padding: 0 10px;
|
||||
border-radius: 5px;
|
||||
color: #555;
|
||||
}
|
||||
|
||||
.uni-popup__success {
|
||||
color: #4cd964;
|
||||
}
|
||||
|
||||
.uni-popup__warn {
|
||||
color: #f0ad4e;
|
||||
}
|
||||
|
||||
.uni-popup__error {
|
||||
color: #dd524d;
|
||||
}
|
||||
|
||||
.uni-popup__info {
|
||||
color: #909399;
|
||||
}
|
||||
</style>
|
||||
606
utils/uniapp/utilsInput.vue
Normal file
606
utils/uniapp/utilsInput.vue
Normal file
@@ -0,0 +1,606 @@
|
||||
<template>
|
||||
<view class="uni-easyinput" :class="{'uni-easyinput-error':msg}" :style="boxStyle">
|
||||
<view class="uni-easyinput__content" :class="inputContentClass" :style="inputContentStyle">
|
||||
<uni-icons v-if="prefixIcon" class="content-clear-icon" :type="prefixIcon" color="#c0c4cc"
|
||||
@click="onClickIcon('prefix')" size="22"></uni-icons>
|
||||
<textarea v-if="type === 'textarea'" class="uni-easyinput__content-textarea"
|
||||
:class="{'input-padding':inputBorder}" :name="name" :value="val" :placeholder="placeholder"
|
||||
:placeholderStyle="placeholderStyle" :disabled="disabled"
|
||||
placeholder-class="uni-easyinput__placeholder-class" :maxlength="inputMaxlength" :focus="focused"
|
||||
:autoHeight="autoHeight" @input="onInput" @blur="_Blur" @focus="_Focus" @confirm="onConfirm"></textarea>
|
||||
<input v-else :type="type === 'password'?'text':type" class="uni-easyinput__content-input"
|
||||
:style="inputStyle" :name="name" :value="val" :password="!showPassword && type === 'password'"
|
||||
:placeholder="placeholder" :placeholderStyle="placeholderStyle"
|
||||
placeholder-class="uni-easyinput__placeholder-class" :disabled="disabled" :maxlength="inputMaxlength"
|
||||
:focus="focused" :confirmType="confirmType" @focus="_Focus" @blur="_Blur" @input="onInput"
|
||||
@confirm="onConfirm" @click="clickInput" />
|
||||
<template v-if="type === 'password' && passwordIcon">
|
||||
<!-- 开启密码时显示小眼睛 -->
|
||||
<uni-icons v-if="isVal" class="content-clear-icon" :class="{'is-textarea-icon':type==='textarea'}"
|
||||
:type="showPassword?'eye-slash-filled':'eye-filled'" :size="22"
|
||||
:color="focusShow?'#2979ff':'#c0c4cc'" @click="onEyes">
|
||||
</uni-icons>
|
||||
</template>
|
||||
<template v-else-if="suffixIcon">
|
||||
<uni-icons v-if="suffixIcon" class="content-clear-icon" :type="suffixIcon" color="#c0c4cc"
|
||||
@click="onClickIcon('suffix')" size="22"></uni-icons>
|
||||
</template>
|
||||
<template v-else>
|
||||
<uni-icons v-if="clearable && isVal && !disabled && type !== 'textarea'" class="content-clear-icon"
|
||||
:class="{'is-textarea-icon':type==='textarea'}" type="clear" :size="clearSize"
|
||||
:color="msg?'#dd524d':(focusShow?'#2979ff':'#c0c4cc')" @click="onClear"></uni-icons>
|
||||
</template>
|
||||
<slot name="right"></slot>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
/**
|
||||
* Easyinput 输入框
|
||||
* @description 此组件可以实现表单的输入与校验,包括 "text" 和 "textarea" 类型。
|
||||
* @tutorial https://ext.dcloud.net.cn/plugin?id=3455
|
||||
* @property {String} value 输入内容
|
||||
* @property {String } type 输入框的类型(默认text) password/text/textarea/..
|
||||
* @value text 文本输入键盘
|
||||
* @value textarea 多行文本输入键盘
|
||||
* @value password 密码输入键盘
|
||||
* @value number 数字输入键盘,注意iOS上app-vue弹出的数字键盘并非9宫格方式
|
||||
* @value idcard 身份证输入键盘,信、支付宝、百度、QQ小程序
|
||||
* @value digit 带小数点的数字键盘 ,App的nvue页面、微信、支付宝、百度、头条、QQ小程序支持
|
||||
* @property {Boolean} clearable 是否显示右侧清空内容的图标控件,点击可清空输入框内容(默认true)
|
||||
* @property {Boolean} autoHeight 是否自动增高输入区域,type为textarea时有效(默认true)
|
||||
* @property {String } placeholder 输入框的提示文字
|
||||
* @property {String } placeholderStyle placeholder的样式(内联样式,字符串),如"color: #ddd"
|
||||
* @property {Boolean} focus 是否自动获得焦点(默认false)
|
||||
* @property {Boolean} disabled 是否禁用(默认false)
|
||||
* @property {Number } maxlength 最大输入长度,设置为 -1 的时候不限制最大长度(默认140)
|
||||
* @property {String } confirmType 设置键盘右下角按钮的文字,仅在type="text"时生效(默认done)
|
||||
* @property {Number } clearSize 清除图标的大小,单位px(默认15)
|
||||
* @property {String} prefixIcon 输入框头部图标
|
||||
* @property {String} suffixIcon 输入框尾部图标
|
||||
* @property {Boolean} trim 是否自动去除两端的空格
|
||||
* @value both 去除两端空格
|
||||
* @value left 去除左侧空格
|
||||
* @value right 去除右侧空格
|
||||
* @value start 去除左侧空格
|
||||
* @value end 去除右侧空格
|
||||
* @value all 去除全部空格
|
||||
* @value none 不去除空格
|
||||
* @property {Boolean} inputBorder 是否显示input输入框的边框(默认true)
|
||||
* @property {Boolean} passwordIcon type=password时是否显示小眼睛图标
|
||||
* @property {Object} styles 自定义颜色
|
||||
* @event {Function} input 输入框内容发生变化时触发
|
||||
* @event {Function} focus 输入框获得焦点时触发
|
||||
* @event {Function} blur 输入框失去焦点时触发
|
||||
* @event {Function} confirm 点击完成按钮时触发
|
||||
* @event {Function} iconClick 点击图标时触发
|
||||
* @example <uni-easyinput v-model="mobile"></uni-easyinput>
|
||||
*/
|
||||
function obj2strClass(obj) {
|
||||
let classess = ''
|
||||
for (let key in obj) {
|
||||
const val = obj[key]
|
||||
if (val) {
|
||||
classess += `${key} `
|
||||
}
|
||||
}
|
||||
return classess
|
||||
}
|
||||
|
||||
function obj2strStyle(obj) {
|
||||
let style = ''
|
||||
for (let key in obj) {
|
||||
const val = obj[key]
|
||||
style += `${key}:${val};`
|
||||
}
|
||||
return style
|
||||
}
|
||||
export default {
|
||||
name: 'uni-easyinput',
|
||||
emits: ['click', 'iconClick', 'update:modelValue', 'input', 'focus', 'blur', 'confirm', 'clear', 'eyes', 'change'],
|
||||
model: {
|
||||
prop: 'modelValue',
|
||||
event: 'update:modelValue'
|
||||
},
|
||||
options: {
|
||||
virtualHost: true
|
||||
},
|
||||
inject: {
|
||||
form: {
|
||||
from: 'uniForm',
|
||||
default: null
|
||||
},
|
||||
formItem: {
|
||||
from: 'uniFormItem',
|
||||
default: null
|
||||
},
|
||||
},
|
||||
props: {
|
||||
name: String,
|
||||
value: [Number, String],
|
||||
modelValue: [Number, String],
|
||||
type: {
|
||||
type: String,
|
||||
default: 'text'
|
||||
},
|
||||
clearable: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
autoHeight: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
placeholder: {
|
||||
type: String,
|
||||
default: ' '
|
||||
},
|
||||
placeholderStyle: String,
|
||||
focus: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
disabled: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
maxlength: {
|
||||
type: [Number, String],
|
||||
default: 140
|
||||
},
|
||||
confirmType: {
|
||||
type: String,
|
||||
default: 'done'
|
||||
},
|
||||
clearSize: {
|
||||
type: [Number, String],
|
||||
default: 24
|
||||
},
|
||||
inputBorder: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
prefixIcon: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
suffixIcon: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
trim: {
|
||||
type: [Boolean, String],
|
||||
default: true
|
||||
},
|
||||
passwordIcon: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
styles: {
|
||||
type: Object,
|
||||
default () {
|
||||
return {
|
||||
color: '#333',
|
||||
disableColor: '#F7F6F6',
|
||||
borderColor: '#e5e5e5'
|
||||
}
|
||||
}
|
||||
},
|
||||
errorMessage: {
|
||||
type: [String, Boolean],
|
||||
default: ''
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
focused: false,
|
||||
val: '',
|
||||
showMsg: '',
|
||||
border: false,
|
||||
isFirstBorder: false,
|
||||
showClearIcon: false,
|
||||
showPassword: false,
|
||||
focusShow: false,
|
||||
localMsg: '',
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
// 输入框内是否有值
|
||||
isVal() {
|
||||
const val = this.val
|
||||
// fixed by mehaotian 处理值为0的情况,字符串0不在处理范围
|
||||
if (val || val === 0) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
},
|
||||
|
||||
msg() {
|
||||
// console.log('computed', this.form, this.formItem);
|
||||
// if (this.form) {
|
||||
// return this.errorMessage || this.formItem.errMsg;
|
||||
// }
|
||||
// TODO 处理头条 formItem 中 errMsg 不更新的问题
|
||||
return this.localMsg || this.errorMessage
|
||||
},
|
||||
// 因为uniapp的input组件的maxlength组件必须要数值,这里转为数值,用户可以传入字符串数值
|
||||
inputMaxlength() {
|
||||
return Number(this.maxlength);
|
||||
},
|
||||
|
||||
// 处理外层样式的style
|
||||
boxStyle() {
|
||||
return `color:${this.inputBorder && this.msg?'#e43d33':this.styles.color};`
|
||||
},
|
||||
// input 内容的类和样式处理
|
||||
inputContentClass() {
|
||||
return obj2strClass({
|
||||
'is-input-border': this.inputBorder,
|
||||
'is-input-error-border': this.inputBorder && this.msg,
|
||||
'is-textarea': this.type === 'textarea',
|
||||
'is-disabled': this.disabled
|
||||
})
|
||||
},
|
||||
inputContentStyle() {
|
||||
const focusColor = this.focusShow ? '#2979ff' : this.styles.borderColor
|
||||
const borderColor = this.inputBorder && this.msg ? '#dd524d' : focusColor
|
||||
return obj2strStyle({
|
||||
'border-color': borderColor || '#e5e5e5',
|
||||
'background-color': this.disabled ? this.styles.disableColor : '#fff'
|
||||
})
|
||||
},
|
||||
// input右侧样式
|
||||
inputStyle() {
|
||||
const paddingRight = this.type === 'password' || this.clearable || this.prefixIcon ? '' : '10px'
|
||||
return obj2strStyle({
|
||||
'padding-right': paddingRight,
|
||||
'padding-left': this.prefixIcon ? '' : '10px'
|
||||
})
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
value(newVal) {
|
||||
this.val = newVal
|
||||
},
|
||||
modelValue(newVal) {
|
||||
this.val = newVal
|
||||
},
|
||||
focus(newVal) {
|
||||
this.$nextTick(() => {
|
||||
this.focused = this.focus
|
||||
this.focusShow = this.focus
|
||||
})
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.init()
|
||||
// TODO 处理头条vue3 computed 不监听 inject 更改的问题(formItem.errMsg)
|
||||
if (this.form && this.formItem) {
|
||||
this.$watch('formItem.errMsg', (newVal) => {
|
||||
this.localMsg = newVal
|
||||
})
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.$nextTick(() => {
|
||||
this.focused = this.focus
|
||||
this.focusShow = this.focus
|
||||
this.val = ''
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
/**
|
||||
* 初始化变量值
|
||||
*/
|
||||
init() {
|
||||
if (this.value || this.value === 0) {
|
||||
this.val = this.value
|
||||
} else if (this.modelValue || this.modelValue === 0) {
|
||||
this.val = this.modelValue
|
||||
} else {
|
||||
this.val = null
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 点击图标时触发
|
||||
* @param {Object} type
|
||||
*/
|
||||
onClickIcon(type) {
|
||||
this.$emit('iconClick', type)
|
||||
},
|
||||
|
||||
/**
|
||||
* 显示隐藏内容,密码框时生效
|
||||
*/
|
||||
onEyes() {
|
||||
this.showPassword = !this.showPassword
|
||||
this.$emit('eyes', this.showPassword)
|
||||
},
|
||||
|
||||
/**
|
||||
* 输入时触发
|
||||
* @param {Object} event
|
||||
*/
|
||||
onInput(event) {
|
||||
let value = event.detail.value;
|
||||
// 判断是否去除空格
|
||||
if (this.trim) {
|
||||
if (typeof(this.trim) === 'boolean' && this.trim) {
|
||||
value = this.trimStr(value)
|
||||
}
|
||||
if (typeof(this.trim) === 'string') {
|
||||
value = this.trimStr(value, this.trim)
|
||||
}
|
||||
};
|
||||
if (this.errMsg) this.errMsg = ''
|
||||
this.val = value
|
||||
// TODO 兼容 vue2
|
||||
this.$emit('input', value);
|
||||
// TODO 兼容 vue3
|
||||
this.$emit('update:modelValue', value)
|
||||
},
|
||||
|
||||
/**
|
||||
* 外部调用方法
|
||||
* 获取焦点时触发
|
||||
* @param {Object} event
|
||||
*/
|
||||
onFocus() {
|
||||
this.$nextTick(() => {
|
||||
this.focused = true
|
||||
})
|
||||
this.$emit('focus', null);
|
||||
},
|
||||
|
||||
_Focus(event) {
|
||||
this.focusShow = true
|
||||
this.$emit('focus', event);
|
||||
},
|
||||
|
||||
/**
|
||||
* 外部调用方法
|
||||
* 失去焦点时触发
|
||||
* @param {Object} event
|
||||
*/
|
||||
onBlur() {
|
||||
this.focused = false
|
||||
this.$emit('focus', null);
|
||||
},
|
||||
_Blur(event) {
|
||||
let value = event.detail.value;
|
||||
this.focusShow = false
|
||||
this.$emit('blur', event);
|
||||
// 根据类型返回值,在event中获取的值理论上讲都是string
|
||||
this.$emit('change', this.val)
|
||||
// 失去焦点时参与表单校验
|
||||
if (this.form && this.formItem) {
|
||||
const {
|
||||
validateTrigger
|
||||
} = this.form
|
||||
if (validateTrigger === 'blur') {
|
||||
this.formItem.onFieldChange()
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 按下键盘的发送键
|
||||
* @param {Object} e
|
||||
*/
|
||||
onConfirm(e) {
|
||||
this.$emit('confirm', this.val);
|
||||
this.$emit('change', this.val)
|
||||
},
|
||||
|
||||
/**
|
||||
* 清理内容
|
||||
* @param {Object} event
|
||||
*/
|
||||
onClear(event) {
|
||||
this.val = '';
|
||||
// TODO 兼容 vue2
|
||||
this.$emit('input', '');
|
||||
// TODO 兼容 vue2
|
||||
// TODO 兼容 vue3
|
||||
this.$emit('update:modelValue', '')
|
||||
// 点击叉号触发
|
||||
this.$emit('clear')
|
||||
},
|
||||
|
||||
/**
|
||||
* 去除空格
|
||||
*/
|
||||
trimStr(str, pos = 'both') {
|
||||
if (pos === 'both') {
|
||||
return str.trim();
|
||||
} else if (pos === 'left') {
|
||||
return str.trimLeft();
|
||||
} else if (pos === 'right') {
|
||||
return str.trimRight();
|
||||
} else if (pos === 'start') {
|
||||
return str.trimStart()
|
||||
} else if (pos === 'end') {
|
||||
return str.trimEnd()
|
||||
} else if (pos === 'all') {
|
||||
return str.replace(/\s+/g, '');
|
||||
} else if (pos === 'none') {
|
||||
return str;
|
||||
}
|
||||
return str;
|
||||
},
|
||||
/**
|
||||
* 输入框点击事件
|
||||
*/
|
||||
clickInput(){
|
||||
this.$emit('click')
|
||||
},
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
$uni-error: #e43d33;
|
||||
$uni-border-1: #DCDFE6 !default;
|
||||
|
||||
.uni-easyinput {
|
||||
/* #ifndef APP-NVUE */
|
||||
width: 100%;
|
||||
/* #endif */
|
||||
flex: 1;
|
||||
position: relative;
|
||||
text-align: left;
|
||||
color: #333;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.uni-easyinput__content {
|
||||
flex: 1;
|
||||
/* #ifndef APP-NVUE */
|
||||
width: 100%;
|
||||
display: flex;
|
||||
box-sizing: border-box;
|
||||
// min-height: 36px;
|
||||
/* #endif */
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
// 处理border动画刚开始显示黑色的问题
|
||||
border-color: #fff;
|
||||
transition-property: border-color;
|
||||
transition-duration: 0.3s;
|
||||
}
|
||||
|
||||
.uni-easyinput__content-input {
|
||||
/* #ifndef APP-NVUE */
|
||||
width: auto;
|
||||
/* #endif */
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
flex: 1;
|
||||
line-height: 1;
|
||||
font-size: 16px;
|
||||
height: 35px;
|
||||
// min-height: 36px;
|
||||
}
|
||||
|
||||
.uni-easyinput__placeholder-class {
|
||||
color: #999;
|
||||
font-size: 16px;
|
||||
// font-weight: 200;
|
||||
}
|
||||
|
||||
@media screen and (min-width: 600px) {
|
||||
.uni-easyinput__content-input {
|
||||
height: 50px;
|
||||
}
|
||||
}
|
||||
|
||||
.is-textarea {
|
||||
align-items: flex-start;
|
||||
}
|
||||
|
||||
.is-textarea-icon {
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
.uni-easyinput__content-textarea {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
flex: 1;
|
||||
line-height: 1.5;
|
||||
font-size: 16px;
|
||||
margin: 6px;
|
||||
margin-left: 0;
|
||||
height: 80px;
|
||||
min-height: 80px;
|
||||
/* #ifndef APP-NVUE */
|
||||
min-height: 80px;
|
||||
width: auto;
|
||||
/* #endif */
|
||||
}
|
||||
|
||||
.input-padding {
|
||||
padding-left: 10px;
|
||||
}
|
||||
|
||||
.content-clear-icon {
|
||||
padding: 0 5px;
|
||||
}
|
||||
|
||||
.label-icon {
|
||||
margin-right: 5px;
|
||||
margin-top: -1px;
|
||||
}
|
||||
|
||||
// 显示边框
|
||||
.is-input-border {
|
||||
/* #ifndef APP-NVUE */
|
||||
display: flex;
|
||||
box-sizing: border-box;
|
||||
/* #endif */
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
border: 1px solid $uni-border-1;
|
||||
border-radius: 4px;
|
||||
/* #ifdef MP-ALIPAY */
|
||||
overflow: hidden;
|
||||
/* #endif */
|
||||
}
|
||||
|
||||
.uni-error-message {
|
||||
position: absolute;
|
||||
bottom: -17px;
|
||||
left: 0;
|
||||
line-height: 12px;
|
||||
color: $uni-error;
|
||||
font-size: 12px;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.uni-error-msg--boeder {
|
||||
position: relative;
|
||||
bottom: 0;
|
||||
line-height: 22px;
|
||||
}
|
||||
|
||||
.is-input-error-border {
|
||||
border-color: $uni-error;
|
||||
|
||||
.uni-easyinput__placeholder-class {
|
||||
color: mix(#fff, $uni-error, 50%);
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.uni-easyinput--border {
|
||||
margin-bottom: 0;
|
||||
padding: 10px 15px;
|
||||
// padding-bottom: 0;
|
||||
border-top: 1px #eee solid;
|
||||
}
|
||||
|
||||
.uni-easyinput-error {
|
||||
padding-bottom: 0;
|
||||
}
|
||||
|
||||
.is-first-border {
|
||||
/* #ifndef APP-NVUE */
|
||||
border: none;
|
||||
/* #endif */
|
||||
/* #ifdef APP-NVUE */
|
||||
border-width: 0;
|
||||
/* #endif */
|
||||
}
|
||||
|
||||
.is-disabled {
|
||||
background-color: #F7F6F6;
|
||||
color: #D5D5D5;
|
||||
|
||||
.uni-easyinput__placeholder-class {
|
||||
color: #D5D5D5;
|
||||
font-size: 16px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
81
utils/upload.js
Normal file
81
utils/upload.js
Normal file
@@ -0,0 +1,81 @@
|
||||
import store from '@/store'
|
||||
import config from '@/config'
|
||||
import {
|
||||
getToken
|
||||
} from '@/utils/auth'
|
||||
import errorCode from '@/utils/errorCode'
|
||||
import {
|
||||
toast,
|
||||
showConfirm,
|
||||
tansParams
|
||||
} from '@/utils/common'
|
||||
|
||||
let timeout = 10000
|
||||
const baseUrl = config.baseUrl
|
||||
|
||||
const upload = config => {
|
||||
// 是否需要设置 token
|
||||
const isToken = (config.headers || {}).isToken === false
|
||||
config.header = config.header || {}
|
||||
if (getToken() && !isToken) {
|
||||
config.header['Authorization'] = 'Bearer ' + getToken()
|
||||
}
|
||||
// get请求映射params参数
|
||||
if (config.params) {
|
||||
let url = config.url + '?' + tansParams(config.params)
|
||||
url = url.slice(0, -1)
|
||||
config.url = url
|
||||
}
|
||||
return new Promise((resolve, reject) => {
|
||||
uni.uploadFile({
|
||||
timeout: config.timeout || timeout,
|
||||
url: (uni.getStorageSync("base_url") || baseUrl) + '/wc-mes' + config.url,
|
||||
// url: (uni.getStorageSync("base_url") || baseUrl) + config.url,
|
||||
filePath: config.filePath,
|
||||
name: config.name || 'file',
|
||||
header: config.header,
|
||||
formData: config.formData,
|
||||
success: (res) => {
|
||||
let result = JSON.parse(res.data)
|
||||
const code = result.code || 200
|
||||
const msg = errorCode[code] || result.msg || errorCode['default']
|
||||
if (code === 200) {
|
||||
resolve(result)
|
||||
} else if (code == 401) {
|
||||
showConfirm("登录状态已过期,您可以继续留在该页面,或者重新登录?").then(res => {
|
||||
if (res.confirm) {
|
||||
store.dispatch('LogOut').then(res => {
|
||||
uni.reLaunch({
|
||||
url: '/pages/login/login'
|
||||
})
|
||||
})
|
||||
}
|
||||
})
|
||||
reject('无效的会话,或者会话已过期,请重新登录。')
|
||||
} else if (code === 500) {
|
||||
toast(msg)
|
||||
reject('500')
|
||||
} else if (code !== 200) {
|
||||
toast(msg)
|
||||
reject(code)
|
||||
}
|
||||
},
|
||||
fail: (error) => {
|
||||
let {
|
||||
message
|
||||
} = error
|
||||
if (message == 'Network Error') {
|
||||
message = '后端接口连接异常'
|
||||
} else if (message.includes('timeout')) {
|
||||
message = '系统接口请求超时'
|
||||
} else if (message.includes('Request failed with status code')) {
|
||||
message = '系统接口' + message.substr(message.length - 3) + '异常'
|
||||
}
|
||||
toast(message)
|
||||
reject(error)
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
export default upload
|
||||
91
utils/version.js
Normal file
91
utils/version.js
Normal file
@@ -0,0 +1,91 @@
|
||||
import store from '@/store'
|
||||
import config from '@/config'
|
||||
import errorCode from '@/utils/errorCode'
|
||||
import {
|
||||
toast,
|
||||
showConfirm,
|
||||
tansParams
|
||||
} from '@/utils/common'
|
||||
|
||||
let timeout = 60 * 2 * 1000
|
||||
|
||||
const token = 'token 5793f8d09ea4b5cea097e3ed3704493009b52147';
|
||||
const baseUrl = `${ config.giteaUrl }/api/v1/repos/Wance/rd_mes_uniapp`;
|
||||
|
||||
const request = config => {
|
||||
config.header = config.header || {}
|
||||
config.header['Authorization'] = token
|
||||
|
||||
// get请求映射params参数
|
||||
if (config.params) {
|
||||
let url = config.url + '?' + tansParams(config.params)
|
||||
url = url.slice(0, -1)
|
||||
config.url = url
|
||||
}
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
uni.request({
|
||||
method: config.method || 'get',
|
||||
timeout: config.timeout || timeout,
|
||||
url: baseUrl + config.url,
|
||||
data: config.data,
|
||||
header: config.header,
|
||||
dataType: 'json'
|
||||
}).then(response => {
|
||||
let [error, res] = response
|
||||
if (error) {
|
||||
toast('后端接口连接异常')
|
||||
reject('后端接口连接异常')
|
||||
return
|
||||
}
|
||||
console.log(res)
|
||||
const code = res.statusCode || 200
|
||||
const msg = res.errMsg || errorCode[code]
|
||||
|
||||
switch (code) {
|
||||
case 200:
|
||||
resolve(res.data);
|
||||
break;
|
||||
case 401:
|
||||
showConfirm('登录状态已过期,您可以继续留在该页面,或者重新登录?').then(res => {
|
||||
if (res.confirm) {
|
||||
store.dispatch('LogOut').then(() => {
|
||||
uni.reLaunch({
|
||||
url: '/pages/login'
|
||||
})
|
||||
})
|
||||
}
|
||||
})
|
||||
reject('无效的会话,或者会话已过期,请重新登录')
|
||||
break;
|
||||
case 500:
|
||||
toast(msg);
|
||||
reject({
|
||||
code: 500,
|
||||
msg
|
||||
})
|
||||
break;
|
||||
default:
|
||||
toast(msg);
|
||||
reject(code);
|
||||
break;
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
let {
|
||||
message
|
||||
} = error
|
||||
if (message === 'Network Error') {
|
||||
message = '后端接口连接异常'
|
||||
} else if (message.includes('timeout')) {
|
||||
message = '系统接口请求超时'
|
||||
} else if (message.includes('Request failed with status code')) {
|
||||
message = '系统接口' + message.substr(message.length - 3) + '异常'
|
||||
}
|
||||
toast(message)
|
||||
reject(error)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
export default request;
|
||||
88
utils/wms-request.js
Normal file
88
utils/wms-request.js
Normal file
@@ -0,0 +1,88 @@
|
||||
import store from '@/store'
|
||||
import config from '@/config'
|
||||
import {
|
||||
getToken
|
||||
} from '@/utils/auth'
|
||||
import errorCode from '@/utils/errorCode'
|
||||
import {
|
||||
toast,
|
||||
showConfirm,
|
||||
tansParams
|
||||
} from '@/utils/common'
|
||||
|
||||
let timeout = 60 * 2 * 1000
|
||||
// const baseUrl = config.wmsUrl
|
||||
//双菱
|
||||
const baseUrl = config.baseUrl
|
||||
|
||||
const request = config => {
|
||||
// let baseUrlTemp = (uni.getStorageSync("wms_url") || config.baseUrl || baseUrl);
|
||||
//双菱
|
||||
let baseUrlTemp = (uni.getStorageSync("base_url") || config.baseUrl || baseUrl) + '/wc-wms';
|
||||
// 是否需要设置 token
|
||||
const isToken = (config.headers || {}).isToken === false
|
||||
config.header = config.header || {}
|
||||
if (getToken() && !isToken) {
|
||||
config.header['Authorization'] = 'Bearer ' + getToken()
|
||||
}
|
||||
// get请求映射params参数
|
||||
if (config.params) {
|
||||
let url = config.url + '?' + tansParams(config.params)
|
||||
url = url.slice(0, -1)
|
||||
config.url = url
|
||||
}
|
||||
return new Promise((resolve, reject) => {
|
||||
uni.request({
|
||||
method: config.method || 'get',
|
||||
timeout: config.timeout || timeout,
|
||||
url: baseUrlTemp + config.url,
|
||||
data: config.data,
|
||||
header: config.header,
|
||||
dataType: 'json'
|
||||
}).then(response => {
|
||||
let [error, res] = response
|
||||
if (error) {
|
||||
toast('后端接口连接异常')
|
||||
reject('后端接口连接异常')
|
||||
return
|
||||
}
|
||||
const code = res.data.code || 200
|
||||
const msg = errorCode[code] || res.data.msg || errorCode['default']
|
||||
if (code === 401) {
|
||||
showConfirm('登录状态已过期,您可以继续留在该页面,或者重新登录?').then(res => {
|
||||
if (res.confirm) {
|
||||
store.dispatch('LogOut').then(res => {
|
||||
uni.reLaunch({
|
||||
url: '/pages/login'
|
||||
})
|
||||
})
|
||||
}
|
||||
})
|
||||
reject('无效的会话,或者会话已过期,请重新登录。')
|
||||
} else if (code === 500) {
|
||||
toast(msg)
|
||||
reject({code:500,msg})
|
||||
} else if (code !== 200) {
|
||||
toast(msg)
|
||||
reject(code)
|
||||
}
|
||||
resolve(res.data)
|
||||
})
|
||||
.catch(error => {
|
||||
let {
|
||||
message
|
||||
} = error
|
||||
if (message === 'Network Error') {
|
||||
message = '后端接口连接异常'
|
||||
} else if (message.includes('timeout')) {
|
||||
message = '系统接口请求超时'
|
||||
} else if (message.includes('Request failed with status code')) {
|
||||
message = '系统接口' + message.substr(message.length - 3) + '异常'
|
||||
}
|
||||
toast(message)
|
||||
reject(error)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
export default request
|
||||
Reference in New Issue
Block a user