main
zouyanyan 3 weeks ago
commit ed8bff61f4

7
.gitignore vendored

@ -0,0 +1,7 @@
node_modules
.DS_Store
.history
/.idea/
unpackage
hbuilderx
.hbuilderx

@ -0,0 +1,156 @@
<script>
//
//import checkupdate from "@/uni_modules/uni-upgrade-center-app/utils/check-update.js"
//
// import callCheckVersion from '@/uni_modules/uni-upgrade-center-app/utils/call-check-version';
//#ifdef APP-PLUS
const jpushModule = uni.requireNativePlugin('JG-JPush');
//#endif
export default {
onLaunch() {
//
//checkupdate();
//#ifdef APP-PLUS
//
// jpushModule.setLoggerEnable(true);
// jpushModule.initJPushService()
// jpushModule.addConnectEventListener(result=>{
// let connectEnable = result.connectEnable
// console.log("jpush", connectEnable)
// });
//
// var user= JSON.parse(uni.getStorageSync("user"));
// if(user&&user.yhdm){
// jpushModule.setAlias({
// 'alias': user.yhdm,
// 'sequence': 1
// })
// }
//
// jpushModule.addTagAliasListener(result => {
// let code = result.code
// let sequence = result.sequence
// let tags = result.tags
// let tag = result.tag
// let tagEnable = result.tagEnable
// let alias = result.alias
// console.log(alias, '')
// });
// //
// jpushModule.addNotificationListener(result => {
// let notificationEventType = result.notificationEventType
// let messageID = result.messageID
// let title = result.title
// let content = result.content
// let extras = result.extras
// console.log("", result)
// //
// if (notificationEventType == 'notificationOpened') {
// uni.reLaunch({
// url: `/pages/message/newMsg`
// });
// }
// })
// jpushModule.getRegistrationID(result => {
// console.log("ID", result.registerID)
// if (result.registerID) {
// uni.setStorageSync("register_id", result.registerID)
// }
// })
// jpushModule.addCustomMessageListener(result => {
// let messageID = result.messageID
// let content = result.content
// let extras = result.extras
// console.log("", result)
// })
//#endif
},
}
</script>
<style lang="scss">
/*每个页面公共css */
@import "uview-ui/index.scss";
@import "common/demo.scss";
@import 'colorui/main.css';
@import 'colorui/icon.css';
body{
font-family: 'FZLTZHUNHJW--GB1-0';
}
.rightc {
height: 100%;
padding-right: 10rpx !important;
text-align: right !important;
display: flex;
flex: 1;
align-items: flex-end;
justify-content: flex-end;
}
.wrapnob{
margin: 0;
padding: 0;
width: 100%;
position: relative;
height: calc(100vh);
/* #ifdef H5 */
height: calc(100vh - var(--window-top));
/* #endif */
}
.wrap{
margin: 0;
padding: 0;
width: 100%;
position: relative;
height: calc(100vh);
/* #ifdef H5 */
height: calc(100vh - var(--window-top) - var(--window-bottom));
/* #endif */
overflow-y: auto;
}
/* 基本布局 */
.page {
width: 100%;
}
/* 当屏幕宽度小于600px时调整布局 */
@media (max-width: 600px) {
.page {
padding: 5px;
}
}
.page {
position: relative;
width: 100%;
padding: 0;
margin-top: 0;
overflow: hidden;
.back{
width: 100%;
height: calc(100vh - var(--window-top)) !important;
position: absolute;
top:0;
left:0;
background: url('@/static/image/bg.jpg') no-repeat top center;
background-size: 100% 100%;
}
}
.page-box{
padding-bottom:20rpx;
}
.u-drawer{
top:calc(var(--window-top) + 100rpx) !important;
height: calc(100vh - var(--window-top) - 100rpx) !important;
z-index: 92 !important;
}
.imgload{
background-image: url('/static/image/nopic.png');
background-size: 66% auto;
background-position: center center;
background-repeat: no-repeat;
}
</style>

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

@ -0,0 +1,39 @@
// 正式环境
const apiurl = 'http://xzapp.runpengsoft.com';
const install = (Vue, vm) => {
// 图片域名链接--正式环境
let imgurl = 'http://xzapp.runpengsoft.com';
// 获取验证码
let sendSms = (params = {}) => vm.$u.post('/api/sendSms',params);
// 登录
let login = (params = {}) => vm.$u.post(`/api/login`, params);
// body 中传参数
// let login = (data = {}, params = {}) => vm.$u.post(`/api/login`, params);
//用户删除
let removeUserNew = (params = {}) => vm.$u.delete(`/uc/api/userInfo/v1/?ids=${params}`);
let saveUserBaseInfoPC = (params = {}) => vm.$u.put(`/uc/api/userInfo/v1/`,params);
let addEquipment= (params = {}) => vm.$u.post(`/server/ywgl/equipment/v1/`,params);
let getDepartOrTeamDetail= (params = {}) => vm.$u.get(`/server/ywgl/orgExt/v1/org/${params}`);
let employeeList=(params = {}) => vm.$u.post(`/server/ywgl/relevant/v1/employee/list?${params}`,);
// 将各个定义的接口名称统一放进对象挂载到vm.$u.api(因为vm就是this也即this.$u.api)下
vm.$u.api = {
imgurl,
sendSms,
login,
removeUserNew,
saveUserBaseInfoPC,
addEquipment,
getDepartOrTeamDetail,
employeeList
};
}
export default {
apiurl,
install
}

@ -0,0 +1,95 @@
const Base64 = {
_keyStr: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",
encode: function(e) {
var t = "";
var n, r, i, s, o, u, a;
var f = 0;
e = Base64._utf8_encode(e);
while (f < e.length) {
n = e.charCodeAt(f++);
r = e.charCodeAt(f++);
i = e.charCodeAt(f++);
s = n >> 2;
o = (n & 3) << 4 | r >> 4;
u = (r & 15) << 2 | i >> 6;
a = i & 63;
if (isNaN(r)) {
u = a = 64
} else if (isNaN(i)) {
a = 64
}
t = t + this._keyStr.charAt(s) + this._keyStr.charAt(o) + this._keyStr.charAt(u) + this._keyStr.charAt(a)
}
return t
},
decode: function(e) {
var t = "";
var n, r, i;
var s, o, u, a;
var f = 0;
e = e.replace(/[^A-Za-z0-9+/=]/g, "");
while (f < e.length) {
s = this._keyStr.indexOf(e.charAt(f++));
o = this._keyStr.indexOf(e.charAt(f++));
u = this._keyStr.indexOf(e.charAt(f++));
a = this._keyStr.indexOf(e.charAt(f++));
n = s << 2 | o >> 4;
r = (o & 15) << 4 | u >> 2;
i = (u & 3) << 6 | a;
t = t + String.fromCharCode(n);
if (u != 64) {
t = t + String.fromCharCode(r)
}
if (a != 64) {
t = t + String.fromCharCode(i)
}
}
t = Base64._utf8_decode(t);
return t
},
_utf8_encode: function(e) {
e = e.replace(/rn/g, "n");
var t = "";
for (var n = 0; n < e.length; n++) {
var r = e.charCodeAt(n);
if (r < 128) {
t += String.fromCharCode(r)
} else if (r > 127 && r < 2048) {
t += String.fromCharCode(r >> 6 | 192);
t += String.fromCharCode(r & 63 | 128)
} else {
t += String.fromCharCode(r >> 12 | 224);
t += String.fromCharCode(r >> 6 & 63 | 128);
t += String.fromCharCode(r & 63 | 128)
}
}
return t
},
_utf8_decode: function(e) {
var t = "";
var n = 0;
var r = 0;
var c1 =0;
var c2 =0;
var c3 =0;
while (n < e.length) {
r = e.charCodeAt(n);
if (r < 128) {
t += String.fromCharCode(r);
n++
} else if (r > 191 && r < 224) {
c2 = e.charCodeAt(n + 1);
t += String.fromCharCode((r & 31) << 6 | c2 & 63);
n += 2
} else {
c2 = e.charCodeAt(n + 1);
c3 = e.charCodeAt(n + 2);
t += String.fromCharCode((r & 15) << 12 | (c2 & 63) << 6 | c3 & 63);
n += 3
}
}
return t
}
}
export default Base64

File diff suppressed because one or more lines are too long

@ -0,0 +1,137 @@
export default{
//首页时间转化
dateTime(e){
let old = new Date(e);
let now = new Date();
//获取old具体时间
let d = old.getTime();
let h = old.getHours();
let m = old.getMinutes();
let Y = old.getFullYear();
let M = old.getMonth()+1;
let D = old.getDate();
//获取now具体时间
let nd =now.getTime();
let nh = now.getHours();
let n = now.getMinutes();
let nY = now.getFullYear();
let nM = now.getMonth()+1;
let nD = now.getDate();
//当天的时间
if(D === nD && M === nM && Y === nY){
if(h<10){
h = '0'+h;
}
if(m<10){
m = '0'+m;
}
return h+':'+m;
}
//昨天时间
if(D+1 === nD && M === nM && Y === nY){
if(h<10){
h = '0'+h;
}
if(m<10){
m = '0'+m;
}
return '昨天 '+h+':'+m;
}else{
//大于两天
return Y+'/'+M+'/'+D;
}
},
//聊天时,发送时间处理
dateTime1(e){
let old = new Date(e);
let now = new Date();
//获取old具体时间
let d = old.getTime();
let h = old.getHours();
let m = old.getMinutes();
let Y = old.getFullYear();
let M = old.getMonth()+1;
let D = old.getDate();
//获取now具体时间
let nd =now.getTime();
let nh = now.getHours();
let n = now.getMinutes();
let nY = now.getFullYear();
let nM = now.getMonth()+1;
let nD = now.getDate();
//当天的时间
if(D === nD && M === nM && Y === nY){
if(h<10){
h = '0'+h;
}
if(m<10){
m = '0'+m;
}
return h+':'+m;
}
//昨天时间
if(D+1 === nD && M === nM && Y === nY){
if(h<10){
h = '0'+h;
}
if(m<10){
m = '0'+m;
}
return '昨天 '+h+':'+m;
}else if( Y == nY){
//今年
if(h<10){
h = '0'+h;
}
if(m<10){
m = '0'+m;
}
return M+'月'+D+'日 '+h+':'+m
}else{
//大于今年
if(h<10){
h = '0'+h;
}
if(m<10){
m = '0'+m;
}
return Y+'年'+ M +'月' +D+ '日 '+h+':'+m
}
},
// 间隔时间差
spaceTime(old,now){
old = new Date(old);
now = new Date(now);
var told = old.getTime();
var tnow = now.getTime();
if(told > (tnow+1000*60*5)){
return now;
}else{
return '';
}
},
chatrurn(data){
data.forEach((cell,i)=>{
cell["ifaudio"]=false;
//时间间隔处理
//这里表示头部时间还是显示一下
var oldTime= new Date();
let t = dateTime.spaceTime(oldTime, cell.bzrq);
if (t) {
oldTime = t;
}
cell.bzrq = t;
// 获取图片,为下面的预览做准备
if(cell.type=='txt'){
cell.content=decodeURIComponent(cell.content);
}
});
return data;
}
}

@ -0,0 +1,86 @@
/* #ifndef APP-NVUE */
view,
text {
box-sizing: border-box;
}
/* #endif */
/* start--演示页面使用的统一样式--start */
.u-demo {
padding: 25px 20px;
}
.u-demo-wrap {
border-width: 1px;
border-color: #ddd;
border-style: dashed;
background-color: rgb(250, 250, 250);
padding: 20px 10px;
border-radius: 3px;
}
.u-demo-area {
text-align: center;
}
.u-no-demo-here {
color: $u-tips-color;
font-size: 13px;
}
.u-demo-result-line {
border-width: 1px;
border-color: #ddd;
border-style: dashed;
padding: 5px 20px;
margin-top: 30px;
border-radius: 5px;
background-color: rgb(240, 240, 240);
color: $u-content-color;
font-size: 16px;
/* #ifndef APP-NVUE */
word-break: break-word;
display: inline-block;
/* #endif */
text-align: left;
}
.u-demo-title,
.u-config-title {
text-align: center;
font-size: 16px;
font-weight: bold;
margin-bottom: 20px;
}
.u-config-item {
margin-top: 25px;
}
.u-config-title {
margin-top: 20px;
padding-bottom: 5px;
}
.u-item-title {
position: relative;
font-size: 15px;
padding-left: 8px;
line-height: 1;
margin-bottom: 11px;
}
.u-item-title:after {
position: absolute;
width: 4px;
top: -1px;
height: 16px;
/* #ifndef APP-NVUE */
content: '';
/* #endif */
left: 0;
border-radius: 10px;
background-color: $u-content-color;
}
/* end--演示页面使用的统一样式--end */

@ -0,0 +1,22 @@
// 如果没有通过拦截器配置域名的话可以在这里写上完整的URL(加上域名部分)
let hotSearchUrl = '/ebapi/store_api/hot_search';
let indexUrl = '/ebapi/public_api/index';
// 此处第二个参数vm就是我们在页面使用的this你可以通过vm获取vuex等操作更多内容详见uView对拦截器的介绍部分
// https://uviewui.com/js/http.html#%E4%BD%95%E8%B0%93%E8%AF%B7%E6%B1%82%E6%8B%A6%E6%88%AA%EF%BC%9F
const install = (Vue, vm) => {
// 此处没有使用传入的params参数
let getSearch = (params = {}) => vm.$u.get(hotSearchUrl, {
id: 2
});
// 此处使用了传入的params参数一切自定义即可
let getInfo = (params = {}) => vm.$u.post(indexUrl, params);
// 将各个定义的接口名称统一放进对象挂载到vm.$u.api(因为vm就是this也即this.$u.api)下
vm.$u.api = {getSearch, getInfo};
}
export default {
install
}

@ -0,0 +1,60 @@
// 这里的vm就是我们在vue文件里面的this所以我们能在这里获取vuex的变量比如存放在里面的token
// 同时我们也可以在此使用getApp().globalData如果你把token放在getApp().globalData的话也是可以使用的
const install = (Vue, vm) => {
Vue.prototype.$u.http.setConfig({
// baseUrl: 'http://spwy-test.spacecig.com',
// baseUrl: 'https://api.youzixy.com',
// 如果将此值设置为true拦截回调中将会返回服务端返回的所有数据response而不是response.data
// 设置为true后就需要在this.$u.http.interceptor.response进行多一次的判断请打印查看具体值
// originalData: true,
// 设置自定义头部content-type
header: {
'content-type': 'application/json'
}
});
// 请求拦截配置Token等参数
Vue.prototype.$u.http.interceptor.request = (config) => {
if(config.url=='/uc/auth'){
config.header.Authorization =''
}else{
config.header.Authorization = uni.getStorageSync('token') ? `Bearer ${uni.getStorageSync('token')}` :"";
}
// 方式一存放在vuex的token假设使用了uView封装的vuex方式https://uviewui.com/components/globalVariable.html
// config.header.token = vm.token;
// 方式二如果没有使用uView封装的vuex方法那么需要使用$store.state获取
// config.header.token = vm.$store.state.token;
// 方式三如果token放在了globalData通过getApp().globalData获取
// config.header.token = getApp().globalData.username;
// 方式四如果token放在了Storage本地存储中拦截是每次请求都执行的所以哪怕您重新登录修改了Storage下一次的请求将会是最新值
// const token = uni.getStorageSync('token');
// config.header.token = token;
return config;
}
// 响应拦截,判断状态码是否通过
Vue.prototype.$u.http.interceptor.response = (res) => {
// 如果把originalData设置为了true这里得到将会是服务器返回的所有的原始数据
// 判断可能变成了res.statueCode或者res.data.code之类的请打印查看结果
if (res.state) {
// 如果把originalData设置为了true这里return回什么this.$u.post的then回调中就会得到什么
return res.value;
} else if (res.token || res.page) {
return res;
} else if (Array.isArray(res)) {
return res;
}
else if(res){
return res;
}
else {
return false;
}
}
}
export default {
install
}

@ -0,0 +1,585 @@
module.exports = {
list: [{
"letter": "A",
"data": [{
"name": "阿拉斯加",
"mobile": "13588889999",
"keyword": "阿拉斯加ABA13588889999"
},
{
"name": "阿克苏",
"mobile": "0551-4386721",
"keyword": "阿克苏AKESU0551-4386721"
},
{
"name": "阿拉善",
"mobile": "4008009100",
"keyword": "阿拉善ALASHAN4008009100"
},
{
"name": "阿勒泰",
"mobile": "13588889999",
"keyword": "阿勒泰ALETAI13588889999"
},
{
"name": "阿里",
"mobile": "13588889999",
"keyword": "阿里ALI13588889999"
},
{
"name": "安阳",
"mobile": "13588889999",
"keyword": "13588889999安阳ANYANG"
}
]
},
{
"letter": "B",
"data": [{
"name": "白城",
"mobile": "该主子没有留电话~",
"keyword": "白城BAICHENG"
},
{
"name": "白山",
"mobile": "13588889999",
"keyword": "白山BAISHAN13588889999"
},
{
"name": "白银",
"mobile": "13588889999",
"keyword": "白银BAIYIN13588889999"
},
{
"name": "保定",
"mobile": "13588889999",
"keyword": "保定BAODING13588889999"
}
]
},
{
"letter": "C",
"data": [{
"name": "沧州",
"mobile": "13588889999",
"keyword": "沧州CANGZHOU13588889999"
},
{
"name": "长春",
"mobile": "13588889999",
"keyword": "长春CHANGCHUN13588889999"
}
]
},
{
"letter": "D",
"data": [{
"name": "大理",
"mobile": "13588889999",
"keyword": "大理DALI13588889999"
},
{
"name": "大连",
"mobile": "13588889999",
"keyword": "大连DALIAN13588889999"
}
]
},
{
"letter": "E",
"data": [{
"name": "鄂尔多斯",
"mobile": "13588889999",
"keyword": "鄂尔多斯EERDUOSI13588889999"
},
{
"name": "恩施",
"mobile": "13588889999",
"keyword": "恩施ENSHI13588889999"
},
{
"name": "鄂州",
"mobile": "13588889999",
"keyword": "鄂州EZHOU13588889999"
}
]
},
{
"letter": "F",
"data": [{
"name": "防城港",
"mobile": "该主子没有留电话~",
"keyword": "防城港FANGCHENGGANG"
},
{
"name": "抚顺",
"mobile": "13588889999",
"keyword": "抚顺FUSHUN13588889999"
},
{
"name": "阜新",
"mobile": "13588889999",
"keyword": "阜新FUXIN13588889999"
},
{
"name": "阜阳",
"mobile": "13588889999",
"keyword": "阜阳FUYANG13588889999"
},
{
"name": "抚州",
"mobile": "13588889999",
"keyword": "抚州FUZHOU13588889999"
},
{
"name": "福州",
"mobile": "13588889999",
"keyword": "福州FUZHOU13588889999"
}
]
},
{
"letter": "G",
"data": [{
"name": "甘南",
"mobile": "13588889999",
"keyword": "甘南GANNAN13588889999"
},
{
"name": "赣州",
"mobile": "13588889999",
"keyword": "赣州GANZHOU13588889999"
},
{
"name": "甘孜",
"mobile": "13588889999",
"keyword": "甘孜GANZI13588889999"
}
]
},
{
"letter": "H",
"data": [{
"name": "哈尔滨",
"mobile": "13588889999",
"keyword": "哈尔滨HAERBIN13588889999"
},
{
"name": "海北",
"mobile": "13588889999",
"keyword": "海北HAIBEI13588889999"
},
{
"name": "海东",
"mobile": "13588889999",
"keyword": "海东HAIDONG13588889999"
},
{
"name": "海口",
"mobile": "13588889999",
"keyword": "海口HAIKOU13588889999"
}
]
},
{
"letter": "I",
"data": [{
"name": "ice",
"mobile": "13588889999",
"keyword": "佳木斯JIAMUSI13588889999"
}]
},
{
"letter": "J",
"data": [{
"name": "佳木斯",
"mobile": "13588889999",
"keyword": "佳木斯JIAMUSI13588889999"
},
{
"name": "吉安",
"mobile": "13588889999",
"keyword": "吉安JIAN13588889999"
},
{
"name": "江门",
"mobile": "13588889999",
"keyword": "江门JIANGMEN13588889999"
}
]
},
{
"letter": "K",
"data": [{
"name": "开封",
"mobile": "13588889999",
"keyword": "开封KAIFENG13588889999"
},
{
"name": "喀什",
"mobile": "13588889999",
"keyword": "喀什KASHI13588889999"
},
{
"name": "克拉玛依",
"mobile": "13588889999",
"keyword": "克拉玛依KELAMAYI13588889999"
}
]
},
{
"letter": "L",
"data": [{
"name": "来宾",
"mobile": "13588889999",
"keyword": "来宾LAIBIN13588889999"
},
{
"name": "兰州",
"mobile": "13588889999",
"keyword": "兰州LANZHOU13588889999"
},
{
"name": "拉萨",
"mobile": "13588889999",
"keyword": "拉萨LASA13588889999"
},
{
"name": "乐山",
"mobile": "13588889999",
"keyword": "乐山LESHAN13588889999"
},
{
"name": "凉山",
"mobile": "13588889999",
"keyword": "凉山LIANGSHAN13588889999"
},
{
"name": "连云港",
"mobile": "13588889999",
"keyword": "连云港LIANYUNGANG13588889999"
},
{
"name": "聊城",
"mobile": "18322223333",
"keyword": "聊城LIAOCHENG18322223333"
},
{
"name": "辽阳",
"mobile": "18322223333",
"keyword": "辽阳LIAOYANG18322223333"
},
{
"name": "辽源",
"mobile": "18322223333",
"keyword": "辽源LIAOYUAN18322223333"
},
{
"name": "丽江",
"mobile": "18322223333",
"keyword": "丽江LIJIANG18322223333"
},
{
"name": "临沧",
"mobile": "18322223333",
"keyword": "临沧LINCANG18322223333"
},
{
"name": "临汾",
"mobile": "18322223333",
"keyword": "临汾LINFEN18322223333"
},
{
"name": "临夏",
"mobile": "18322223333",
"keyword": "临夏LINXIA18322223333"
},
{
"name": "临沂",
"mobile": "18322223333",
"keyword": "临沂LINYI18322223333"
},
{
"name": "林芝",
"mobile": "18322223333",
"keyword": "林芝LINZHI18322223333"
},
{
"name": "丽水",
"mobile": "18322223333",
"keyword": "丽水LISHUI18322223333"
}
]
},
{
"letter": "M",
"data": [{
"name": "眉山",
"mobile": "15544448888",
"keyword": "眉山MEISHAN15544448888"
},
{
"name": "梅州",
"mobile": "15544448888",
"keyword": "梅州MEIZHOU15544448888"
},
{
"name": "绵阳",
"mobile": "15544448888",
"keyword": "绵阳MIANYANG15544448888"
},
{
"name": "牡丹江",
"mobile": "15544448888",
"keyword": "牡丹江MUDANJIANG15544448888"
}
]
},
{
"letter": "N",
"data": [{
"name": "南昌",
"mobile": "15544448888",
"keyword": "南昌NANCHANG15544448888"
},
{
"name": "南充",
"mobile": "15544448888",
"keyword": "南充NANCHONG15544448888"
},
{
"name": "南京",
"mobile": "15544448888",
"keyword": "南京NANJING15544448888"
},
{
"name": "南宁",
"mobile": "15544448888",
"keyword": "南宁NANNING15544448888"
},
{
"name": "南平",
"mobile": "15544448888",
"keyword": "南平NANPING15544448888"
}
]
},
{
"letter": "O",
"data": [{
"name": "欧阳",
"mobile": "15544448888",
"keyword": "欧阳ouyang15544448888"
}]
},
{
"letter": "P",
"data": [{
"name": "盘锦",
"mobile": "15544448888",
"keyword": "盘锦PANJIN15544448888"
},
{
"name": "攀枝花",
"mobile": "15544448888",
"keyword": "攀枝花PANZHIHUA15544448888"
},
{
"name": "平顶山",
"mobile": "15544448888",
"keyword": "平顶山PINGDINGSHAN15544448888"
},
{
"name": "平凉",
"mobile": "15544448888",
"keyword": "平凉PINGLIANG15544448888"
},
{
"name": "萍乡",
"mobile": "15544448888",
"keyword": "萍乡PINGXIANG15544448888"
},
{
"name": "普洱",
"mobile": "15544448888",
"keyword": "普洱PUER15544448888"
},
{
"name": "莆田",
"mobile": "15544448888",
"keyword": "莆田PUTIAN15544448888"
},
{
"name": "濮阳",
"mobile": "15544448888",
"keyword": "濮阳PUYANG15544448888"
}
]
},
{
"letter": "Q",
"data": [{
"name": "黔东南",
"mobile": "15544448888",
"keyword": "黔东南QIANDONGNAN15544448888"
},
{
"name": "黔南",
"mobile": "15544448888",
"keyword": "黔南QIANNAN15544448888"
},
{
"name": "黔西南",
"mobile": "15544448888",
"keyword": "黔西南QIANXINAN15544448888"
}
]
},
{
"letter": "R",
"data": [{
"name": "日喀则",
"mobile": "15544448888",
"keyword": "日喀则RIKAZE15544448888"
},
{
"name": "日照",
"mobile": "15544448888",
"keyword": "日照RIZHAO15544448888"
}
]
},
{
"letter": "S",
"data": [{
"name": "三门峡",
"mobile": "15544448888",
"keyword": "三门峡SANMENXIA15544448888"
},
{
"name": "三明",
"mobile": "15544448888",
"keyword": "三明SANMING15544448888"
},
{
"name": "三沙",
"mobile": "15544448888",
"keyword": "三沙SANSHA15544448888"
}
]
},
{
"letter": "T",
"data": [{
"name": "塔城",
"mobile": "15544448888",
"keyword": "塔城TACHENG15544448888"
},
{
"name": "漯河",
"mobile": "15544448888",
"keyword": "漯河TAHE15544448888"
},
{
"name": "泰安",
"mobile": "15544448888",
"keyword": "泰安TAIAN15544448888"
}
]
},
{
"letter": "W",
"data": [{
"name": "潍坊",
"mobile": "15544448888",
"keyword": "潍坊WEIFANG15544448888"
},
{
"name": "威海",
"mobile": "15544448888",
"keyword": "威海WEIHAI15544448888"
},
{
"name": "渭南",
"mobile": "15544448888",
"keyword": "渭南WEINAN15544448888"
},
{
"name": "文山",
"mobile": "15544448888",
"keyword": "文山WENSHAN15544448888"
}
]
},
{
"letter": "X",
"data": [{
"name": "厦门",
"mobile": "15544448888",
"keyword": "厦门XIAMEN15544448888"
},
{
"name": "西安",
"mobile": "15544448888",
"keyword": "西安XIAN15544448888"
},
{
"name": "湘潭",
"mobile": "15544448888",
"keyword": "湘潭XIANGTAN15544448888"
}
]
},
{
"letter": "Y",
"data": [{
"name": "雅安",
"mobile": "15544448888",
"keyword": "雅安YAAN15544448888"
},
{
"name": "延安",
"mobile": "15544448888",
"keyword": "延安YANAN15544448888"
},
{
"name": "延边",
"mobile": "15544448888",
"keyword": "延边YANBIAN15544448888"
},
{
"name": "盐城",
"mobile": "15544448888",
"keyword": "盐城YANCHENG15544448888"
}
]
},
{
"letter": "Z",
"data": [{
"name": "枣庄",
"mobile": "15544448888",
"keyword": "枣庄ZAOZHUANG15544448888"
},
{
"name": "张家界",
"mobile": "15544448888",
"keyword": "张家界ZHANGJIAJIE15544448888"
},
{
"name": "张家口",
"mobile": "15544448888",
"keyword": "张家口ZHANGJIAKOU15544448888"
}
]
},
{
"letter": "#",
"data": [{
"name": "其他.",
"mobile": "16666666666",
"keyword": "echo16666666666"
}]
}
]
}

@ -0,0 +1,21 @@
export default {
// 可以以页面为单位来写比如首页的内容写在index字段个人中心写在center共同部分写在common部分
components: {
desc: 'Numerous components cover the various requirements of the development process, and the components are rich in functions and compatible with multiple terminals. Let you integrate quickly, out of the box'
},
js: {
desc: 'Numerous intimate gadgets are a weapon that you can call upon during the development process, allowing you to dart in your hand and pierce the Yang with a hundred steps'
},
template: {
desc: 'Collection of many commonly used pages and layouts, reducing the repetitive work of developers, allowing you to focus on logic and get twice the result with half the effort'
},
nav: {
components: 'Components',
js: 'JS',
template: 'Template'
},
common: {
intro: 'UI framework for rapid development of multiple platforms',
title: 'uView UI',
},
}

@ -0,0 +1,21 @@
export default {
// 可以以页面为单位来写比如首页的内容写在index字段个人中心写在center共同部分写在common部分
components: {
desc: '众多组件覆盖开发过程的各个需求,组件功能丰富,多端兼容。让你快速集成,开箱即用'
},
js: {
desc: '众多的贴心小工具,是你开发过程中召之即来的利器,让你飞镖在手,百步穿杨'
},
template: {
desc: '收集众多的常用页面和布局,减少开发者的重复工作,让你专注逻辑,事半功倍'
},
nav: {
components: '组件',
js: '工具',
template: '模板'
},
common: {
intro: '多平台快速开发的UI框架',
title: 'uView UI',
},
}

@ -0,0 +1,95 @@
var utils = {
//时间格式化
formatDate: (value) => {
let date = null;
if (!value) {
return date;
}
if (value.constructor == Date && !isNaN(value.getTime())) {
date = value;
}
else if (value.constructor == String || value.constructor == Number) {
date = new Date(value);
}
else {
throw "格式化日期时,传入的数据格式不正确。";
}
let y = date.getFullYear();
let MM = date.getMonth() + 1;
MM = MM < 10 ? ('0' + MM) : MM;
let d = date.getDate();
d = d < 10 ? ('0' + d) : d;
let h = date.getHours();
h = h < 10 ? ('0' + h) : h;
let m = date.getMinutes();
m = m < 10 ? ('0' + m) : m;
let s = date.getSeconds();
s = s < 10 ? ('0' + s) : s;
return y + '-' + MM + '-' + d + ' ' + h + ':' + m + ':' + s;
},
format: (value) => {
let date = null;
if (!value) {
return date;
}
if (value.constructor == Date && !isNaN(value.getTime())) {
date = value;
}
else if (value.constructor == String || value.constructor == Number) {
date = new Date(value);
}
else {
throw "格式化日期时,传入的数据格式不正确。";
}
let y = date.getFullYear();
let MM = date.getMonth() + 1;
MM = MM < 10 ? ('0' + MM) : MM;
let d = date.getDate();
d = d < 10 ? ('0' + d) : d;
return y + '/' + MM + '/' + d;
},
//字典数据根据key显示文字
dataFilter:(arr, val='')=> {
let name = "";
arr.forEach((item) => {
if (item.key == val) {
name = item.name;
}else{
name='--'
}
});
return name;
},
//列表转换为树格式
listtoTree:(data)=>{
let result = [];
if (!Array.isArray(data)) {
return result;
}
data.forEach((item) => {
delete item.children;
});
let map = {};
data.forEach((item) => {
map[item.id] = item;
});
data.forEach((item) => {
let parent = map[item.parentId];
if (parent) {
(parent.children || (parent.children = [])).push(item);
} else {
result.push(item);
}
});
return result;
},
getRemoteFile: (path) => {
return `https://www.sanduolantoyoga.com/yoga${path}`;
}
}
// 格式化日期
export default utils;

File diff suppressed because one or more lines are too long

@ -0,0 +1,729 @@
<template xlang="wxml">
<view class="tki-tree">
<view
class="tki-tree-mask"
:class="{ show: showTree }"
@tap="_cancel"
></view>
<view class="tki-tree-cnt" :class="{ show: showTree }">
<view class="tki-tree-bar">
<view
class="tki-tree-bar-cancel"
@tap="_cancel"
:style="{ color: cancelColor }"
hover-class="hover-c"
>
取消
</view>
<view v-if="isSearch" class="tki-tree-bar-title">
<u-search
class="searchinput"
v-model="keyword"
:placeholder="placeholder"
@custom="_searchcustom"
@clear="_searchclear"
:clearabled="true"
:show-action="showAction"
@change="searchchange"
shape="square"
bg-color="#EFF4F9"
input-align="left"
></u-search>
</view>
<view v-else class="tki-tree-bar-title" :style="{ color: titleColor }">
{{ title }}
</view>
<view
class="tki-tree-bar-confirm"
:style="{ color: confirmColor }"
hover-class="hover-c"
@tap="_confirm"
>确定</view
>
</view>
<view class="tki-tree-view">
<scroll-view class="tki-tree-view-sc" :scroll-y="true">
<block v-for="(item, index) in treeList" :key="index">
<view
class="tki-tree-item"
:style="[
{
paddingLeft: item.rank * 15 + 'px',
zIndex: item.rank * -1 + 50,
},
]"
:class="{
border: border === true,
show: item.show,
last: item.lastRank,
showchild: item.showChild,
open: item.open,
}"
>
<view
class="tki-tree-label"
@tap.stop="_treeItemTap(item, index)"
>
<image
class="tki-tree-icon"
:src="
item.lastRank
? lastIcon
: item.showChild
? currentIcon
: defaultIcon
"
></image>
{{ item.name }} {{isCount&&!item.lastRank?'('+item.count+')':''}}
</view>
<view
class="tki-tree-check"
@tap.stop="_treeItemSelect(item, index)"
v-if="
((selectParent ? true : item.lastRank) && (isArea ? item.source[lastNotchoose] == 1 : true)) &&((isLevel && selectLevel && (item.rank + 1) >= selectLevel)||!isLevel)
"
>
<view
class="tki-tree-check-yes"
v-if="item.checked"
:class="{ radio: !multiple }"
:style="{ 'border-color': confirmColor }"
>
<view
class="tki-tree-check-yes-b"
:style="{ 'background-color': confirmColor }"
></view>
</view>
<view
class="tki-tree-check-no"
v-else
:class="{ radio: !multiple }"
:style="{ 'border-color': confirmColor }"
></view>
</view>
</view>
</block>
</scroll-view>
</view>
</view>
</view>
</template>
<script>
export default {
name: "tki-tree",
props: {
range: {
type: Array,
default: function () {
return [];
},
},
idKey: {
type: String,
default: "id",
},
// '12112121,31313131'
defaultIds: {
// type: String,
default: "",
},
value: {
type: String,
default: "",
},
rangeKey: {
type: String,
default: "label",
},
title: {
type: String,
default: "",
},
multiple: {
//
type: Boolean,
default: false,
// default: true
},
isArea: {
//
type: Boolean,
default: false,
},
selectParent: {
//
type: Boolean,
default: false,
},
selectThis: {
type: Boolean,
default: false,
},
isLevel: {
//
type: Boolean,
default: false,
},
selectLevel: {
// 1
type: Number,
default: 0, //
},
foldAll: {
//
type: Boolean,
default: false,
},
confirmColor: {
//
type: String,
default: "", // #07bb07
},
cancelColor: {
//
type: String,
default: "", // #757575
},
lastNotchoose: {
//
type: String,
default: "", // #757575
},
titleColor: {
//
type: String,
default: "", // #757575
},
currentIcon: {
// ic
type: String,
default: require("@/static/image/arrowx.png"),
},
defaultIcon: {
// ic
type: String,
default: require("@/static/image/arrowr.png"),
},
lastIcon: {
// ic
type: String,
default: "",
},
border: {
// 线
type: Boolean,
default: false,
},
unfold: {
//
type: Boolean,
default: false,
},
isCount: {
//
type: Boolean,
default: false,
},
isSearch: {
//
type: Boolean,
default: false,
},
placeholder: {
//
type: String,
default: "请输入检索关键字",
},
searchKey: {
//
type: String,
default: "",
},
},
data() {
return {
showTree: false,
treeListData: [],
treeList: [],
selectIndex: -1,
thisItem: null,
thisIndex: null,
idArr: [],
showAction: false,
keyword: "", //
sort:1,
// value :this.localValue
};
},
computed: {},
methods: {
// _handleList(val) {
// this.value =val
// console.log(this.value)
// },
_show() {
this.showTree = true;
},
_hide() {
// this.showTree = false;
//
this._confirm();
},
_cancel() {
this._hide();
this.$emit("cancel", "");
},
_searchcustom(val) {
//
if (this.searchKey) {
//
this.treeListData.forEach((v, i) => {
this.treeListData[i].checked = false;
});
this.treeList = this.treeListData.filter((p) => {
//filterpersonList
return (
(p.source &&
p.source[this.searchKey] &&
p.source[this.searchKey].indexOf(val) !== -1) ||
(p.source && p.source.children
? this.isfilter(p.source.children, val)
: false)
);
});
}
// this.$emit("searchDo", val);
},
isfilter(arrs, val) {
var rets = false;
arrs.filter((p) => {
//filterpersonList
if (
(p[this.searchKey] && p[this.searchKey].indexOf(val) !== -1) ||
(p.children ? this.isfilter(p.children, val) : false)
) {
rets = true;
}
});
return rets;
},
_searchclear() {
//
this.showAction = false;
var inidata = this.treeListData;
this.treeList = [...inidata];
// this.$emit("searchDo", "");
},
searchchange(value) {
if (value) {
this.showAction = true;
}
},
_confirm() {
//
let rt = [],
treeList = this.treeList,
obj = {};
if (this.selectThis) {
treeList = this.treeList.slice(0, this.thisIndex + 1);
}
treeList.forEach((v, i) => {
if (treeList[i].checked) {
obj = {};
obj.parents = treeList[i].parents;
console.log(obj.sort)
obj = Object.assign(obj, treeList[i].source);
//
delete obj.children
console.log(obj)
obj.sort = treeList[i].sort;
rt.push(obj);
}
});
// this._hide();
this.showTree = false;
this.$emit("confirm", rt);
},
//
_renderTreeList(list = [], rank = 0, parentId = [], parents = []) {
list.forEach((item) => {
this.treeList.push({
id: item[this.idKey],
name: item[this.rangeKey],
source: item,
parentId, // id
parents, // id
rank, //
showChild: this.unfold, //false, //
open: this.unfold, //false, //
show: rank === 0 || this.unfold, //
hideArr: [],
orChecked: item.checked ? item.checked : false,
checked: item.checked ? item.checked : false,
count:(((this.selectParent ? true : !item.children) && (this.isArea ? this.lastNotchoose&&item[this.lastNotchoose]&&item[this.lastNotchoose] == 1 : true)) ||
(this.isLevel && this.selectLevel && rank + 1 >= this.selectLevel)?1:0)
});
if (Array.isArray(item.children) && item.children.length > 0) {
let parentid = [...parentId],
parentArr = [...parents],
childrenid = [...childrenid];
delete parentArr.children;
parentid.push(item[this.idKey]);
parentArr.push({
[this.idKey]: item[this.idKey],
[this.rangeKey]: item[this.rangeKey],
});
this._renderTreeList(item.children, rank + 1, parentid, parentArr);
} else {
this.treeList[this.treeList.length - 1].lastRank = true;
}
});
},
//
_defaultSelect(val) {
if (this.defaultIds) {
let defaultIds = this.defaultIds.split(",") || this.defaultIds;
this.treeList.forEach((item) => {
defaultIds.forEach((i) => {
if (item.id == i) {
item.checked = true;
}
});
});
}
this.treeList.forEach((v, i) => {
if (v.checked) {
this.treeList.forEach((v2, i2) => {
if (v.parentId.toString().indexOf(v2.parentId.toString()) >= 0) {
v2.show = true;
if (v.parentId.includes(v2.id)) {
v2.showChild = true;
v2.open = true;
}
}
});
}
});
},
//
_treeItemTap(item, index) {
this.thisItem = item;
this.thisIndex = index;
console.log(item, index, "点击");
if (item.lastRank === true) {
//
if (item.source.isArea == 1) {
this.treeList[index].checked = !this.treeList[index].checked;
this._fixMultiple(index);
return;
}
}
let list = this.treeList;
let id = item.id;
item.showChild = !item.showChild;
item.open = item.showChild ? true : !item.open;
list.forEach((childItem, i) => {
if (item.showChild === false) {
//
if (!childItem.parentId.includes(id)) {
return;
}
if (!this.foldAll) {
if (childItem.lastRank !== true && !childItem.open) {
childItem.showChild = false;
}
//
if (childItem.show) {
childItem.hideArr[item.rank] = id;
}
} else {
if (childItem.lastRank !== true) {
childItem.showChild = false;
}
}
childItem.show = false;
} else {
//
if (childItem.parentId[childItem.parentId.length - 1] === id) {
childItem.show = true;
}
//
if (childItem.parentId.includes(id) && !this.foldAll) {
// console.log(childItem.hideArr)
if (childItem.hideArr[item.rank] === id) {
childItem.show = true;
if (childItem.open && childItem.showChild) {
childItem.showChild = true;
} else {
childItem.showChild = false;
}
childItem.hideArr[item.rank] = null;
}
// console.log(childItem.hideArr)
}
}
});
// console.log(this.treeList)
},
_treeItemSelect(item, index) {
item.sort=this.sort
this.sort++;
this.thisItem = item;
this.thisIndex = index;
this.treeList[index].checked = !this.treeList[index].checked;
this._fixMultiple(index);
if (this.selectParent) {
//
this._chenge(item, this.treeList[index].checked);
}
},
_chenge(e, e1) {
console.log(e)
this.idArr.push(e.id);
if (e.source.children == undefined &&this.multiple) {
this.treeList.forEach((k, i) => {
this.idArr.forEach((k1, i1) => {
if (k.id == k1 && e1 == true) {
this.treeList[i].checked = true;
} else if (k.id == k1 && e1 == false) {
this.treeList[i].checked = false;
}
});
});
if (e.checked) {
e.parentId.forEach((k, i) => {
this.treeList.forEach((k1, i1) => {
if (k1.id == k) {
this.treeList[i1].checked = true;
}
});
});
} else {
e.parentId.forEach((k, i) => {
this.treeList.forEach((k1, i1) => {
if (k1.id == k) {
this.treeList[i1].checked = false;
}
});
});
}
this.treeList.forEach((k1, i1) => {
if (k1.checked ) {
k1.parentId.forEach((k2, i2) => {
this.treeList.forEach((k3, i3) => {
if (k3.id == k2) {
this.treeList[i3].checked = true;
}
});
});
}
});
this.idArr = [];
return;
}
if (!this.selectThis) { //
this.handkeCheck1(e.source.children);
}
this.treeList.forEach((k, i) => {
this.idArr.forEach((k1, i1) => {
if (k.id == k1 && e1 == true) {
this.treeList[i].checked = true;
} else if (k.id == k1 && e1 == false) {
this.treeList[i].checked = false;
}
});
});
if(this.multiple){
if ( e.checked) {
e.parentId.forEach((k, i) => {
this.treeList.forEach((k1, i1) => {
if (k1.id == k) {
this.treeList[i1].checked = true;
}
});
});
} else {
e.parentId.forEach((k, i) => {
this.treeList.forEach((k1, i1) => {
if (k1.id == k) {
this.treeList[i1].checked = false;
this.treeList[i1].halfchecked = true;
}
});
});
}
this.treeList.forEach((k1, i1) => {
if (k1.checked) {
k1.parentId.forEach((k2, i2) => {
this.treeList.forEach((k3, i3) => {
if (k3.id == k2) {
this.treeList[i3].checked = true;
}
});
});
}
});
}
this.idArr = [];
},
handkeCheck1(list) {
list.forEach((k, i) => {
this.idArr.push(k.id);
if (k.children == undefined) return;
this.handkeCheck1(k.children);
});
},
handkeCheck(list, e, e1) {
//
list.forEach((k, i) => {
if (k.children != undefined) {
if (k.id == e.id && e.checked == true) {
k.checked = true;
// console.log(k.id,'');
this.handkeChecks(k.children, e, e1);
} else if (k.id == e.id && e.checked == false) {
k.checked = false;
this.handkeChecks(k.children, e, e1);
} else {
this.handkeCheck(k.children, e, e1);
}
} else {
// console.log(1);
if (k.id == e.id && e.checked == true) {
k.checked = true;
} else if (k.id == e.id && e.checked == false) {
k.checked = false;
}
}
});
},
handkeChecks(list, e, e1) {
list.forEach((k, i) => {
if (k.children != undefined) {
if (e.checked) {
k.checked = true;
this.handkeChecks(k.children, e, e1);
} else {
k.checked = false;
this.handkeChecks(k.children, e, e1);
}
} else {
// console.log(k, 'else');
if (e.checked) {
k.checked = true;
} else {
k.checked = false;
}
}
});
},
//
_fixMultiple(index) {
if (!this.multiple) {
//
this.treeList.forEach((v, i) => {
if (i != index) {
this.treeList[i].checked = false;
} else {
//
// this.treeList[i].checked = true;
// console.log(index,'4444');
}
});
}
},
//
_reTreeList() {
this.treeList.forEach((v, i) => {
this.treeList[i].checked = v.orChecked;
});
},
_initTree(range = this.range) {
// console.log('');
this.treeList = [];
this._renderTreeList(range);
// console.log(this.treeList)
this.$nextTick(() => {
this._defaultSelect(range);
if (this.treeList.length > 0) {
this.treeList.map((item, index) => {
// if( this.value.indexOf(item.id)>=0){
if (!this.multiple) {
//
if (this.value === item.id) {
//
this.treeList[index].checked = true;
}
} else {
if (("," + this.value + ",").indexOf("," + item.id + ",") >= 0) {
this.treeList[index].checked = true;
}
}
});
}
});
//
this.treeList.map((item, index) => {
if(item.parentId&&item.parentId.length>0){
item.parentId.forEach(ii => {
this.treeList.filter((p) => {
if (p.id == ii) {
p.count=p.count+item.count;
}
});
});
}
});
var _this = this;
setTimeout(function () {
var inidata = _this.treeList;
_this.treeListData = [...inidata];
}, 800);
},
_initcount(cell){
}
},
watch: {
defaultIds(value) {
this._initTree();
},
range(list) {
// console.log('1');
this._initTree(list);
},
multiple() {
// console.log('2');
if (this.range.length) {
this._reTreeList();
}
},
selectParent() {
// console.log('3');
if (this.range.length) {
this._reTreeList();
}
},
deep: true, //
immediate: true, //
},
mounted() {
this._initTree();
},
};
</script>
<style scoped>
@import "./style.css";
</style>

@ -0,0 +1,157 @@
.tki-tree-mask {
position: fixed;
top: 0rpx;
right: 0rpx;
bottom: 0rpx;
left: 0rpx;
z-index: 9998;
background-color: rgba(0, 0, 0, 0.6);
opacity: 0;
transition: all 0.3s ease;
visibility: hidden;
}
.tki-tree-mask.show {
visibility: visible;
opacity: 1;
}
.tki-tree-cnt {
position: fixed;
top: 0rpx;
right: 0rpx;
bottom: 0rpx;
left: 0rpx;
z-index: 9999;
top: 225rpx;
transition: all 0.3s ease;
transform: translateY(100%);
}
.tki-tree-cnt.show {
transform: translateY(0);
}
.tki-tree-bar {
background-color: #fff;
height: 100rpx;
padding-left: 20rpx;
padding-right: 20rpx;
display: flex;
justify-content: space-between;
align-items: center;
box-sizing: border-box;
border-bottom-width: 2rpx !important;
border-bottom-style: solid;
border-bottom-color: #f5f5f5;
font-size: 32rpx;
color: #757575;
line-height: 1;
}
.tki-tree-bar-confirm {
color: #89965f;
}
.tki-tree-view {
position: absolute;
top: 0rpx;
right: 0rpx;
bottom: 0rpx;
left: 0rpx;
top: 100rpx;
background-color: #fff;
padding-top: 20rpx;
padding-right: 20rpx;
padding-bottom: 20rpx;
padding-left: 20rpx;
}
.tki-tree-view-sc {
height: 100%;
overflow: hidden;
}
.tki-tree-item {
display: flex;
justify-content: space-between;
align-items: center;
font-size: 26rpx;
color: #757575;
line-height: 1;
height: 0;
opacity: 0;
transition: 0.2s;
position: relative;
overflow: hidden;
}
.tki-tree-item.show {
height: 100rpx;
opacity: 1;
}
.tki-tree-item.showchild:before {
transform: rotate(90deg);
}
.tki-tree-item.last:before {
opacity: 0;
}
.tki-tree-icon {
width: 26rpx;
height: 26rpx;
margin-right: 8rpx;
}
.tki-tree-label {
flex: 1;
display: flex;
align-items: center;
height: 100%;
line-height: 1.2;
word-break: break-all;
}
.tki-tree-check {
width: 40px;
height: 40px;
display: flex;
justify-content: center;
align-items: center;
}
.tki-tree-check-yes,
.tki-tree-check-no {
width: 20px;
height: 20px;
border-top-left-radius: 20%;
border-top-right-radius: 20%;
border-bottom-right-radius: 20%;
border-bottom-left-radius: 20%;
border-top-width: 2rpx;
border-left-width: 2rpx;
border-bottom-width: 2rpx;
border-right-width: 2rpx;
border-style: solid;
border-color: #89965f;
display: flex;
justify-content: center;
align-items: center;
box-sizing: border-box;
}
.tki-tree-check-yes-b {
width: 12px;
height: 12px;
border-top-left-radius: 20%;
border-top-right-radius: 20%;
border-bottom-right-radius: 20%;
border-bottom-left-radius: 20%;
background-color: #89965f;
}
.tki-tree-check .radio {
border-top-left-radius: 50%;
border-top-right-radius: 50%;
border-bottom-right-radius: 50%;
border-bottom-left-radius: 50%;
}
.tki-tree-check .radio .tki-tree-check-yes-b {
border-top-left-radius: 50%;
border-top-right-radius: 50%;
border-bottom-right-radius: 50%;
border-bottom-left-radius: 50%;
}
.hover-c {
opacity: 0.6;
}
.tki-tree-bar-title{
color:#000000;
width: 66%;
text-align: center;
}

@ -0,0 +1,571 @@
<template>
<view>
<view class="submit">
<view class="submit-chat">
<view class="bt-img" @tap="records">
<image :src="toc"></image>
</view>
<!-- 文本框 -->
<textarea :maxlength="-1" :auto-height="true" :adjust-position="true" confirm-type="send" :cursor-spacing="10"
:selection-start="selectionStart" :selection-end="selectionEnd" class="chat-send btnt" :class="{displaynone:isrecord}"
@confirm="sendMsg" @input="inputs" @focus="focus" v-model="msg"></textarea>
<view class="record btn" :class="{displaynone:!isrecord}" @touchstart="touchstart" @touchend="touchend"
@touchmove="touchmove">
按住说话
</view>
<view class="bt-img" @tap="emoji">
<image src="../../static/icon/emote.png"></image>
</view>
<view v-if="ifmore" class="bt-img" @tap="more">
<image src="../../static/icon/more.png"></image>
</view>
<u-button v-if="!ifmore" @tap="sendMsg" style="background-color: #89965f; width: 88rpx;color: #fff;border-radius: 10rpx;"></u-button>
</view>
<!-- 表情框 -->
<view class="emoji" :class="{displaynone:!isemoji}">
<view class="emoji-send">
<!-- <view class="emoji-send-det" @tap="emojiBack">
<image src="../../static/icon/emote.png"></image>
</view> -->
<view class="emoji-send-bt" @tap="emojiSend"></view>
</view>
<emoji @emotion="emotion" :height="260"></emoji>
</view>
<!-- 更多操作框 -->
<view class="more" :class="{displaynone:!ismore}">
<view class="more-list" @tap="sendImg('album')">
<image src="../../static/icon/image.png"></image>
<view class="more-list-title">图片</view>
</view>
<view class="more-list" @tap="sendImg('camera')">
<image src="../../static/icon/photo.png"></image>
<view class="more-list-title">拍照</view>
</view>
<!-- <view class="more-list" @tap="choseLocation">
<image src="../../static/icon/location.png"></image>
<view class="more-list-title">定位</view>
</view> -->
<view class="more-list" @click="chooseVideo()">
<image src="../../static/icon/video.png"></image>
<view class="more-list-title">拍摄视频</view>
</view>
<!-- <view class="more-list">
<image src="../../static/icon/file.png"></image>
<view class="more-list-title">文件</view>
</view> -->
</view>
</view>
<view class="voice-bg" :class="{displaynone:!voicebg}">
<view class="voice-bg-len">
<view class="voice-bg-time" :style="{width:vlength/0.6+'%'}">
{{vlength}}
</view>
<view class="voice-del">上滑取消录音</view>
</view>
</view>
<u-toast ref="uToast" />
</view>
</template>
<script>
//
import emoji from '../emoji/emoji.vue'
//
const recorderManager = uni.getRecorderManager();
export default {
components: {
emoji,
},
data() {
return {
isrecord: false,
isemoji: false,
ismore: false,
ifmore: true,
voicebg: false,
pageY: 0,
msg: "",
// require
toc: require('../../static/icon/voice.png'),
timer: '', //
vlength: 0,
selectionStart: 0,
selectionEnd: 0
};
},
methods: {
//
getElementHeight() {
const query = uni.createSelectorQuery().in(this);
query.select('.submit').boundingClientRect(data => {
this.$emit('heights', data.height);
}).exec();
},
//
records() {
//
this.ismore = false
this.isemoji = false
//
setTimeout(() => {
this.getElementHeight();
}, 10)
if (this.isrecord) {
this.isrecord = false;
this.toc = require("../../static/icon/voice.png");
} else {
this.isrecord = true;
this.toc = require("../../static/icon/keyboard.png");
}
},
//
emoji() {
console.log('emoji')
this.isemoji = !this.isemoji;
//
this.ismore = false
this.isrecord = false;
this.toc = require("../../static/icon/voice.png");
//
setTimeout(() => {
this.getElementHeight();
}, 10)
},
//
emotion(e) {
console.log(e),
this.msg = this.msg + e
},
//
sendMsg(e) {
console.log(e.detail.value,this.msg)
// var chatm = e.detail.value;
// var pos = chatm.indexOf('\n');
this.updateCursor();
// -1
// if (pos != -1 && chatm.length > 1) {
// this.$emit('inputs', this.msg);
// setTimeout(() => {
// this.msg = '';
// }, 0)
// }
if (this.msg.length > 1) {
// 0
this.send(this.msg, 'txt');
this.ifmore=true;
}
},
inputs(e) {
var chatm = e.detail.value;
if (chatm.length > 1) {
this.ifmore=false;
}
else{
this.ifmore=true;
}
},
updateCursor() {
// text
this.selectionStart = this.msg.length;
this.selectionEnd = this.msg.length;
},
//
focus() {
console.log('focus');
//
// this.isemoji = false;
// this.ismore = false;
setTimeout(() => {
this.getElementHeight()
}, 10);
},
//
emojiSend() {
// if (this.msg.length > 0) {
// this.$emit('inputs', this.msg);
// setTimeout(() => {
// this.msg = '';
// }, 0)
// }
if (this.msg.length > 0) {
//0
this.send(this.msg, 'txt')
}
},
// 退
emojiBack() {
if (this.msg.length > 0) {
this.msg = this.msg.substring(0, this.msg.length - 1);
}
},
//
more() {
console.log('more')
this.ismore = !this.ismore;
//
this.isemoji = false
this.isrecord = false;
this.toc = require("../../static/icon/voice.png");
setTimeout(() => {
this.getElementHeight();
}, 10)
},
//
chooseVideo(){
var that =this;
uni.chooseVideo({
sourceType: ['camera', 'album'],
maxDuration: 60, //
success: function (res) {
console.log('选择视频成功,返回的参数:', res);
// 使 res.tempFilePath
const filePath = res.tempFilePath;
console.log(filePath);
if(that.checkImageSize(filePath)){
that.send(filePath, 'video');
}
else{
that.$refs.uToast.show({
title: "视频大小不能超过20M...",
type: "error",
duration: 2000,
});
}
},
fail: function (err) {
console.error('选择视频失败:', err);
}
});
},
//
sendImg(e) {
let count = 9;
if (e == 'album') {
count = 9;
} else {
count = 1;
}
uni.chooseImage({
count: count, //9
sizeType: ['original', 'compressed'], //
sourceType: [e], //
// success: function (res) { //functionsend
success: (res) => {
console.log(JSON.stringify(res.tempFilePaths));
const filePaths = res.tempFilePaths;
for (let i = 0; i < filePaths.length; i++) {
if(this.checkImageSize(filePath)){
this.send(filePaths[i], 'image')
}
else{
this.$refs.uToast.show({
title: "图片大小不能超过20M...",
type: "error",
duration: 2000,
});
}
}
}
});
},
checkImageSize(filePath) {
var ifsize= 0;
uni.getFileInfo({
filePath: filePath,
success: function (res) {
console.log('文件大小(字节):', res.size);
if (res.size > 20*1024 * 1024) { // 20MB
console.log('文件过大');
//
ifsize=0;
} else {
console.log('文件大小合适');
//
ifsize=1;
}
return ifsize;
},
fail: function (err) {
console.error('获取文件信息失败:', err);
return ifsize;
}
});
},
//
//
touchstart(e) {
console.log("开始录音")
console.log("点击产生数据", e)
this.pageY = e.changedTouches[0].pageY;
this.voicebg = true;
let i = 1;
this.timer = setInterval(() => {
this.vlength = i;
i++;
//
if (i > 60) {
clearInterval(this.timer);
this.touchend();
}
}, 1000)
recorderManager.start();
},
//
touchmove(e) {
// console.log("y",e.changedTouches[0].pageY);
if (this.pageY - e.changedTouches[0].pageY > 100) {
//
this.voicebg = false;
}
},
//
touchend() {
console.log("结束录音")
clearInterval(this.timer);
recorderManager.stop();
// recorderManager.onStop(function(res) {
recorderManager.onStop((res) => {
if(this.vlength<1){
this.$refs.uToast.show({
title: "录音时间过短...",
type: "warning",
duration: 2000,
});
}
else{
let data = {
voice: res.tempFilePath,
time: this.vlength
}
if (this.voicebg) {
this.send(data, 'audio');
}
}
// //
this.vlength = 0;
this.voicebg = false;
console.log('recorder stop' + JSON.stringify(res));
// self.voicePath = res.tempFilePath;
});
},
//
choseLocation() {
uni.chooseLocation({
// success: function(res) {
success: res => {
let data = {
name: res.name,
address: res.address,
latitude: res.latitude,
longitude: res.longitude
}
this.send(data, 3);
// console.log('' + res.name);
// console.log('' + res.address);
// console.log('' + res.latitude);
// console.log('' + res.longitude);
}
});
},
//
send(msg, type) {
console.log(msg, type)
let date = {
message: msg,
type: type
}
this.$emit('inputs', date);
setTimeout(() => {
this.msg = '';
}, 0)
}
}
};
</script>
<style lang="scss" scoped>
.submit {
background: rgba(244, 244, 244, 0.96);
border-top: 1px solid rgba(39, 40, 50, 0.1);
width: 100%;
position: fixed;
bottom: 0;
z-index: 999;
padding-bottom: var(--status-bar-height);
// padding-bottom: env(safe-area-inset-bottom);
}
.displaynone {
display: none;
}
.submit-chat {
width: 100%;
display: flex;
align-items: flex-end;
box-sizing: border-box;
padding: 14rpx 20rpx;
image {
width: 56rpx;
height: 56rpx;
margin: 0 10rpx;
flex: auto;
}
.btnt {
flex: auto;
background-color: #fff;
border-radius: 10rpx;
padding: 20rpx;
max-height: 240rpx;
margin: 0 10rpx;
overflow-y: auto;
}
.btn {
flex: auto;
background-color: #fff;
border-radius: 10rpx;
padding: 20rpx;
max-height: 160rpx;
margin: 0 10rpx;
}
.chat-send {
line-height: 44rpx;
}
.record {
line-height: 44rpx;
text-align: center;
font-size: 20rpx;
color: rgba(39, 40, 50, 0.6);
}
}
.emoji {
width: 100%;
height: 460rpx;
background: rgba(236, 237, 238, 1);
box-shadow: 0px 11rpx 0px 0px rgba(0, 0, 0, 0.1);
.emoji-send {
width: 150rpx;
height: 104rpx;
padding-top: 24rpx;
background-color: rgba(236, 237, 238, 0.8);
position: fixed;
// bottom: 0;
bottom: env(safe-area-inset-bottom);
right: 0;
display: flex;
.emoji-send-bt {
flex: 1;
margin: 0 32rpx 0 20rpx;
height: 80rpx;
background: rgba(255, 228, 49, 1);
font-size: 32rpx;
text-align: center;
line-height: 80rpx;
border-radius: 12rpx;
}
.emoji-send-det {
flex: 1;
margin-left: 24rpx;
height: 80rpx;
background: #fff;
font-size: 32rpx;
text-align: center;
line-height: 80rpx;
border-radius: 12rpx;
image {
width: 42rpx;
height: 32rpx;
}
}
}
}
.more {
width: 100%;
min-height: 220rpx;
background: rgba(236, 237, 238, 1);
box-shadow: 0px 11rpx 0px 0px rgba(0, 0, 0, 0.1);
bottom: env(safe-area-inset-bottom);
padding: 8rpx 20rpx;
box-sizing: border-box;
.more-list {
width: 25%;
text-align: center;
float: left;
padding-top: 32rpx;
image {
width: 90rpx;
height: 90rpx;
padding: 24rpx;
background: rgba(255, 255, 255, 1);
border-radius: 24rpx;
}
.more-list-title {
font-size: 24rpx;
color: rgba(39, 40, 50, 0.5);
line-height: 34rpx;
}
}
}
.voice-bg {
height: 100%;
width: 100%;
background-color: rgba(0, 0, 0, 0.3);
position: fixed;
top: 0;
bottom: 0;
z-index: 1001;
.voice-bg-len {
height: 84rpx;
width: 600rpx;
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
margin: auto;
background-color: rgba(255, 255, 255, 0.2);
border-radius: 42rpx;
text-align: center;
}
.voice-bg-time {
display: inline-block;
min-width: 120rpx;
line-height: 84rpx;
background-color: #89965f;
border-radius: 42rpx;
color:#ffffff;
}
.voice-del {
position: absolute;
bottom: -480rpx;
width: 100%;
text-align: center;
color: #fff;
font-size: 28rpx;
}
}
</style>

@ -0,0 +1,295 @@
<template>
<view>
<view class="upload">
<block v-for="(upload,index) in uploads" :key="index">
<view class="uplode-file">
<image v-if="types == 'image'" class="uploade-img" :src="upload" :data-src="upload" @tap="previewImage"></image>
<image v-if="types == 'image'" class="clear-one-icon" :src="clearIcon" @tap="delImage(index)"></image>
<video v-if="types == 'video'" class="uploade-img" :src="upload" controls>
<cover-image v-if="types == 'video'" class="clear-one-icon" :src="clearIcon" @tap="delImage(index)"></cover-image>
</video>
</view>
</block>
<view v-if="uploads.length < uploadCount" :class="uploadIcon ? 'uploader-icon' : 'uploader-input-box'">
<view v-if="!uploadIcon" class="uploader-input" @tap="chooseUploads"></view>
<image v-else class="image-cion" :src="uploadIcon" @tap="chooseUploads"></image>
</view>
</view>
<button type="primary" v-if="types == 'image' && !autoUpload" @tap="unifiedUpload"></button>
</view>
</template>
<script>
export default{
props: {
types: {
type: String,
default: 'image'
},
dataList: {
type: Array,
default: function() {
return []
}
},
clearIcon: {
type: String,
default: 'http://img1.imgtn.bdimg.com/it/u=451604666,2295832001&fm=26&gp=0.jpg'
},
uploadIcon: {
type: String,
default: ''
},
uploadUrl: {
type: String,
default: ''
},
deleteUrl: {
type: String,
default: ''
},
uploadCount: {
type: Number,
default: 1
},
// 3M
upload_max: {
type: Number,
default: 3
},
autoUpload: {
type: Boolean,
default: false
}
},
data(){
return {
//
uploadImages: [],
//
uploads: [],
//
exceeded_list: [],
}
},
watch:{
dataList:{
handler(val){
this.uploads = val;
},
immediate: true
}
},
methods:{
previewImage (e) {
var current = e.target.dataset.src
uni.previewImage({
current: current,
urls: this.dataList
})
},
chooseUploads(){
switch (this.types){
case 'image':
uni.chooseImage({
count: this.uploadCount - this.uploads.length, //9
sizeType: ['original', 'compressed'], //
sourceType: ['album', 'camera'], //
success: (res) => {
for(let i = 0; i< res.tempFiles.length; i++){
if(Math.ceil(res.tempFiles[i].size / 1024) < this.upload_max * 1024){
this.uploads.push(res.tempFiles[i].path)
if(this.autoUpload){
this.uploadFile(res.tempFiles[i].path)
}else{
this.uploadImages.push(res.tempFiles[i].path);
}
}else {
this.exceeded_list.push(i === 0 ? 1 : i + 1);
uni.showModal({
title: '提示',
content: `${[...new Set(this.exceeded_list)].join(',')}张图片超出限制${this.upload_max}MB,已过滤`
});
}
}
},
fail: (err) => {
uni.showModal({
content: JSON.stringify(err)
});
}
});
break;
case 'video' :
uni.chooseVideo({
sourceType: ['camera', 'album'],
success: (res) => {
if(Math.ceil(res.size / 1024) < this.upload_max * 1024){
this.uploads.push(res.tempFilePath)
uni.uploadFile({
url: this.uploadUrl, //
filePath: res.tempFilePath,
name: 'file',
//
formData: {
'user': 'test'
},
success: (uploadFileRes) => {
this.$emit('successVideo',uploadFileRes)
}
});
}else {
uni.showModal({
title: '提示',
content: `${[...new Set(this.exceeded_list)].join(',')}张视频超出限制${this.upload_max}MB,已过滤`
});
}
},
fail: (err) => {
uni.showModal({
content: JSON.stringify(err)
});
}
});
break;
}
},
delImage(index){
//apph5
if(this.uploads[index].substring(0,4) !== 'http' || this.uploads[index].substring(0,11) == 'http://tmp/'){
this.uploads.splice(index,1)
return;
};
if(!this.deleteUrl) {
uni.showModal({
content: '请填写删除接口'
});
return;
};
uni.request({
url: this.deleteUrl,
method: 'DELETE',
data: {
image: this.dataList[index]
},
success: res => {
if(res.data.status == 1) {
uni.showToast({
title: '删除成功'
})
this.uploads.splice(index,1)
}
},
});
},
uploadFile(path){
uni.uploadFile({
url: this.uploadUrl, //
filePath: path,
name: 'file',
//
formData: {
'user': 'test'
},
success: (uploadFileRes) => {
this.$emit('successImage',uploadFileRes)
}
});
},
unifiedUpload(){
if(!this.uploadUrl) {
uni.showModal({
content: '请填写上传接口'
});
return;
};
for (let i of this.uploadImages) {
this.uploadFile(i)
}
}
}
}
</script>
<style scoped>
.upload {
display: flex;
flex-direction: row;
flex-wrap: wrap;
}
.uplode-file {
margin: 10upx;
width: 210upx;
height: 210upx;
position: relative;
}
.uploade-img {
display: block;
width: 210upx;
height: 210upx;
}
.clear-one{
position: absolute;
top: -10rpx;
right: 0;
}
.clear-one-icon{
position: absolute;
width: 20px;
height: 20px;
top: 0;
right: 0;
z-index: 9;
}
.uploader-input-box {
position: relative;
margin:10upx;
width: 208upx;
height: 208upx;
border: 2upx solid #D9D9D9;
}
.uploader-input-box:before,
.uploader-input-box:after {
content: " ";
position: absolute;
top: 50%;
left: 50%;
-webkit-transform: translate(-50%, -50%);
transform: translate(-50%, -50%);
background-color: #D9D9D9;
}
.uploader-input-box:before {
width: 4upx;
height: 79upx;
}
.uploader-input-box:after {
width: 79upx;
height: 4upx;
}
.uploader-input-box:active {
border-color: #999999;
}
.uploader-input-box:active:before,
.uploader-input-box:active:after {
background-color: #999999;
}
.uploader-input {
position: absolute;
z-index: 1;
top: 0;
left: 0;
width: 100%;
height: 100%;
opacity: 0;
}
.uploader-icon{
position: relative;
margin:10upx;
width: 208upx;
height: 208upx;
}
.uploader-icon .image-cion{
width: 100%;
height: 100%;
}
</style>

@ -0,0 +1,77 @@
<template>
<view class="emoji" :style="{height:height+'px'}">
<view class="emoji-line" v-for="(line,i) in emoji" :key="i">
<view class="emoji-line-item" v-for="(item,index) in line" :key="index" @tap="clickEmoji(item)">{{item}}
</view>
</view>
</view>
</template>
<script>
export default {
props:{
height:{
type:Number,
default:260
}
},
name: "emoji",
data() {
return {
emoji: [
['😀', '😁', '😂', '🤣', '😃', '😃', '😅'],
['😄', '😆', '😉', '😊', '😋', '😎', '😍'],
['😎', '😘', '😗', '😙', '🙂', '🤗', '😑'],
['😏', '😣', '😥', '😮', '🤐', '😯', '😶'],
['😪', '😫', '😴', '😌', '😛', '🤤', '🙄'],
['😒', '😓', '😕', '🙃', '🤑', '🙁', '😚'],
['😖', '😤', '😭', '😨', '😰', '😬', '😵'],
['😱', '😡', '😷', '💀', '👻', '💍', '💄'],
['💩', '👑', '🎓', '👀', '💪🏻', '☝🏻', '✌🏼'],
['🤘🏻', '🤙🏼', '👌🏻', '✊🏻', '👍🏼', '👎🏻', '👏🏻'],
['🙏🏻', '🤝', '🍖', '🍲', '🍦', '🍰'] //'🍔',
],
emojiindex: [
[11, 12, 13, 14, 15, 16,17],
[21, 22, 23, 24, 25, 26, 27],
[31, '😘', '😗', '😙', '🙂', '🤗', '😑'],
[41, '😣', '😥', '😮', '🤐', '😯', '😶'],
[51, '😫', '😴', '😌', '😛', '🤤', '🙄'],
[61, '😓', '😕', '🙃', '🤑', '🙁', '😚'],
[71, '😤', '😭', '😨', '😰', '😬', '😵'],
[81, '😡', '😷', '💀', '👻', '💍', '💄'],
[91, '👑', '🎓', '👀', '💪🏻', '☝🏻', '✌🏼'],
['🤘🏻', '🤙🏼', '👌🏻', '✊🏻', '👍🏼', '👎🏻', '👏🏻'],
['🙏🏻', '🤝', '🍖', '🍲', '🍦', '🍰'] //'🍔',
]
};
},
methods: {
clickEmoji(e) {
this.$emit('emotion', e)
}
}
}
</script>
<style lang="scss">
.emoji {
width: 100%;
// height: 460rpx;
padding: 16rpx 10rpx 130rpx 10rpx;
box-sizing: border-box;
overflow: hidden;
overflow-y: auto;
.emoji-line{
display: flex;
.emoji-line-item {
flex: 1;
text-align: center;
font-size: 44rpx;
line-height: 140rpx;
}
}
}
</style>

@ -0,0 +1,46 @@
// 贝塞尔算法
function bezier(pots, amount) {
var pot;
var lines;
var ret = [];
var points;
for (var i = 0; i <= amount; i++) {
points = pots.slice(0);
lines = [];
while (pot = points.shift()) {
if (points.length) {
lines.push(pointLine([pot, points[0]], i / amount));
} else if (lines.length > 1) {
points = lines;
lines = [];
} else {
break;
}
}
ret.push(lines[0]);
}
function pointLine(points, rate) {
var pointA, pointB, pointDistance, xDistance, yDistance, tan, radian, tmpPointDistance;
var ret = [];
pointA = points[0];//点击
pointB = points[1];//中间
xDistance = pointB.x - pointA.x;
yDistance = pointB.y - pointA.y;
pointDistance = Math.pow(Math.pow(xDistance, 2) + Math.pow(yDistance, 2), 1 / 2);
tan = yDistance / xDistance;
radian = Math.atan(tan);
tmpPointDistance = pointDistance * rate;
ret = {
x: pointA.x + tmpPointDistance * Math.cos(radian),
y: pointA.y + tmpPointDistance * Math.sin(radian)
};
return ret;
}
return {
'bezier_points': ret
};
}
export default {
bezier
}

@ -0,0 +1,157 @@
<template>
<view class="container">
<!-- 加入购物车的小球 -->
<view class="good_box" v-if="!hide_good_box" :style="'left:'+bus_x+'px;top:'+bus_y+'px;'">
<image :src="imgUrl"></image>
</view>
</view>
</template>
<script>
import $flyInData from '@/components/fly-in-cart/fly-in-cart.js'
export default {
data() {
return {
count: 0,
hide_good_box: true,
finger: {},
busPos: {},
bus_x: 0,
bus_y: 0,
imgUrl: '',
}
},
props: {
cartx: { //X 0-1
type: String,
default: '0'
},
carty: { //y 0-1
type: String,
default: '0'
},
},
created: function() {
/** 计算购物车的坐标 **/
var that = this;
uni.getSystemInfo({
success: function(res) {
let ww = res.windowWidth;//
let hh = res.windowHeight;//
//
let devx = 1;//x
let devy = 1;//y
// #ifdef APP-PLUS
devx = 1;
devy = 0.93;
// #endif
// #ifdef MP-WEIXIN
devx = 1;
devy = 0.9;
// #endif
// #ifdef H5
devx = 1;
devy = 1;
// #endif
that.busPos['x'] = ww * that.cartx * devx; //*cartxX x
that.busPos['y'] = hh * that.carty * devy; //*cartyy y
}
})
that.count = 0;
},
methods: {
touchOnGoods: function(e) {
this.imgUrl = e.currentTarget.dataset.img;
// good_box
if (!this.hide_good_box) return;
var topPoint = {};
this.finger['x'] = e.touches["0"].clientX-13; // x
this.finger['y'] = e.touches["0"].clientY-10; // y -10,
if (this.finger['y'] < this.busPos['y']) {
topPoint['y'] = this.finger['y'] - 150;
} else {
topPoint['y'] = this.busPos['y'] - 150;
}
topPoint['x'] = Math.abs(this.finger['x'] - this.busPos['x']) / 2;
/** this.finger['x']是点击位置X坐标 this.busPos['x']是购物车X坐标***/
if (this.finger['x'] > this.busPos['x']) {
/* 当点击位置X坐标>购物车X坐标 时 执行 左抛物线 **/
topPoint['x'] = (this.finger['x'] - this.busPos['x']) / 2 + this.busPos['x'];
/* 贝塞尔算法 创建从购物车到点击位置的 抛物线 抛物线本身并不分左右*/
this.linePos = $flyInData.bezier([this.busPos, topPoint, this.finger], 30);
this.startAnimationLeft(); //线 线
} else {
/* 当点击位置X坐标<购物车X坐标 时 执行 右抛物线 **/
topPoint['x'] = (this.busPos['x'] - this.finger['x']) / 2 + this.finger['x'];
/* 贝塞尔算法 创建从点击位置到购物车的 抛物线 抛物线本身并不分左右*/
this.linePos = $flyInData.bezier([this.finger, topPoint, this.busPos], 30);
this.startAnimationRight(); //线 线
}
},
/* 向右抛物线 根据抛弧线数据 定时器修改good_box style left 和 top 的值来实现动画效果 */
startAnimationRight: function() {
var index = 0,
that = this,
bezier_points = that.linePos['bezier_points'];//线
that.bus_x = that.finger['x']
that.bus_y = that.finger['y']
that.hide_good_box = false
that.timer = setInterval(function() {
index++;
that.bus_x = bezier_points[index]['x']
that.bus_y = bezier_points[index]['y']
if (index >= 28) {
clearInterval(that.timer);
that.hide_good_box = true,
that.hideCount = false,
that.count = that.count += 1
}
}, 20); //
},
/* 向左抛物线 */
startAnimationLeft: function() {
var index = 0,
that = this,
bezier_points = that.linePos['bezier_points'];
that.bus_x = that.finger['x']
that.bus_y = that.finger['y']
that.hide_good_box = false
var len = bezier_points.length;
index = len
that.timer = setInterval(function() {
index--;
that.bus_x = bezier_points[index]['x']
that.bus_y = bezier_points[index]['y']
if (index < 1) {
clearInterval(that.timer);
that.hide_good_box = true,
that.hideCount = false,
that.count = that.count += 1
}
}, 20); //
}
}
}
</script>
<style lang="scss">
.container {
.good_box {
width: 30px;
height: 30px;
position: fixed;
border-radius: 50%;
overflow: hidden;
left: 50%;
top: 50%;
z-index: +99999;
}
.good_box image {
display: block;
width: 100%;
height: 100%;
}
}
</style>

@ -0,0 +1,241 @@
<template>
<view class="uni-combox">
<view v-if="label" class="uni-combox__label" :style="labelStyle">
<text>{{label}}</text>
</view>
<view class="uni-combox__input-box">
<input class="uni-combox__input" type="text" :placeholder="placeholder" v-model="inputVal" @input="onInput" @focus="onFocus" @blur="onBlur" />
<!-- <uni-icons class="uni-combox__input-arrow" type="arrowdown" size="14" @click="toggleSelector"></uni-icons> 源代码注释掉上下距离太高不好看,去掉源码中class-->
<uni-icons type="arrowdown" size="18" v-if="inputVal===''" color="#999999" @click="toggleSelector"></uni-icons> <!-- 下箭头颜色#999999 -->
<uni-icons type="clear" size="18" v-else color="#999999" @click="clearInputVal"></uni-icons> <!-- add by limeng 追加的代码片段用叉号图标快速清空输入框 -->
<view class="uni-combox__selector" v-if="showSelector">
<scroll-view scroll-y="true" class="uni-combox__selector-scroll">
<view class="uni-combox__selector-empty" v-if="filterCandidatesLength === 0">
<text>{{emptyTips}}</text>
</view>
<view class="uni-combox__selector-item" v-for="(item,index) in filterCandidates" :key="index" @click="onSelectorClick(index)">
<text>{{item}}</text>
</view>
</scroll-view>
</view>
</view>
</view>
</template>
<script>
import uniIcons from '../uni-icons/uni-icons.vue'
export default {
name: 'uniCombox',
components: {
uniIcons
},
props: {
label: {
type: String,
default: ''
},
labelWidth: {
type: String,
default: 'auto'
},
placeholder: {
type: String,
default: ''
},
/**
candidates: {
type: Array,
default () {
return []
}
},*/
//add by limeng 20210702 map
candidatesMap: {
type: Map,//使
default () {
return {}
}
},
emptyTips: {
type: String,
default: '无匹配项'
},
value: {
type: String,
default: ''
}
},
data() {
return {
showSelector: false,
inputVal: '', //
inputValId: '',//add by limeng id(id)
}
},
computed: {
labelStyle() {
if (this.labelWidth === 'auto') {
return {}
}
return {
width: this.labelWidth
}
},
filterCandidates() {
//candidatesMap keycandidates
var candidates = [];//
this.candidatesMap.forEach(function(value, key){
var key = key;
candidates.push(key);//
})
return candidates.filter((item) => {
return item.indexOf(this.inputVal) > -1
})
},
filterCandidatesLength() {
return this.filterCandidates.length
}
},
watch: {
value: {
handler(newVal) {
this.inputVal = newVal
},
immediate: true
},
},
methods: {
toggleSelector() {
this.showSelector = !this.showSelector
},
onFocus() {
this.showSelector = true
},
onBlur() {
/**update by limeng 20210710
离开输入框焦点的时候输入框里的内容必须包含在下拉框列表中
否则输入框内容是用户瞎写的没有意义后台也无法识别
因此,强制用户必须以选中的为准
备注提供输入功能仅仅是为了匹配合适的下拉选项但不能以输入的值为准,必须以选中的为准
*/
//if(this.candidates.indexOf(this.inputVal) > -1){ //
if(this.filterCandidates.indexOf(this.inputVal) > -1){ //
//alert("");
//()
setTimeout(() => {
this.showSelector = false
}, 50)
}else {
//alert("");
return;
}
},
onSelectorClick(index) {//index 1,2,3...,mapkey value
this.inputVal = this.filterCandidates[index]//
this.inputValId = this.candidatesMap.get(this.inputVal);//idcode(便)
this.showSelector = false;//
this.$emit('input', this.inputVal);//(name)input,v-model
this.$emit("setId",this.inputValId);//nameidcode,setIddata
},
onInput() {
setTimeout(() => {
this.$emit('input', this.inputVal)
})
},
clearInputVal(){
this.inputVal='';
this.inputValId = '';//id
this.$emit("setId",'');//
}
}
}
</script>
<style scoped>
.uni-combox {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
height: 40px;
flex-direction: row;
align-items: center;
/* border-bottom: solid 1px #DDDDDD;
*/
}
.uni-combox__label {
font-size: 16px;
line-height: 22px;
padding-right: 10px;
color: #999999;
}
.uni-combox__input-box {
position: relative;
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex: 1;
flex-direction: row;
align-items: center;
}
.uni-combox__input {
flex: 1;
font-size: 33upx;/*16px*/
height: 25px;
line-height: 22px;
}
.uni-combox__input-arrow {
padding: 10px;
}
.uni-combox__selector {
box-sizing: border-box;
position: absolute;
top: 42px;
left: 0;
width: 100%;
background-color: #FFFFFF;
border-radius: 0px;
box-shadow: #DDDDDD 4px 4px 8px, #DDDDDD -4px -4px 8px;
z-index: 2;
}
.uni-combox__selector-scroll {
max-height: 500px;/*200px*/
box-sizing: border-box;
}
.uni-combox__selector::before {
content: '';
position: absolute;
width: 0;
height: 0;
border-bottom: solid 6px #FFFFFF;
border-right: solid 6px transparent;
border-left: solid 6px transparent;
left: 50%;
top: -6px;
margin-left: -6px;
}
.uni-combox__selector-empty,
.uni-combox__selector-item {
/* #ifdef APP-NVUE */
display: flex;
/* #endif */
line-height: 50px;/*36px*/
font-size: 33upx;/* 14px*/
text-align: center;
border-bottom: solid 1px #DDDDDD;
margin: 0px 10px;
}
.uni-combox__selector-empty:last-child,
.uni-combox__selector-item:last-child {
border-bottom: none;
}
</style>

@ -0,0 +1,36 @@
<template>
<iframe :onload="onloadCode" style="width:460rpx;height:100%;border:1px solid #fff;background: #000;border-radius: 20rpx;"></iframe>
</template>
<script>
export default {
name: "myVideo",
props: {
videoUrl: {
//
type: String,
default: "",
},
},
data() {
return {
onloadCode: `
const url = '${this.videoUrl}'
this.contentWindow.document.body.innerHTML = '<video style="width: 100%;height: 100%" controls="controls" src="'+url+'"></video>';
const iframe = top.document.getElementsByTagName('iframe')[0]
var evObj = document.createEvent('MouseEvents');
evObj.initEvent( 'event1', true, false );
iframe.dispatchEvent(evObj)
`
// onloadCode: `
// const url = 'https://vd3.bdstatic.com/mda-mja2qsy47mbyh1xc/sc/cae_h264_clips/1633918903861514556/mda-mja2qsy47mbyh1xc.mp4?auth_key=1634030413-0-0-7898726f7bd328302e2119fdf694fd5e&bcevod_channel=searchbox_feed&pd=1&pt=3&abtest='
// this.contentWindow.document.body.innerHTML = '<video style="width: 100%;height: 100%" controls="controls" src="'+url+'"></video>';
// const iframe = top.document.getElementsByTagName('iframe')[0]
// var evObj = document.createEvent('MouseEvents');
// evObj.initEvent( 'event1', true, false );
// iframe.dispatchEvent(evObj)
// `
};
}
}
</script>

@ -0,0 +1,88 @@
<template>
<view class="step">
<u-steps v-if="id&&numList.length>0" ref='step' :list="numList" :current="current" mode="number" :icon="icon"></u-steps>
<view v-else class="lctips">暂无审批流程记录</view>
</view>
</template>
<script>
export default {
name: "lctree",
props: {
id: String,
},
data() {
return {
current:0,
icon: 'checkmark', //error', //checkmark',
numList: []
};
},
mounted() {
this._initTree();
},
methods: {
_initTree() {
if(this.id&&this.id!==null){
this.$u.api.getApprovalRecord(this.id).then(res => {
console.log(res);
if(!res.state){
var data = res;
var flowVoList = data.flowVoList ? data.flowVoList : [];
this.current=flowVoList.length;
if (flowVoList.length > 0) {
flowVoList.forEach((item,idx)=>{
var cell={};
if (item.opinionType == '1') {
//
cell={
name: item.stepContent
};
this.numList.push(cell);
}
else if(item.opinionType == '2'){
//
cell={
name: item.stepContent,
color:"#ff9900",
icon:"close",
};
this.numList.push(cell);
}
else {
if ((item.isStart&&item.isStart=='1') || item.stepContent=='发起申请') {
cell={
name: item.stepContent
};
this.numList.push(cell);
}
else{
//
cell={
name: item.stepContent
};
this.numList.push(cell);
this.current=idx;
}
}
});
}
}
});
}
}
}
}
</script>
<style lang="scss" scoped>
.step {
padding: 20rpx 0 0 0;
}
.lctips{
font-size:28rpx;
color: #000;
margin:0 auto;
text-align:center;
}
</style>

@ -0,0 +1,318 @@
<template>
<view class="uni-combox">
<view class="uni-combox-dialog" v-if="isDialogInput && showSelector">
<view class="uni-combox-input">
<input
class="uni-combox__input"
type="text"
:placeholder="selectItem.value ? selectItem.value : placeholder"
v-model="inputVal"
@input="onInput"
@blur="onBlur"
:focus="'true'"
style="height: 90upx;"
/>
<uni-icons style="line-height: 90upx;" class="uni-combox__input-arrow" type="close" size="14" @click="clearSelector"></uni-icons>
<view class="uni-combox__selector">
<scroll-view scroll-y="true" class="uni-combox__selector-scroll">
<view class="uni-combox__selector-empty" v-if="isLoading"><text>数据加载...</text></view>
<view class="uni-combox__selector-empty" v-if="filterCandidatesLength === 0 && !isLoading">
<text>{{ emptyTips }}</text>
</view>
<view v-if="!isLoading" class="uni-combox__selector-item" v-for="(item, index) in filterCandidates" :key="index" @click="onSelectorClick(item)">
<text>{{ item.value }}</text>
</view>
</scroll-view>
</view>
</view>
</view>
<view v-if="label" class="uni-combox__label" :style="labelStyle">
<text>{{ label }}</text>
</view>
<view class="uni-combox__input-box">
<input
v-if="isDialogInput"
class="uni-combox__input"
type="text"
:placeholder="selectItem.value ? selectItem.value : placeholder"
v-model="inputVal"
@focus="onFocus"
/>
<input
v-else
class="uni-combox__input"
type="text"
:placeholder="selectItem.value ? selectItem.value : placeholder"
v-model="inputVal"
@focus="onFocus"
@input="onInput"
@blur="onBlur"
/>
<uni-icons v-if="!showSelector && !inputVal" class="uni-combox__input-arrow" type="arrowdown" size="14" @click="toggleSelector"></uni-icons>
<uni-icons v-else class="uni-combox__input-arrow" type="close" size="14" @click="clearSelector"></uni-icons>
<view class="uni-combox__selector" v-if="!isDialogInput && showSelector">
<scroll-view scroll-y="true" class="uni-combox__selector-scroll">
<view class="uni-combox__selector-empty" v-if="isLoading"><text>数据加载...</text></view>
<view class="uni-combox__selector-empty" v-if="filterCandidatesLength === 0 && !isLoading">
<text>{{ emptyTips }}</text>
</view>
<view v-if="!isLoading" class="uni-combox__selector-item" v-for="(item, index) in filterCandidates" :key="index" @click="onSelectorClick(item)">
<text>{{ item.value }}</text>
</view>
</scroll-view>
</view>
</view>
</view>
</template>
<script>
import uniIcons from '../uni-icons/uni-icons.vue';
/**
* Combox 组合输入框
* @description 组合输入框一般用于既可以输入也可以选择的场景
* @tutorial https://ext.dcloud.net.cn/plugin?id=1261
* @property {String} label 左侧文字
* @property {String} labelWidth 左侧内容宽度
* @property {String} placeholder 输入框占位符
* @property {Array} candidates 候选项列表
* @property {String} emptyTips 筛选结果为空时显示的文字
* @property {String} value 组合框的值
* @property {String} isDialogInput 弹出框输入和选择避免键盘遮挡
*/
export default {
name: 'uniCombox',
components: {
uniIcons
},
props: {
label: {
type: String,
default: ''
},
labelWidth: {
type: String,
default: 'auto'
},
placeholder: {
type: String,
default: ''
},
candidates: {
type: Array,
default() {
return [];
}
},
emptyTips: {
type: String,
default: '无匹配项'
},
value: {
type: String,
default: ''
},
isDialogInput: {
type: Boolean,
default: false
}
},
data() {
return {
showSelector: false,
inputVal: '',
isLoading: false,
showDowm: true,
selectItem: { key: '', value: '' }
};
},
computed: {
labelStyle() {
if (this.labelWidth === 'auto') {
return {};
}
return {
width: this.labelWidth
};
},
filterCandidates() {
return this.candidates.filter(item => {
return item;
});
},
filterCandidatesLength() {
return this.filterCandidates.length;
}
},
watch: {
value: {
handler(newVal) {
if(newVal) {
this.candidates.filter(item => {
if (this.value === item.key) {
this.selectItem = item;
this.inputVal = item.value;
}
});
}else {
this.selectItem = { key: '', value: '' }
this.inputVal = ''
}
},
immediate: true
},
candidates: {
handler(newVal) {
this.isLoading = false;
},
immediate: true
}
},
methods: {
toggleSelector() {
this.showSelector = !this.showSelector;
},
clearSelector() {
this.selectItem = { key: '', value: '' };
this.inputVal = '';
this.showSelector = false;
this.isLoading = false;
this.$emit('clear');
},
onFocus() {
this.showSelector = true;
if (this.inputVal) {
this.inputVal = '';
}
},
onBlur() {
setTimeout(() => {
if (this.selectItem.value) {
const selectItem = JSON.parse(JSON.stringify(this.selectItem));
this.inputVal = selectItem.value;
} else {
this.inputVal = '';
}
this.showSelector = false;
}, 50);
},
onSelectorClick(item) {
this.selectItem = item;
this.inputVal = item.value;
this.showSelector = false;
this.$emit('select', item.key, item);
},
onInput() {
setTimeout(() => {
if (this.inputVal) {
this.isLoading = true;
this.$emit('input', this.inputVal);
} else {
this.isLoading = false;
}
});
}
}
};
</script>
<style lang="scss" scoped>
.uni-combox {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
height: 40upx;
flex-direction: row;
align-items: center;
// border-bottom: solid 1px #DDDDDD;
}
.uni-combox__label {
font-size: 28upx;
line-height: 40upx;
padding-right: 10px;
color: #999999;
}
.uni-combox__input-box {
position: relative;
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex: 1;
flex-direction: row;
align-items: center;
}
.uni-combox__input {
flex: 1;
font-size: 28upx;
}
.uni-combox__input-arrow {
padding-left: 15upx;
padding-right: 15upx;
}
.uni-combox__selector {
box-sizing: border-box;
position: absolute;
top: 50px;
left: 0;
width: 100%;
background-color: #ffffff;
border-radius: 6px;
box-shadow: #dddddd 4px 4px 8px, #dddddd -4px -4px 8px;
z-index: 2;
}
.uni-combox__selector-scroll {
max-height: 350upx;
box-sizing: border-box;
}
.uni-combox__selector::before {
content: '';
position: absolute;
width: 0;
height: 0;
border-bottom: solid 6px #ffffff;
border-right: solid 6px transparent;
border-left: solid 6px transparent;
left: 50%;
top: -6px;
margin-left: -6px;
}
.uni-combox__selector-empty,
.uni-combox__selector-item {
/* #ifdef APP-NVUE */
display: flex;
/* #endif */
line-height: 70upx;
font-size: 28upx;
text-align: center;
border-bottom: solid 1px #dddddd;
margin: 0px 10px;
}
.uni-combox__selector-empty:last-child,
.uni-combox__selector-item:last-child {
border-bottom: none;
}
.uni-combox-dialog {
background: #cccccc7d;
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
z-index: 100;
}
.uni-combox-input {
background: #fff;
display: -webkit-box;
display: -webkit-flex;
display: flex;
height: 90upx;
}
</style>

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

@ -0,0 +1,3 @@
àRCopyright 1990-2009 Adobe Systems Incorporated.
All rights reserved.
See ./LICENSEáCNS2-H

@ -0,0 +1,3 @@
àRCopyright 1990-2009 Adobe Systems Incorporated.
All rights reserved.
See ./LICENSEá ETen-B5-H` ^

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save