Commit bc5c4c87 by 于方蒙

create project

parents
//app.js
App({
onLaunch: function () {
},
globalData: {
serverInfo:{
gateWayUrl:"https://m.dalvv.com/managerApi",
qrReplaceUrl:'https://m.dalvv.com/mini/1/',
uploadFileUrl:'https://m.dalvv.com/upFile',
},
    ThisWechatTarget:1,
    ThisWechatType:1,
handleNum:0,
indexIcon: [
{
icon: '../../images/index_icon/index_icon(2).png',
title: '设备管理',
url: '../deviceList/index',
index:0,
},
{
icon: '../../images/index_icon/index_icon(3).png',
title: '商品管理',
url: '../goodsList/index'
},
{
icon: '../../images/index_icon/index_icon(4).png',
title: '商品方案',
url: '../goodsPlan/index'
},
{
icon: '../../images/index_icon/index_icon(5).png',
title: '补货管理',
url: '../replenishment/index',
index:0,
},
{
icon: '../../images/index_icon/index_icon(6).png',
title: '订单管理',
url: '../ordersList/index'
},
{
icon: '../../images/index_icon/index_icon(7).png',
title: '酒店管理',
url: '../hotelList/index'
},
{
icon: '../../images/index_icon/index_icon(8).png',
title: '用户管理',
url: '../userList/index'
},
{
icon: '../../images/index_icon/index_icon(9).png',
title: '设备告警',
url: '../devicewarning/index',
index:0,
},
{
icon: '../../images/index_icon/index_icon(10).png',
title: '售后管理',
url: '../afterSale/index',
index:0,
}
]
},
})
\ No newline at end of file
{
"pages":[
"pages/login/index",
"pages/index/index",
"pages/accountStatement/index",
"pages/afterSale/index",
"pages/afterSaleList/index",
"pages/bindDevice/index",
"pages/bluetoothWarning/index",
"pages/bluetoothWarningDetail/index",
"pages/bluetoothWarningOrders/index",
"pages/center/index",
"pages/cardList/index",
"pages/cardDetail/index",
"pages/createCard/index",
"pages/createUser/index",
"pages/createHotel/index",
"pages/createGoods/index",
"pages/createRepair/index",
"pages/changePassword/index",
"pages/createGoodsPlan/index",
"pages/daySheet/index",
"pages/deployToolSec/index",
"pages/deviceList/index",
"pages/deviceDetail/index",
"pages/devicewarning/index",
"pages/deviceOrdersCount/index",
"pages/deviceSalesStatistics/index",
"pages/editPlan/index",
"pages/getWechat/index",
"pages/goodsList/index",
"pages/goodsPlan/index",
"pages/goodsDetail/index",
"pages/goodsPlanDetail/index",
"pages/goodsSalesStatistics/index",
"pages/hotelList/index",
"pages/hotelDetail/index",
"pages/hotelInventory/index",
"pages/hotelSalesStatistics/index",
"pages/hotelInventoryDetail/index",
"pages/handleMessage/index",
"pages/noStockDevice/index",
"pages/ordersList/index",
"pages/ordersSalesStatistics/index",
"pages/roomHelper/index",
"pages/register/index",
"pages/refundList/index",
"pages/replenishmentRecord/index",
"pages/resetDevice/index",
"pages/replenishmentDetail/index",
"pages/replenishment/index",
"pages/statistics/index",
"pages/storehouse/index",
"pages/separateDetail/index",
"pages/shortageList/index",
"pages/tool/plan",
"pages/trainInfo/index",
"pages/trainInfoDetail/index",
"pages/updateCard/index",
"pages/updateUser/index",
"pages/updateGoodsPlan/index",
"pages/updateGoodsDetail/index",
"pages/updateHotelDetail/index",
"pages/userList/index",
"pages/userDetail/index",
"pages/withdrawal/index",
"pages/withdrawalsRecord/index",
"pages/wallet/index",
"pages/warehouse/index",
"pages/wxBindList/index",
"pages/logs/logs"
],
"window":{
"backgroundTextStyle":"light",
"navigationBarBackgroundColor": "#fff",
"navigationBarTitleText": "达蒙智能平台",
"navigationBarTextStyle":"black"
},
"style": "v2",
"sitemapLocation": "sitemap.json",
"tabBar": {
"color": "#2E2421",
"selectedColor": "#387EE8",
"list": [
{
"pagePath": "pages/index/index",
"text": "首页",
"iconPath": "/images/bottom_icon/bottom_icon(1).png",
"selectedIconPath": "/images/bottom_icon/bottom_icon(5).png"
},
{
"pagePath": "pages/statistics/index",
"text": "统计",
"iconPath": "/images/bottom_icon/bottom_icon(2).png",
"selectedIconPath": "/images/bottom_icon/bottom_icon(6).png"
},
{
"pagePath": "pages/storehouse/index",
"text": "工具",
"iconPath": "/images/bottom_icon/bottom_icon(3).png",
"selectedIconPath": "/images/bottom_icon/bottom_icon(7).png"
},
{
"pagePath": "pages/center/index",
"text": "我的",
"iconPath": "/images/bottom_icon/bottom_icon(4).png",
"selectedIconPath": "/images/bottom_icon/bottom_icon(8).png"
}
]
}
}
/**基础样式**/
.cb {
clear: both !important;
float: none !important;
height: 0 !important;
}
.blue_color {
color: rgb(55, 126, 232) !important;
}
.red_color {
color: red !important;
}
.add_btn {
position: fixed;
bottom: 20vw;
right: 5vw;
width: 12vw;
height: 12vw;
background-size: 100% 100%;
}
/**顶部banner**/
#top_banner {
width: 100%;
background-color: #77adff;
background-image: linear-gradient(90deg, #77adff 0%, #387ee8 100%);
height: 52vw;
/* background-image: url('../images/top_banner/top_banner(1).png'); */
background-size: 100% 100%;
position: relative;
}
#top_banner .banner_img {
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
background-size: 100% 100%;
}
/**底部导航栏**/
#bottom_nav_box {
width: 100%;
height: 16vw;
position: fixed;
left: 0;
bottom: 0;
border-top: 1px solid #efefef;
background-color: #FFFFFF;
}
.bottom_nav_item {
width: 25%;
height: 100%;
float: left;
text-align: center;
font-size: 2.8vw;
color: rgb(164, 182, 210)
}
.bottom_nav_icon {
width: 7vw;
height: 7vw;
background-size: 100% 100%;
margin-top: 2vw
}
.bottom_nav_active {
color: rgb(55, 126, 232);
}
/**方块按钮样式**/
#block_item_box {
width: 100%;
margin-top: 5vw;
}
.block_item {
width: 44vw;
height: 22vw;
border-radius: 10px;
-moz-box-shadow: 2px 4px 5px 2px #f2f3f3;
-webkit-box-shadow: 2px 4px 5px 2px #f2f3f3;
box-shadow: 2px 4px 5px 2px #f2f3f3;
margin-left: 4vw;
margin-bottom: 4vw;
float: left;
}
.block_item_img {
width: 7vw;
height: 7vw;
background-size: 100% 100%;
float: left;
margin-left: 6vw;
margin-top: 7.5vw;
}
.block_item_title {
height: 7vw;
line-height: 7vw;
float: left;
font-size: 4.5vw;
margin-left: 4vw;
margin-top: 7.5vw;
font-weight: 500;
}
/**菜单样式**/
.tap_box {
width: 100%;
height: 12vw;
background-color: #FFFFFF;
}
.tap_item {
font-size: 4vw;
height: 10vw;
line-height: 7vw;
margin: 1vw 0;
text-align: center;
width: 50%;
float: left;
position: relative;
}
.tap_active {
color: rgb(55, 126, 232);
}
.tap_item view:nth-child(2) {
width: 100%;
height: 5px;
overflow: hidden;
}
.tap_active_line {
border-top: 2px solid rgb(55, 126, 232);
color: rgba(0, 0, 0, 0);
opacity: 0;
}
.tap_active .tap_active_line {
opacity: 1;
}
/**列表样式**/
.list_item {
width: 100%;
background-color: #FFFFFF;
height: 15vw;
line-height: 15vw;
}
.list_icon {
width: 5vw;
height: 5vw;
margin: 5vw 4vw;
float: left;
}
.list_title_box {
width: 87vw;
border-top: 1px solid rgb(245, 245, 245);
float: left;
position: relative;
}
.list_title {
font-size: 4vw;
float: left;
}
.list_item_icon {
position: absolute;
top: 0;
right: 0;
width: 4vw;
height: 4vw;
background-size: 100% 100%;
margin-right: 4vw;
margin-top: 5.5vw;
}
/**列表内容样式**/
.info_item {
width: 92vw;
padding: 0 4vw;
height: 12vw;
line-height: 12vw;
border-bottom: 1px solid rgb(248, 248, 248);
font-size: 3.8vw;
}
.info_item input {
height: 8vw;
padding: 2vw 0;
line-height: 8vw;
}
.info_title {
float: left;
width: 25vw;
}
.info_content {
float: left;
width: 67vw;
}
.info_plan {
float: left;
width: 47vw;
}
.info_price {
float: right;
width: 20vw;
}
.ball_item {
float: left !important;
margin: 0 0.5vw 0 0 !important;
width: 4vw !important;
height: 4vw !important;
line-height: 4vw !important;
text-align: center !important;
color: #FFFFFF !important;
background-color: rgb(55, 126, 232) !important;
border-radius: 50% !important;
font-size: 3.2vw !important;
margin-top: 4vw !important;
}
.top_line {
border-top: 3vw solid rgb(248, 248, 248);
}
.info_content_img {
background-size: 100% 100%;
width: 4vw;
height: 4vw;
margin-top: 4vw;
float: right;
}
.info_image_item {
height: auto;
padding-bottom: 2vw;
}
.img_content {
width: 100%;
}
.image_item {
position: relative;
width: 20vw;
height: 20vw;
float: left;
margin-right: 3vw;
margin-bottom: 2vw;
}
.image_item image {
width: 100%;
height: 100%;
background-size: 100% 100%;
}
/**搜索栏**/
#search_box {
width: 100%;
height: 14vw;
background-color: rgb(248, 248, 248);
position: relative;
}
#search_content_box {
width: 78vw;
height: 9vw;
background-color: #FFFFFF;
border-radius: 5vw;
position: absolute;
top: 2.5vw;
left: 3vw;
}
#search_content_box image {
float: left;
width: 5vw;
height: 5vw;
background-size: 100% 100%;
margin: 2vw 2vw 2vw 5vw;
}
#search_content_box input {
height: 7vw;
line-height: 7vw;
margin: 1vw 0;
font-size: 3.5vw;
}
#search_btn {
position: absolute;
font-size: 3.8vw;
right: 5vw;
height: 14vw;
line-height: 14vw;
top: 0;
}
.input_scan_icon {
width: 5vw;
height: 5vw;
position: absolute;
background-size: 100% 100%;
right: 0;
top: 0;
}
/**图文列表**/
.img_list_item {
width: 100%;
border-bottom: 1px solid rgb(248, 248, 248);
height: 30vw;
background-color: #FFFFFF;
}
.img_list_item image {
width: 22vw;
height: 22vw;
margin: 4vw;
background-size: 100% 100%;
float: left;
}
.item_text_box {
width: 70vw;
float: left;
margin-top: 4vw;
}
.item_text {
font-size: 3.5vw;
margin-bottom: 3.2vw;
}
/**表单样式**/
.input_box_item {
width: 94vw;
height: 12vw;
border-bottom: 1px solid rgb(248, 248, 248);
padding: 0 3vw;
}
.required_tips {
color: red;
font-size: 3.5vw;
float: left;
height: 12vw;
line-height: 11vw;
margin-right: 1vw;
}
.input_title {
float: left;
width: 25vw;
font-size: 3.8vw;
height: 12vw;
line-height: 12vw;
}
.input_box_item input {
float: left;
height: 10vw;
margin-top: 1vw;
line-height: 10vw;
font-size: 3.8vw;
}
.main_btn,
.sec_btn {
width: 90vw;
margin: 3vw auto 0 auto;
height: 12vw;
line-height: 12vw;
text-align: center;
background-color: rgb(55, 126, 232);
color: #FFFFFF;
font-size: 4.5vw;
border-radius: 10px;
border: 1px solid rgb(55, 126, 232);
}
.sec_btn {
background-color: #FFFFFF;
color: rgb(55, 126, 232);
}
.thi_btn {
background-color: rgb(252, 135, 56) !important;
border-color: rgb(252, 135, 56) !important;
}
.four_btn {
background-color: rgb(94, 201, 72) !important;
border-color: rgb(94, 201, 72) !important;
}
.tips_btn {
width: 100%;
height: 10vw;
line-height: 10vw;
color: rgb(153, 174, 204);
font-size: 4vw;
text-align: center;
}
.radian_btn,
.radian_main_btn {
width: 90vw;
height: 12vw;
line-height: 12vw;
border-radius: 6vw;
text-align: center;
color: rgb(55, 126, 232);
font-size: 4.5vw;
background-color: #FFFFFF;
margin: 0 auto;
font-weight: block;
}
.radian_main_btn {
background-color: rgb(55, 126, 232);
color: #FFFFFF;
margin: 2vw auto 5vw auto;
}
/**搜索表单样式**/
.serach_form_btn_box {
width: 50vw;
margin: 5vw auto;
height: 8vw;
line-height: 8vw;
}
.serach_form_btn {
width: 20vw;
height: 100%;
border: 1px solid rgb(55, 126, 232);
border-radius: 5px;
color: rgb(55, 126, 232);
text-align: center;
font-size: 4vw;
float: right;
}
.serach_form_btn_box .active {
background-color: rgb(55, 126, 232) !important;
color: #FFFFFF;
float: left;
}
button {
padding: 0 !important;
}
/**消息样式**/
.message_box {
width: 100%;
background-color: #FFFFFF;
height: 48vw;
border-bottom: 2vw solid #EEEEEE;
}
.message_top {
width: 100%;
height: 12vw;
line-height: 12vw;
font-size: 3.5vw;
}
.message_top view:nth-child(1) {
float: left;
color: #999999;
margin-left: 5vw;
}
.message_top view:nth-child(2) {
float: right;
color: #999999;
margin-right: 5vw;
}
.message_title{
margin-top: 2vw;
}
.message_title view{
line-height: 5vw;
float: none;
}
.message_title view:nth-child(1){
color: #000000;
margin-left: 0;
float: none !important;
}
.message_title view:nth-child(2){
font-size: 3vw;
margin-left: 0;
float: none !important;
}
.message_content {
width: 100%;
height: 24vw;
background-color: #F9F7F7;
font-size: 3.2vw;
color: #666666;
}
.message_content image {
width: 10vw;
height: 10vw;
border-radius: 50%;
background-color: #FFFFFF;
background-size: 100% 100%;
float: left;
margin: 5vw 3vw;
}
.message_content_text {
float: left;
height: 12vw;
line-height: 4vw;
margin: 4vw 0;
}
.message_content_right {
font-size: 3.8vw;
color: #387ee8;
font-weight: bold;
padding-right: 5vw;
float: right;
margin-top: 4vw;
}
.message_bottom {
width: 100%;
}
.message_btn {
width: 18vw;
height: 6vw;
line-height: 6vw;
float: right;
border-radius: 5px;
border: 1px solid #387ee8;
background-color: #FFFFFF;
text-align: center;
margin: 3vw 5vw 3vw 0;
color: #387ee8;
font-size: 3.5vw;
}
.radio {
margin-left: 5vw;
}
.wechatBtn {
width: 90vw;
height: 12vw;
line-height: 12vw;
background-color: #07C160;
color: #ffffff;
font-size: 4.5vw;
border-radius: 10px;
margin: 10px auto 0;
text-align: center;
}
.tab_box {
width: 100%;
height: 8vw;
line-height: 8vw;
}
.tab_item {
width: calc(100% / 4 - 6%);
margin: 0 3%;
float: left;
text-align: center;
color: #bbbbbb;
font-size: 3.5vw;
border-bottom: 3px solid #FFFFFF;
}
.tab_item_active {
border-bottom: 3px solid #387ee8 !important;
color: #000000;
}
.tab_swiper {
width: 100%;
height: calc(100vh - 9vw);
position: fixed;
left: 0;
bottom: 0;
}
.hotel_item {
width: 92vw;
padding: 6vw 4vw;
border-bottom: 1px solid rgb(248, 248, 248);
color: #999999;
font-size: 3.5vw;
}
.hotel_item image {
width: 6vw;
height: 6vw;
background-size: 100% 100%;
float: right;
}
.hotel_name {
font-size: 4vw;
font-weight: bold;
float: left;
color: #000000;
}
.hotel_content_item {
margin-top: 2vw;
}
.hotel_content_item view:nth-child(1) {
float: left;
}
.hotel_content_item view:nth-child(2) {
float: right;
}
.ball_item {
margin-top: 0.5vw !important;
}
.hotel_box {
border-bottom: 1px solid #EEEEEE;
width: 100%;
}
.hotel_name_item {
width: 95%;
height: 12vw;
line-height: 12vw;
font-size: 3.5vw;
padding: 0 2.5%;
}
.hotel_name_item image:nth-child(1) {
float: left;
width: 4vw;
height: 4vw;
margin: 4vw;
}
.hotel_name_arrow {
float: right;
width: 6vw;
height: 6vw;
margin: 4vw 3vw 0 3vw;
background-size: 100% 100%;
}
.hotel_name_text {
float: left;
width: 60vw;
}
radio .wx-radio-input{
width: 4vw;
height: 4vw;
line-height: 4vw;
text-align: center;
}
radio .wx-radio-input.wx-radio-input-checked{
border-color:#387ee8 !important;
background:#387ee8 !important;
}
radio .wx-radio-input.wx-radio-input-checked::before{
width: 4vw;
height: 4vw;
line-height: 4vw;
text-align: center;
}
\ No newline at end of file
const app = getApp();
Page({
data: {
userInfo: wx.getStorageSync('userInfo'),
index1: "tap_active",
index2: "",
transRecordList:[],
separateList:[],
start_time:"请选择开始时间",
end_time: "请选择结束时间",
},
onShow: function () {
var PageThis = this;
PageThis.setData({
userInfo:wx.getStorageSync('userInfo')
})
this.getAll();
},
getAll:function(){
this.getTransRecordList();
this.getSeparateList();
},
getTransRecordList:function(){
var PageThis = this;
wx.request({
url: app.globalData.serverInfo.gateWayUrl,
header: {
'content-type': 'application/json'
},
method: 'POST',
data: {
api_name: "get_trans_record_list",
start_time: PageThis.data.start_time == "请选择开始时间" ? "" : PageThis.data.start_time,
end_time: PageThis.data.end_time == "请选择结束时间" ? "" : PageThis.data.end_time,
login_manager_id: PageThis.data.userInfo.manager_id
},
success:function(res){
var data = res.data.data;
PageThis.setData({
transRecordList: data
})
}
})
},
getSeparateList:function(){
var PageThis = this;
wx.request({
url: app.globalData.serverInfo.gateWayUrl,
header: {
'content-type': 'application/json'
},
method: 'POST',
data: {
api_name: "get_separate_list",
start_time: PageThis.data.start_time == "请选择开始时间" ? "" : PageThis.data.start_time,
end_time: PageThis.data.end_time == "请选择结束时间" ? "" : PageThis.data.end_time,
login_manager_id: PageThis.data.userInfo.manager_id
},
success: function (res) {
var data = res.data.data;
PageThis.setData({
separateList: data
})
}
})
},
switchTap:function(e){
var PageThis = this;
var index = e.currentTarget.dataset.index;
if(index == 1){
PageThis.setData({
index1: "tap_active",
index2: "",
})
}else if(index == 2){
PageThis.setData({
index1: "",
index2: "tap_active",
})
}
},
pickerChange: function (e) {
var PageThis = this;
var val = e.detail.value;
var name = e.target.dataset.name;
switch (name) {
case "start_time":
PageThis.setData({
start_time: val
})
break;
case "end_time":
PageThis.setData({
end_time: val
})
break;
}
}
})
\ No newline at end of file
{
"navigationBarTitleText": "个人中心",
"usingComponents": {}
}
\ No newline at end of file
<view class="tap_box">
<view class="tap_item {{index1}}" bindtap="switchTap" data-index="1">
<view><span>对账单</span></view>
<view><span class="tap_active_line">###1</span></view>
</view>
<view class="tap_item {{index2}}" bindtap="switchTap" data-index="2">
<view><span>分账记录</span></view>
<view><span class="tap_active_line">#####1</span></view>
</view>
</view>
<view class="date_picker">
<picker mode="date" fields="day" data-name="start_time" bindchange="pickerChange">
<span>{{start_time}}</span>
</picker>
<view class="link_icon">~</view>
<picker mode="date" fields="day" data-name="end_time" bindchange="pickerChange">
<span>{{end_time}}</span>
</picker>
<view class="serach_btn" bindtap="getAll">搜索</view>
<view class="cb"></view>
</view>
<view class="data_box">
<view class="data_item">
<view>{{userInfo.manager_total_money}}</view>
<view>总收益(元)</view>
</view>
<view class="data_item">
<view>{{userInfo.manager_money}}</view>
<view>余额(元)</view>
</view>
</view>
<view id="record_list" wx:if="{{index1 == 'tap_active'}}">
<view class="record_item" wx:for="{{transRecordList}}" wx:key="k">
<view class="record_state">
<view wx:if="{{item.record_type == 1}}">收益</view>
<view wx:if="{{item.record_type == 2}}">提现</view>
<view>{{item.record_time}}</view>
</view>
<view class="record_money color_blue" wx:if="{{item.record_type == 1}}">{{item.record_money}}</view>
<view class="record_money" wx:if="{{item.record_type == 1}}">-{{item.record_money}}0</view>
</view>
</view>
<view class="statistics_list_box" wx:if="{{index2 == 'tap_active'}}">
<view class="statistics_list_title">
<view>分成时间</view>
<view>分成金额</view>
</view>
<view class="statistics_list_item" wx:for="{{separateList}}" wx:key="k">
<view>{{item.pay_create}}</view>
<view>{{item.sep_money}}</view>
</view>
</view>
\ No newline at end of file
#record_list{
width: 100%;
border-top: 3vw solid rgb(248,248,248);
}
.record_item{
width: 100%;
height: 20vw;
border-bottom: 1px solid rgb(248,248,248);
}
.record_state{
height: 13vw;
margin: 3.5vw;
float: left;
}
.record_state view:nth-child(1){
font-size: 4.2vw;
color: rgb(49,66,92);
}
.record_state view:nth-child(2){
color: rgb(156,156,156);
font-size: 3.5vw;
margin-top: 2vw;
}
.record_money{
height: 20vw;
line-height: 20vw;
font-size: 4vw;
float: right;
margin-right: 5vw;
color: red;
}
.color_blue{
color:rgb(55,126,232) !important;
}
.date_picker{
width: 88vw;
margin: 4vw 6vw;
}
.date_picker .serach_btn{
float: left;
background-color: rgb(55,126,232);
color: #FFFFFF;
text-align: center;
font-size: 3.8vw;
height: 8vw;
line-height: 8vw;
width: 14vw;
margin-left: 4vw;
border-radius: 5px;
}
.data_box{
width: calc(90vw + 1px);
height: 30vw;
border-radius: 15px;
background-image: linear-gradient(90deg, #77adff 0%, #387ee8 100%);
color: #FFFFFF;
margin: 8vw auto;
}
.data_item{
width: 45vw;
text-align: center;
float: left;
margin-top: 8vw;
}
.data_item:nth-child(1){
border-right: 1px solid rgb(106,160,245)
}
.data_item view:nth-child(1){
font-size: 6vw;
height: 8vw;
line-height: 8vw;
}
.data_item view:nth-child(2){
font-size: 3.2vw;
height: 6vw;
line-height: 6vw;
}
.statistics_list_box{
width: 93vw;
margin: 0 auto;
border-top: 3vw solid rgb(248,248,248);
padding: 0 3.5vw;
}
.statistics_list_title,.statistics_list_item{
width: 90vw;
height: 12vw;
line-height: 12vw;
padding: 0 1.5vw;
border-bottom: 1px solid rgb(248,248,248);
font-size: 3.8vw;
}
.statistics_list_title view,.statistics_list_item view{
width: 60vw;
color: rgb(150,150,150);
height: 100%;
float: left;
}
.statistics_list_title view:nth-child(2){
width: 30vw;
text-align: center;
}
.statistics_list_item view{
color: #000000;
}
.statistics_list_item view:nth-child(2){
width: 30vw;
text-align: center;
color: rgb(106,160,245);
}
picker{
float: left;
width: 28vw;
height: 8vw;
background-color: rgb(248,248,248);
color: #999999;
border-radius: 5px;
margin-left: 0;
line-height: 8vw;
padding-left: 2vw;
font-size: 3.5vw;
}
.link_icon{
height: 8vw;
line-height: 8vw;
float: left;
padding: 0 2vw;
}
\ No newline at end of file
// pages/afterSale/index.js
const app = getApp();
Page({
/**
* 页面的初始数据
*/
data: {
listData: [
{
icon: '../../images/icons/icon(24).png',
title: '添加售后设备',
url: '../createRepair/index'
},
{
icon: '../../images/icons/icon(59).png',
title: '售后设备列表',
url: '../afterSaleList/index'
}
]
},
//**页面跳转 */
navigateTo: function (e) {
var _url = e.currentTarget.dataset.url;
wx.navigateTo({
url: _url
})
}
})
\ No newline at end of file
{
"usingComponents": {}
}
\ No newline at end of file
<view id="top_banner">
<image class="banner_img" src="../../images/top_banner/top_banner(3).png"></image>
</view>
<view id="block_item_box">
<view class="block_item" wx:for="{{listData}}" wx:key="k" bindtap="navigateTo" data-url="{{item.url}}">
<image class="block_item_img" src="{{item.icon}}"></image>
<view class="block_item_title">{{item.title}}</view>
</view>
</view>
\ No newline at end of file
/* pages/afterSale/index.wxss */
.block_item_img{
margin-left: 4vw !important;
}
.block_item_title{
margin-left: 3vw !important;
}
\ No newline at end of file
const app = getApp();
Page({
data: {
userInfo:{},
list:[]
},
onLoad: function (options) {
var PageThis = this;
PageThis.setData({
userInfo:wx.getStorageSync('userInfo')
})
},
onShow: function () {
this.getDeviceRepair();
},
getDeviceRepair(){
var PageThis = this;
wx.request({
url: app.globalData.serverInfo.gateWayUrl,
header: {
'content-type': 'application/json'
},
method: 'POST',
data: {
api_name: "get_device_repair",
login_manager_id: PageThis.data.userInfo.manager_id
},
success:function(res){
var ret = res.data;
if(Number(ret.state) === 1){
var list = ret.data;
for(var i in list){
list[i].repair_content = JSON.parse(list[i].repair_content);
var str = "待维修"
switch(list[i].repair_state){
case 1:
str = "待维修";
break;
case 2:
str = "维修中";
break;
case 3:
str = "已维修";
break;
case 4:
str = "已完成";
break;
}
list[i].repair_state_name = str;
if(Number(list[i].repair_delivery_type) == 1){
list[i].repair_delivery_type_name = "自取";
}else if(Number(list[i].repair_delivery_type) == 2){
list[i].repair_delivery_type_name = "快递";
}
}
PageThis.setData({
list:list
})
}
}
})
}
})
\ No newline at end of file
{
"usingComponents": {}
}
\ No newline at end of file
<view class="input_box_item">
<view class="input_title">设备号</view>
<input placeholder="请输入设备号" data-name="dev_no" value="{{dev_no}}"></input>
</view>
<view class="input_box_item">
<view class="input_title">状态</view>
<input placeholder="请选择售后状态" data-name="state" value="{{state}}"></input>
</view>
<view class="serach_form_btn_box">
<view class="serach_form_btn active" bindtap="getOrdersList">搜索</view>
<view class="serach_form_btn" bindtap="reset">重置</view>
</view>
<view class="message_list">
<view class="message_box" wx:for="{{list}}" wx:key="k">
<view class="message_top">
<view>{{item.repair_dev_no}}</view>
<view style="color:red">{{item.repair_state_name}}</view>
<view class="cb"></view>
</view>
<view class="message_content">
<image src="../../images/icons/warning.png"></image>
<view class="message_content_text">
<view>寄送方式:{{item.repair_delivery_type_name}}</view>
<view>维修描述:{{item.repair_content.reason}}</view>
</view>
<view class="cb"></view>
</view>
</view>
</view>
<!-- <view class="page_box">
<view class="total_page">(总计:<span>19</span>条)</view>
<view class="page_select">
<view class="page_up page_disable">上一页</view>
<view class="now_page">1/3</view>
<view class="page_down">下一页</view>
<view class="cb"></view>
</view>
</view> -->
\ No newline at end of file
picker{
float: left;
width: 31vw;
height: 8vw;
background-color: rgb(248,248,248);
color: gray;
border-radius: 5px;
margin-top: 2vw !important;
margin-left: 0;
line-height: 8vw;
padding-left: 2vw;
font-size: 3.5vw;
}
input{
background-color: rgb(248,248,248);
padding-left: 2vw;
width: 69.5vw;
height: 8vw !important;
line-height: 8vw !important;
border-radius: 5px;
margin-top: 1vw !important;
}
.input_box_item{
width: 100%;
border-bottom: none;
height: 10vw;
line-height: 10vw;
overflow-x: hidden;
}
.input_title{
width: 20vw;
margin-left: 2vw;
height: 100%;
line-height: 10vw;
}
.link_icon{
height: 10vw;
line-height: 10vw;
float: left;
padding: 0 2vw;
}
.list_box{
width: 100%;
overflow-x: hidden;
}
.message_list{
width: 100%;
border-top: 1px solid #EEEEEE;
overflow-y: scroll;
position: fixed;
top: 38vw;
left: 0;
height: calc(100vh - 38vw);
/* height: calc(100vh - 55vw); */
}
.message_box {
height:35vw !important;
}
.message_content{
height: 18vw !important;
}
.message_content image{
width: 6vw !important;
height: 6vw !important;
margin: 5vw 5vw !important;
}
.page_box{
position: fixed;
left: 0;
bottom: 0;
width: 100%;
background-color: #FFFFFF;
}
.total_page{
width: 100%;
height: 5vw;
line-height: 5vw;
text-align: center;
font-size: 3.2vw;
border-top: 1px solid #ededed;
border-bottom: 1px solid #ededed;
color: #666666;
background-color: #FFFFFF;
}
.total_page span{
color: #387ee8;
}
.page_select{
width: 100%;
height: 12vw;
line-height: 12vw;
text-align: center;
font-size: 3.5vw;
background-color: #FFFFFF;
}
.page_select view{
width: calc(100% / 3);
float: left;
}
.now_page{
font-weight: bold;
outline: 1px solid #ededed;
}
.page_up,.page_down{
color: #387ee8;
}
.page_disable{
background-color: #F7F7F7 !important;
color: #CCCCCC !important;
}
\ No newline at end of file
// pages/bindDevice/index.js
const app = getApp();
Page({
data: {
userInfo: wx.getStorageSync('userInfo'),
hotelId: 0,
deviceList: [],
deviceListValue:[],
hotelInfo: {},
bindList: [],
managerList: [],
managerValue: [],
managerName: "请选择管理员",
managerId: 0
},
onLoad: function (options) {
var id = options.id;
var PageThis = this;
PageThis.setData({
userInfo:wx.getStorageSync('userInfo')
})
this.setData({
hotelId:id
})
this.getHotelInfo();
this.getManagerList();
this.getDeviceList();
},
getHotelInfo:function(){
var PageThis = this;
wx.request({
url: app.globalData.serverInfo.gateWayUrl,
header: {
'content-type': 'application/json'
},
method: 'POST',
data: {
api_name: "hotel_detail",
hotel_id: PageThis.data.hotelId,
login_manager_id: PageThis.data.userInfo.manager_id
},
success:function(res){
var data = res.data.data;
PageThis.setData({
hotelInfo: data
})
}
})
},
getDeviceList:function(){
var PageThis = this;
wx.request({
url: app.globalData.serverInfo.gateWayUrl,
header: {
'content-type': 'application/json'
},
method: 'POST',
data: {
api_name: "device_list",
bind_value: 2,
login_manager_id: PageThis.data.userInfo.manager_id
},
success: function (res) {
var data = res.data.data;
var deviceList = [];
for (var i in data){
deviceList.push(data[i].dev_no)
}
PageThis.setData({
deviceList: deviceList,
deviceListValue: data
})
}
})
},
addDevice:function(){
var PageThis = this;
var bindList = PageThis.data.bindList;
bindList.push({
index:bindList.length,
deviceId:0,
devNo:"请选择绑定设备",
dev_hotel_room:"",
dev_room_address: "",
});
PageThis.setData({
bindList: bindList
})
},
delDevice:function(e){
var PageThis = this;
var index = e.currentTarget.dataset.index;
var bindList = PageThis.data.bindList;
var newList = [];
for (var i in bindList){
if (bindList[i].index != index){
bindList[i].index = newList.length;
newList.push(bindList[i]);
}
}
PageThis.setData({
bindList: newList
})
},
scanAdd:function(){
var PageThis = this;
var bindList = PageThis.data.bindList;
wx.scanCode({
scanType:['qrCode'],
success (res) {
console.log(res)
var scan_url = res.result;
var code = scan_url.replace(app.globalData.serverInfo.qrReplaceUrl,'');
if(code != ""){
wx.showModal({
title: '绑定设备',
content: '确定绑定设备编号为:'+code+"的设备?",
success (res) {
if (res.confirm) {
bindList.push({
index:bindList.length,
deviceId:0,
devNo:code,
dev_hotel_room:"",
dev_room_address: "",
});
PageThis.setData({
bindList: bindList
})
} else if (res.cancel) {
console.log('用户点击取消')
}
}
})
}
}
})
},
sureBind:function(){
var PageThis = this;
var bindList = PageThis.data.bindList;
var ids = [];
for (var i in bindList){
ids.push(bindList[i].deviceId);
}
wx.request({
url: app.globalData.serverInfo.gateWayUrl,
header: {
'content-type': 'application/json'
},
method: 'POST',
data: {
api_name: "bind_device_hotel",
login_manager_id: PageThis.data.userInfo.manager_id,
dev_list:PageThis.data.bindList,
hotel_id:PageThis.data.hotelId,
hotel_manager_id: PageThis.data.managerId
},
success:function(res){
res = res.data;
if(res.state == 1){
wx.showToast({
title: "绑定成功",
icon: "success",
duration: 2000
})
setTimeout(function(){
wx.navigateBack();
},2000)
}else{
wx.showToast({
title: res.msg,
icon:"none",
duration:1500
})
}
}
})
},
getManagerList: function () {
var PageThis = this;
wx.request({
url: app.globalData.serverInfo.gateWayUrl,
header: {
'content-type': 'application/json'
},
method: 'POST',
data: {
api_name: "manager_list",
login_manager_id: PageThis.data.userInfo.manager_id
},
success: function (res) {
var data = res.data.data;
var managerList = [];
var managerValue = [];
for (var i in data) {
if (data[i].manager_type == 6){
managerList.push(data[i]['manager_username']);
managerValue.push(data[i])
}
}
PageThis.setData({
"managerList": managerList,
"managerValue": managerValue
})
}
})
},
pickerChange:function(e){
var PageThis = this;
var index = e.currentTarget.dataset.index;
var name = e.currentTarget.dataset.name;
var id = e.detail.value;
if (name == "devNo"){
var deviceList = PageThis.data.deviceList;
var deviceListValue = PageThis.data.deviceListValue;
var bindList = PageThis.data.bindList;
bindList[index]['deviceId'] = deviceListValue[id]['dev_id'];
bindList[index]['devNo'] = deviceListValue[id]['dev_no'];
PageThis.setData({
"bindList": bindList
})
}else{
var managerList = PageThis.data.managerList;
var managerValue = PageThis.data.managerValue;
PageThis.setData({
"managerId": managerValue[id]['manager_id'],
"managerName": managerList[id]
})
}
},
inputChange:function(e){
var PageThis = this;
var index = e.currentTarget.dataset.index;
var name = e.currentTarget.dataset.name;
var bindList = PageThis.data.bindList;
bindList[index][name] = e.detail.value;
PageThis.setData({
"bindList": bindList
})
}
})
\ No newline at end of file
{
"usingComponents": {}
}
\ No newline at end of file
<view class="info_item">
<view class="info_title"><span class="red_color">*</span>酒店</view>
<view class="info_content">{{hotelInfo.h_title}}</view>
</view>
<view class="device_item" wx:for="{{bindList}}" wx:key="k">
<view class="info_item top_line">
<view class="info_title">设备号</view>
<view class="info_content">
<picker range="{{deviceList}}" data-name="devNo" data-index="{{item.index}}" bindchange="pickerChange">
<span>{{item.devNo}}</span>
<!-- <image class="info_content_img" src="../../images/icons/icon(52).png"></image> -->
</picker>
</view>
</view>
<view class="info_item">
<view class="info_title">房间号</view>
<input placeholder="请输入房间号" bindinput="inputChange" data-index="{{item.index}}" data-name="dev_hotel_room" value="{{item.dev_hotel_room}}"></input>
</view>
<view class="info_item">
<view class="info_title">房间位置</view>
<input placeholder="请输入房间位置" bindinput="inputChange" data-index="{{item.index}}" data-name="dev_room_address" value="{{item.dev_room_address}}"></input>
<view class="del_btn" bindtap="delDevice" data-index="{{item.index}}">删除</view>
</view>
</view>
<view class="main_btn" bindtap="addDevice">增加设备</view>
<view class="main_btn" bindtap="scanAdd">扫码添加</view>
<view class="main_btn" bindtap="sureBind">完成绑定</view>
\ No newline at end of file
.del_btn{
width: 12vw;
text-align: center;
height: 6vw;
line-height: 6vw;
font-size: 3.5vw;
color: #FFFFFF;
border-radius: 5px;
background-color: red;
margin-top: 3.5vw;
float: right;
}
.info_item input{
width: 50vw !important;
float: left;
}
\ No newline at end of file
const app = getApp();
Page({
data: {
userInfo:{},
dev_no:"",
start_time:"请选择开始时间",
end_time:"请选择结束时间",
list:{}
},
onLoad: function (options) {
this.setData({
userInfo:wx.getStorageSync('userInfo')
})
this.getList();
},
getList(){
var PageThis = this;
wx.request({
url: app.globalData.serverInfo.gateWayUrl,
header: {
'content-type': 'application/json'
},
method: 'POST',
data: {
api_name: "get_fail_scan_device_list",
dev_no: PageThis.data.dev_no,
start_time: PageThis.data.start_time == "请选择开始时间" ? "" : PageThis.data.start_time,
end_time: PageThis.data.end_time == "请选择结束时间" ? "" : PageThis.data.end_time,
login_manager_id: PageThis.data.userInfo.manager_id
},
success(res){
var ret = res.data;
if(Number(ret.state) === 1){
PageThis.setData({
list:ret.data
})
}
}
})
},
//**页面跳转 */
navigateTo: function (e) {
var _url = e.currentTarget.dataset.url;
var _id = e.currentTarget.dataset.id;
wx.navigateTo({
url: _url + "?id=" + _id,
})
},
inputChange:function(e){
var PageThis = this;
PageThis.setData({
"pay_no": e.detail.value
})
}, pickerChange:function(e){
var PageThis = this;
var name = e.currentTarget.dataset.name;
var val = e.detail.value;
switch(name){
case "start_time":
PageThis.setData({
start_time: val
})
break;
case "end_time":
PageThis.setData({
end_time: val
})
break;
}
},
reset:function(){
var PageThis = this;
PageThis.setData({
dev_no: "",
start_time: "请选择开始时间",
end_time: "请选择结束时间",
})
}
})
\ No newline at end of file
{
"usingComponents": {}
}
\ No newline at end of file
<view class="input_box_item">
<view class="input_title">设备号</view>
<input placeholder="请输入搜索的设备号" data-name="dev_no" value="{{dev_no}}"></input>
</view>
<view class="input_box_item">
<view class="input_title">时间区间</view>
<picker mode="date" fields="day" data-name="start_time" bindchange="pickerChange">
<span>{{start_time}}</span>
</picker>
<view class="link_icon">~</view>
<picker mode="date" fields="day" data-name="end_time" bindchange="pickerChange">
<span>{{end_time}}</span>
</picker>
</view>
<view class="serach_form_btn_box">
<view class="serach_form_btn active" bindtap="getOrdersList">搜索</view>
<view class="serach_form_btn" bindtap="reset">重置</view>
</view>
<view class="b_list" wx:for="{{list}}" wx:key="k">
<view class="b_list_left">
<view>{{item.dev_no}}</view>
<view>酒店名称:{{item.hotel_title}}</view>
<view>设备拥有人:{{item.partner_nickname}}</view>
</view>
<view class="b_list_right">
<view bindtap="navigateTo" data-url="../bluetoothWarningDetail/index" data-id="{{item.dev_id}}">查看明细</view>
<view bindtap="navigateTo" data-url="../bluetoothWarningOrders/index" data-id="{{item.dev_id}}">订单明细</view>
</view>
<view class="b_list_center">
<view>{{item.dev_create}}</view>
<view>{{item.dev_hotel_room}}</view>
</view>
<view class="cb"></view>
</view>
\ No newline at end of file
input{
background-color: rgb(248,248,248);
padding-left: 2vw;
width: 69.5vw;
height: 8vw !important;
line-height: 8vw !important;
border-radius: 5px;
margin-top: 1vw !important;
}
.input_box_item{
width: 100%;
border-bottom: none;
height: 10vw;
line-height: 10vw;
overflow-x: hidden;
}
.input_title{
width: 20vw;
margin-left: 2vw;
height: 100%;
line-height: 10vw;
}
.link_icon{
height: 10vw;
line-height: 10vw;
float: left;
padding: 0 2vw;
}
picker{
float: left;
width: 31vw;
height: 8vw;
background-color: rgb(248,248,248);
color: gray;
border-radius: 5px;
margin-top: 2vw !important;
margin-left: 0;
line-height: 8vw;
padding-left: 2vw;
font-size: 3.5vw;
}
.b_list{
width: 90%;
border-top: 1px solid #eeeeee;
margin: 0 5%;
font-size: 3.3vw;
height: 6vw;
line-height: 6vw;
color: #666666;
padding-top: 5vw;
height: 20vw;
}
.b_list_left{
float: left;
width: 38%;
}
.b_list_left view:nth-child(1){
font-weight: bold;
}
.b_list_center{
float: right;
text-align: right;
width: 38%;
}
.b_list_right{
float: right;
width: 24%;
}
.b_list_right view{
width: 80%;
margin: 10%;
color: #FFFFFF;
height: 7vw;
line-height: 7vw;
margin-top: -0.5vw;
border-radius: 3px;
text-align: center;
background-color: #387ee8;
margin-bottom: 3vw;
}
.b_list_right view:nth-child(2){
background-color: #2C96A3;
}
\ No newline at end of file
const app = getApp();
Page({
data: {
tabIndex:0,
tabList:[],
tab_swiper_index:0,
list:[]
},
onLoad: function (options) {
var id = options.id;
var item = ["失败记录","成功记录"];
var list = [];
for(var i in item){
var obj = {
"tabName":item[i],
"tabClass":"",
"tabIndex":i,
"tabContent":[]
}
list.push(obj);
}
list[0]['tabClass'] = "tab_item_active";
this.setData({
userInfo:wx.getStorageSync('userInfo'),
tabList:list
})
this.getData(id);
},
onTabItem(e){
var PageThis = this;
var index = e.currentTarget.dataset.page;
var tabList = PageThis.data.tabList;
for(var i in tabList){
if(Number(tabList[i].tabIndex) === Number(index)){
tabList[i].tabClass = "tab_item_active";
}else{
tabList[i].tabClass = "";
}
}
PageThis.setData({
tabIndex:index,
tabList:tabList
})
},
tabSwiperChange(e){
var PageThis = this;
var index = e.detail.current;
var tabList = PageThis.data.tabList;
for(var i in tabList){
if(Number(tabList[i].tabIndex) === Number(index)){
tabList[i].tabClass = "tab_item_active";
}else{
tabList[i].tabClass = "";
}
}
PageThis.setData({
tab_swiper_index:index,
tabList:tabList
})
},
fakeData(){
var PageThis = this;
var data = [];
var title = {
"brand":"手机品牌",
"model":"手机型号",
"system":"操作系统",
"edition":"软件版本",
"type":"手机类型",
"state":"连接状态",
"ip":"IP地址",
"time":"连接时间"
}
data.push(title);
for(var i=0;i<50;i++){
var obj = {
"brand":"apple",
"model":"iphone11",
"system":"14.0.2",
"edition":"7.0.16",
"type":"ios",
"state":"wx-蓝牙连接失败",
"ip":"42.90.71.108",
"time":"2020-07-20 02:45:07"
}
data.push(obj);
}
PageThis.setData({
list:data
})
},
getData(id){
var PageThis = this;
wx.request({
url: app.globalData.serverInfo.gateWayUrl,
header: {
'content-type': 'application/json'
},
method: 'POST',
data: {
api_name: "get_one_device_scan_list",
dev_id: id,
login_manager_id: PageThis.data.userInfo.manager_id,
},
success:function(res){
var ret = res.data;
var data = [];
var title = {
"scan_mobile_brand":"手机品牌",
"scan_mobile_model":"手机型号",
"scan_mobile_os":"操作系统",
"scan_mobile_version":"软件版本",
"scan_mobile_type":"手机类型",
"scan_result":"连接状态",
"scan_ip":"IP地址",
"scan_time":"连接时间",
"scan_result":99
}
data.push(title);
for(var i in ret.data){
data.push(ret.data[i]);
}
PageThis.setData({
"list":data
})
}
})
}
})
\ No newline at end of file
{
"usingComponents": {}
}
\ No newline at end of file
<view class="tab_box">
<view wx:for="{{tabList}}" wx:key="k" class="tab_item {{item.tabClass}}" bindtap="onTabItem" data-page="{{item.tabIndex}}">{{item.tabName}}</view>
</view>
<view id="device_code">设备号:{{list[1].dev_no}}</view>
<view class="tabel_box">
<view class="table_title_box">
<view class="tabel_item" wx:for="{{list}}" wx:key="k" wx:if="{{item.scan_result == tabIndex || item.scan_result == 99}}">
<view>{{item.scan_mobile_brand}}</view>
</view>
</view>
<view class="table_content_box">
<view class="tabel_item" wx:for="{{list}}" wx:key="k" wx:if="{{item.scan_result == tabIndex || item.scan_result == 99}}">
<view>{{item.scan_mobile_model}}</view>
<view>{{item.scan_mobile_os}}</view>
<view>{{item.scan_mobile_version}}</view>
<view>{{item.scan_mobile_type}}</view>
<view>{{item.scan_result}}</view>
<view>{{item.scan_ip}}</view>
<view>{{item.scan_time}}</view>
<view class="cb"></view>
</view>
</view>
</view>
.tab_item{
width: calc(100% / 2 - 30%);
margin: 0 15%;
}
.tab_swiper_item{
width: 100%;
overflow-y: scroll;
overflow-x: scroll;
}
#device_code{
width: 95%;
padding-left: 5%;
height: 10vw;
line-height: 10vw;
font-size: 3.5vw;
font-weight: bold;
}
.tabel_box{
width: 100%;
height: calc(100vh - 18vw);
position: fixed;
bottom: 0;
left: 0;
overflow-y: scroll;
}
.table_title_box{
width: 30vw;
box-shadow:2px 0px 3px 1px #D1D1D1;
position: absolute;
z-index: 10;
}
.table_title_box .tabel_item{
height: 10vw;
line-height: 10vw;
width: 30vw;
font-size: 3.5vw;
font-weight: bold;
text-align: center;
}
.table_title_box .tabel_item:nth-child(2n),.table_content_box .tabel_item:nth-child(2n){
background-color: #EEECEF;
}
.table_content_box{
width: 70vw;
overflow-x: scroll;
position: absolute;
left: 30vw;
}
.table_content_box .tabel_item{
width: calc(40vw * 8);
height: 10vw;
line-height: 10vw;
font-size: 3.5vw;
font-weight: bold;
}
.table_content_box .tabel_item view{
width: 40vw;
text-align: center;
float: left;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.table_content_box .tabel_item view:nth-child(7){
width: 60vw;
}
\ No newline at end of file
// pages/bluetoothWarningOrders/index.js
const app = getApp();
Page({
data: {
ordersList:[],
userInfo:{}
},
onLoad: function (options) {
var id = options.id;
this.setData({
userInfo:wx.getStorageSync('userInfo'),
})
this.getData(id);
},
getData(id){
var PageThis = this;
wx.request({
url: app.globalData.serverInfo.gateWayUrl,
header: {
'content-type': 'application/json'
},
method: 'POST',
data: {
api_name: "get_one_device_orders_detail",
dev_id: id,
login_manager_id: PageThis.data.userInfo.manager_id,
},
success:function(res){
console.log(res);
PageThis.setData({
ordersList:res.data.data
})
}
})
}
})
\ No newline at end of file
{
"usingComponents": {}
}
\ No newline at end of file
<view class="list_box">
<view class="orders_item" wx:for="{{ordersList}}" wx:key="k">
<view class="order_item_top">
<view class="order_item_hotel_name">{{item.hotel_title}}</view>
<view class="orders_item_state" wx:if="{{item.pay_state == 10}}">未支付</view>
<view class="orders_item_state" wx:if="{{item.pay_state == 20}}">已支付</view>
<view class="orders_item_state" wx:if="{{item.pay_state == 21}}">申请退款</view>
<view class="orders_item_state" wx:if="{{item.pay_state == 22}}">退款中</view>
<view class="orders_item_state" wx:if="{{item.pay_state == 30}}">已退款</view>
<view class="orders_item_state" wx:if="{{item.pay_state == 31}}">部分退款</view>
<view class="orders_item_state" wx:if="{{item.pay_state == 40}}">已完成</view>
</view>
<view class="orders_goods">
<image src="{{item.goods_cover}}"></image>
<view class="orders_goods_content">
<view>
<view class="orders_content_item orders_goods_name">{{item.detail_goods_title}}</view>
<view class="orders_content_item red_color">¥{{item.pay_total_money}}</view>
</view>
<view>
<view class="orders_content_item">
<span>设备格子:</span>
<view class="ball_item">{{item.detail_lat_title*1}}</view>
</view>
</view>
</view>
</view>
<view class="order_item_bottom">
<view class="order_item_info_box">
<view>订单号:{{item.pay_no}}</view>
<view>{{item.pay_create}} </view>
</view>
<view class="order_item_detail_box">
<view>实付金额:<span class="red_color">¥{{item.pay_real_money}}</span></view>
</view>
</view>
</view>
</view>
\ No newline at end of file
.list_box{
width: 100%;
overflow-x: hidden;
}
.orders_item{
width: 100%;
background-color: #FFFFFF;
border-top: 3vw solid rgb(248,248,248);
border-bottom: 2px solid rgb(248,248,248);
}
.order_item_top{
width: 92%;
height: 14vw;
margin: 0 auto;
}
.order_item_hotel_name{
float: left;
font-size: 4.5vw;
height: 100%;
line-height: 14vw;
font-weight: bold;
}
.orders_item_state{
float: right;
background-color: rgb(118,173,255);
color: #FFFFFF;
border-radius: 4vw;
height: 7vw;
line-height: 7vw;
font-size: 3.5vw;
text-align: center;
width: 16vw;
margin: 3.5vw 0;
}
.orders_goods{
width: 100%;
background-color: rgb(248,248,248);
height: 24vw;
}
.orders_goods image{
width: 16vw;
height: 16vw;
background-size: 100% 100%;
margin: 4vw;
float: left;
}
.orders_goods_content{
float: left;
width: 72vw;
height: 22vw;
margin-top: 2vw;
}
.orders_content_item{
width: 55%;
float: left;
text-align: right;
font-size: 3.2vw;
color: #999999;
height: 4vw;
line-height: 4vw;
margin-top: 4vw;
font-weight: bold
}
.orders_content_item span{
float: left;
}
.orders_content_item:nth-child(odd){
width: 45% !important;
text-align: left !important;
}
.orders_goods_name{
font-size: 4vw;
color: #000000;
}
.ball_item{
float: left !important;
margin: 0 0.5vw 0 0!important;
width: 4vw !important;
height: 4vw !important;
line-height: 4vw !important;
text-align: center !important;
color: #FFFFFF !important;
background-color: rgb(55,126,232) !important;
border-radius: 50% !important;
font-size: 3.2vw !important;
}
.order_item_bottom{
height: 20vw;
width: 92vw;
margin: 0 auto;
}
.order_item_info_box{
color: #999999;
font-size: 3.2vw;
width: 100%;
padding-top: 4vw;
}
.order_item_info_box view:nth-child(1){
width: 65%;
float: left;
}
.order_item_info_box view:nth-child(2){
float: right;
}
.order_item_detail_box{
width: 100%;
font-size: 3.8vw;
padding-top: 7vw;
}
.order_item_detail_box view:nth-child(1){
float: left;
}
.order_item_detail_box view:nth-child(2){
color: #000000;
float: right;
}
\ No newline at end of file
// pages/cardDetail/index.js
const app = getApp();
Page({
data: {
userInfo: wx.getStorageSync('userInfo'),
cardId:0,
cardInfo: {}
},
onLoad: function (options){
var PageThis = this;
PageThis.setData({
userInfo:wx.getStorageSync('userInfo')
})
var id = options.id;
this.setData({
cardId: id
})
},
onShow: function (options) {
this.getCardDetail();
},
//**页面跳转 */
navigateTo: function (e) {
var _url = e.currentTarget.dataset.url;
var _id = e.currentTarget.dataset.id;
wx.navigateTo({
url: _url + "?id=" + _id,
})
},
getCardDetail:function(){
var PageThis = this;
var id = PageThis.data.cardId;
wx.request({
url: app.globalData.serverInfo.gateWayUrl,
header: {
'content-type': 'application/json'
},
method: 'POST',
data: {
api_name: "get_bank_card_detail",
card_id: id,
login_manager_id: PageThis.data.userInfo.manager_id
},
success: function (res) {
var data = res.data.data;
PageThis.setData({
"cardInfo": data
})
}
})
}
})
\ No newline at end of file
{
"usingComponents": {}
}
\ No newline at end of file
<view class="info_item">
<view class="info_title">银行卡号</view>
<view class="info_content">{{cardInfo.card_no}}</view>
</view>
<view class="info_item">
<view class="info_title">银行名称</view>
<view class="info_content">{{cardInfo.card_bank}}</view>
</view>
<view class="info_item">
<view class="info_title">开户行名称</view>
<view class="info_content">{{cardInfo.card_open_bank}}</view>
</view>
<view class="info_item">
<view class="info_title">持卡人姓名</view>
<view class="info_content">{{cardInfo.card_name}}</view>
</view>
<view class="info_item">
<view class="info_title">预留手机号</view>
<view class="info_content">{{cardInfo.card_mobile}}</view>
</view>
<view class="info_item">
<view class="info_title">身份证号</view>
<view class="info_content">{{cardInfo.card_identify}}</view>
</view>
<view class="main_btn" bindtap="navigateTo" data-url="../updateCard/index" data-id="{{cardInfo.card_id}}">编辑</view>
\ No newline at end of file
/* pages/cardDetail/index.wxss */
\ No newline at end of file
// pages/cardList/index.js
const app = getApp();
Page({
data: {
userInfo: wx.getStorageSync('userInfo'),
search_value:"",
cardList : []
},
onShow: function () {
var PageThis = this;
PageThis.setData({
userInfo:wx.getStorageSync('userInfo')
})
this.getCardList();
},
//**页面跳转 */
navigateTo: function (e) {
var _url = e.currentTarget.dataset.url;
var _id = e.currentTarget.dataset.id;
wx.navigateTo({
url: _url + "?id=" + _id,
})
},
getCardList:function(){
var PageThis = this;
wx.request({
url: app.globalData.serverInfo.gateWayUrl,
header: {
'content-type': 'application/json'
},
method: 'POST',
data: {
api_name: "get_bank_card",
keywords: PageThis.data.search_value,
login_manager_id: PageThis.data.userInfo.manager_id
},
success:function(res){
res = res.data;
if(res.state == 1){
PageThis.setData({
cardList:res.data
})
}
}
})
}
})
\ No newline at end of file
{
"usingComponents": {}
}
\ No newline at end of file
<view id="search_box">
<view id="search_content_box">
<image src="../../images/icons/icon(51).png"></image>
<input placeholder="请输入银行名称" bindinput="inputChange"></input>
</view>
<view id="search_btn" bindtap="getManagerList">搜索</view>
</view>
<view id="card_list">
<view class="card_item" wx:for="{{cardList}}" wx:key="k" bindtap="navigateTo" data-url="../cardDetail/index" data-id="{{item.card_id}}">
<view class="card_state">
<view>{{item.card_no}}</view>
<view>{{item.card_bank}}</view>
</view>
<view class="card_money blue_color">{{item.card_name}}</view>
</view>
</view>
<image class="add_btn" src="../../images/icons/icon(33).png" bindtap="navigateTo" data-url="../createCard/index"></image>
\ No newline at end of file
#card_list{
width: 100%;
border-top: 3vw solid rgb(248,248,248);
}
.card_item{
width: 100%;
height: 20vw;
border-bottom: 1px solid rgb(248,248,248);
}
.card_state{
height: 13vw;
margin: 3.5vw;
float: left;
}
.card_state view:nth-child(1){
font-size: 4.2vw;
color: rgb(49,66,92);
}
.card_state view:nth-child(2){
color: rgb(156,156,156);
font-size: 3.5vw;
margin-top: 2vw;
}
.card_money{
height: 20vw;
line-height: 20vw;
font-size: 4vw;
float: right;
margin-right: 5vw;
}
\ No newline at end of file
const app = getApp()
var com=require('../com/com.js')
Page({
data: {
userInfo: wx.getStorageSync('userInfo'),
bottomNavList: app.globalData.bottomNavList,
bootomNavIndex: 4,
listData: [
{
icon: '../../images/icons/icon(25).png',
title: '我的钱包',
url: '../wallet/index',
index:1
},
{
icon: '../../images/icons/icon(61).png',
title: '日报表',
url: '../daySheet/index',
index:1
},
{
icon: '../../images/icons/icon(29).png',
title: '提现账号',
url: '../cardList/index',
index:1
},
{
icon: '../../images/icons/icon(26).png',
title: '对账单',
url: '../accountStatement/index',
index:1
},
{
icon: '../../images/icons/refund.png',
title: '退款列表',
url: '../refundList/index',
index:1
},
// {
// icon: '../../images/icons/icon(27).png',
// title: '解除微信授权',
// url: ''
// },
{
icon: '../../images/icons/icon(28).png',
title: '修改密码',
url: '../changePassword/index',
index:0
},
{
icon: '../../images/icons/icon(28).png',
title: '绑定微信',
url: '../getWechat/index',
index:1
},
{
icon: '../../images/icons/wx.png',
title: '微信用户列表',
url: '../wxBindList/index',
index:1
},
{
icon: '../../images/icons/train.png',
title: '培训资料',
url: '../trainInfo/index',
index:1
},
{
icon: '../../images/icons/icon(30).png',
title: '退出账号',
url: 'loginOut',
index:0
}
]
},
onLoad(){
var PageThis = this;
PageThis.setData({
userInfo:wx.getStorageSync('userInfo')
})
},
setBindWechat:function(){
wx.navigateTo({
url: '../getWechat/index',
})
},
//**页面跳转 */
navigateTo: function (e) {
var _url = e.currentTarget.dataset.url;
switch (_url){
case "loginOut":
wx.showModal({
title: '提示',
content: '确认要退出登录?',
success(res) {
if (res.confirm) {
try {
wx.removeStorageSync('userInfo');
wx.removeStorage({ key: 'userInfo' });
wx.reLaunch({
url: '../login/index',
})
} catch (e) {}
} else if (res.cancel) {
}
}
})
break;
default:
wx.navigateTo({
url: _url,
})
break;
}
},
})
\ No newline at end of file
{
"usingComponents": {}
}
\ No newline at end of file
<view id="top_banner">
<image class="banner_img" src="../../images/top_banner/top_banner_default.png"></image>
<view class="center_user_box">
<image class="center_img" src="{{userInfo.manager_bind_avatar}}"></image>
<view class="center_name">{{userInfo.manager_nickname}}</view>
</view>
</view>
<view id="list_box">
<view wx:for="{{listData}}" wx:key="k" class="list_item" data-url="{{item.url}}" bindtap="navigateTo" wx:if="{{userInfo.manager_type!=7}}">
<image class="list_icon" src="{{item.icon}}"></image>
<view class="list_title_box">
<view class="list_title">{{item.title}}</view>
<image class="list_item_icon" src="../../images/icons/icon(55).png"></image>
</view>
<view class="cb"></view>
</view>
<view wx:for="{{listData}}" wx:key="k" class="list_item" data-url="{{item.url}}" bindtap="navigateTo" wx:if="{{userInfo.manager_type==7&&item.index==0}}">
<image class="list_icon" src="{{item.icon}}"></image>
<view class="list_title_box">
<view class="list_title">{{item.title}}</view>
<image class="list_item_icon" src="../../images/icons/icon(55).png"></image>
</view>
<view class="cb"></view>
</view>
</view>
page{
background-color: #F8F8F8;
}
.center_user_box{
position: absolute;
z-index: 1;
width: 100%;
text-align: center;
margin-top: 10vw;
}
.center_img{
width: 18vw;
height: 18vw;
border-radius: 50%;
background-size: 100% 100%;
border: 5px solid rgb(125,172,246);
}
.center_name{
color: #FFFFFF;
font-size: 4.2vw;
margin-top: 2vw;
}
#list_box{
width: 100%;
background-color: rgb(248,248,248);
height: calc(100vh - 65vw);
padding-top: 3vw;
}
\ No newline at end of file
// pages/changePassword/index.js
const app = getApp();
Page({
data: {
userInfo: wx.getStorageSync('userInfo'),
submitData:{
oldPassword: "",
newPassword: "",
rePassword: "",
}
},
onLoad(){
var PageThis = this;
PageThis.setData({
userInfo:wx.getStorageSync('userInfo')
})
},
inputChange: function (e) {
var PageThis = this;
var name = e.currentTarget.dataset.name;
var data = PageThis.data.submitData;
data[name] = e.detail.value;
PageThis.setData({
"submitData": data
})
},
sureSubmit:function(){
var PageThis = this;
var data = PageThis.data.submitData;
data['api_name'] = "update_manager_password";
data['login_manager_id'] = PageThis.data.userInfo.manager_id
wx.request({
url: app.globalData.serverInfo.gateWayUrl,
header: {
'content-type': 'application/json'
},
method: 'POST',
data: data,
success:function(res){
res = res.data;
if (res.state == 1){
wx.showToast({
title: "修改成功",
icon: "success",
duration: 1500
})
setTimeout(function(){
try {
wx.removeStorageSync('userInfo');
wx.removeStorage({ key: 'userInfo' });
wx.reLaunch({
url: '../login/index',
})
} catch (e) { }
},1500);
}else{
wx.showToast({
title: res.msg,
icon:"none",
duration: 2000
})
}
}
})
}
})
\ No newline at end of file
{
"usingComponents": {}
}
\ No newline at end of file
<view class="input_box_item">
<view class="required_tips">*</view>
<view class="input_title">旧密码</view>
<input placeholder="请输入旧密码" bindinput="inputChange" data-name="oldPassword"></input>
</view>
<view class="input_box_item">
<view class="required_tips">*</view>
<view class="input_title">新密码</view>
<input placeholder="请输入新密码" bindinput="inputChange" data-name="newPassword"></input>
</view>
<view class="input_box_item">
<view class="required_tips">*</view>
<view class="input_title">确认新密码</view>
<input placeholder="请再次输入新密码" bindinput="inputChange" data-name="rePassword"></input>
</view>
<view class="main_btn" bindtap="sureSubmit">确认修改</view>
\ No newline at end of file
/* pages/changePassword/index.wxss */
\ No newline at end of file
// pages/com/com.js
//防止多次点击
const app = getApp();
function comButtonClicked(self) {
var timestamp = Date.parse(new Date())/ 1000;
var selfTime =self.data.timestampClicked;
if(timestamp - selfTime >= 2 || selfTime == 0){
self.setData({
timestampClicked: timestamp
})
return true;
}else{
console.log('2秒内多次点击')
return false;
}
}
//获取用户信息USERINFO 输入self 输出账号信息
function comUserInfo(self) {
wx.request({
url: app.globalData.serverInfo.gateWayUrl,
header: {
'content-type': 'application/json'
},
method: 'POST',
data:{
api_name: "get_user_info",
login_manager_id: self
},
success: function(res) {
if (res.data.state == 1) {
wx.setStorage({
key: 'userInfo',
data: res.data.data
});
}
}
});
}
function comTest(self) {
console.log('调用了com->com.js->下面的ComTest函数,并携带了数据:'+self);
}
module.exports.comButtonClicked = comButtonClicked;
module.exports.comUserInfo = comUserInfo;
module.exports.comTest = comTest;
\ No newline at end of file
{
"component": true
}
\ No newline at end of file
// pages/createCared/index.js
const app = getApp();
Page({
data: {
userInfo: wx.getStorageSync('userInfo'),
cardInfo: {}
},
onLoad(){
var PageThis = this;
PageThis.setData({
userInfo:wx.getStorageSync('userInfo')
})
},
createCard:function(){
var PageThis = this;
var cardInfo = PageThis.data.cardInfo;
cardInfo['api_name'] = "add_bank_card";
cardInfo['login_manager_id'] = PageThis.data.userInfo.manager_id
wx.request({
url: app.globalData.serverInfo.gateWayUrl,
header: {
'content-type': 'application/json'
},
method: 'POST',
data: cardInfo,
success:function(res){
res = res.data;
if(res.state == 1){
wx.showToast({
title: '创建成功',
icon: 'success',
duration: 1500,
})
setTimeout(function(){
wx.navigateBack()
},1500);
}else{
wx.showToast({
title: res.msg,
icon: 'none',
duration: 2000,
})
}
}
})
},
inputChange: function (e) {
var PageThis = this;
var name = e.currentTarget.dataset.name;
var data = PageThis.data.cardInfo;
data[name] = e.detail.value;
PageThis.setData({
"cardInfo": data
})
},
})
\ No newline at end of file
{
"usingComponents": {}
}
\ No newline at end of file
<view class="info_item">
<view class="info_title">银行卡号</view>
<input placeholder="请输入银行卡号" bindinput="inputChange" data-name="card_no"></input>
</view>
<view class="info_item">
<view class="info_title">银行名称</view>
<input placeholder="请输入银行名称" bindinput="inputChange" data-name="card_bank"></input>
</view>
<view class="info_item">
<view class="info_title">开户行名称</view>
<input placeholder="请输入开户行名称" bindinput="inputChange" data-name="card_open_bank"></input>
</view>
<view class="info_item">
<view class="info_title">持卡人姓名</view>
<input placeholder="请输入持卡人姓名" bindinput="inputChange" data-name="card_name"></input>
</view>
<view class="info_item">
<view class="info_title">预留手机号</view>
<input placeholder="请输入预留手机号" bindinput="inputChange" data-name="card_mobile"></input>
</view>
<view class="info_item">
<view class="info_title">身份证号</view>
<input placeholder="请输入身份证号" bindinput="inputChange" data-name="card_identify" type="idcard"></input>
</view>
<view class="main_btn" bindtap="createCard">确认创建</view>
\ No newline at end of file
/* pages/createCared/index.wxss */
\ No newline at end of file
// pages/createGoods/index.js
const app = getApp();
Page({
data: {
userInfo: wx.getStorageSync('userInfo'),
mainImg:{
filePath: "../../images/icons/add_img.png",
isUpload: 0,
uploadPath: "",
type: "main",
size: 0
},
cateTitle:"请选择商品分类",
detailImg:[],
detailImgCount:0,
cateList:[],
cateValue:[],
goodsInfo:{},
radioList:[
{
"name":"营业额分成",
"value":1,
"checked":true
},
{
"name":"利润分成",
"value":2,
"checked":false
}
]
},
onLoad: function (options) {
var PageThis = this;
PageThis.setData({
userInfo:wx.getStorageSync('userInfo')
})
this.getGoodsCate();
},
getGoodsCate:function(){
var PageThis = this;
wx.request({
url: app.globalData.serverInfo.gateWayUrl,
header: {
'content-type': 'application/json'
},
method: 'POST',
data:{
api_name: "goods_cate",
login_manager_id: PageThis.data.userInfo.manager_id
},
success:function(res){
var data = res.data.data;
var cateList = [];
for (var i in data){
cateList.push(data[i].c_title);
}
PageThis.setData({
"cateValue": data,
"cateList": cateList
})
}
})
},
chooseImage:function(e){
var PageThis = this;
var count = 1;
var type = e.currentTarget.dataset.type;
if (type == "detail"){
count = 10 - PageThis.data.detailImg.length;
}
wx.chooseImage({
count: count,
sizeType: ['original'],
sourceType: ['album'],
success: function(res) {
console.log(res);
if (type == "main"){
PageThis.setData({
"mainImg": {
"filePath": res.tempFiles[0].path,
"isUpload": 0,
"uploadPath": "",
"type": "main",
"size": res.tempFiles[0].size
}
})
}else{
var imgs = PageThis.data.detailImg;
for (var i in res.tempFilePaths){
var obj = {
"filePath": res.tempFiles[i].path,
"isUpload": 0,
"uploadPath":"",
"type": "detail",
"size": res.tempFiles[i].size,
};
imgs.push(obj);
}
PageThis.setData({
"detailImg": imgs,
"detailImgCount": PageThis.data.detailImgCount + res.tempFilePaths.length
})
}
},
})
},
delImage:function(e){
var PageThis = this;
var name = e.currentTarget.dataset.name;
var data = PageThis.data.detailImg;
var new_data = [];
var new_num = 0;
for (var i in data){
if (data[i]['filePath'] != name){
new_data.push(data[i])
new_num++;
}
}
PageThis.setData({
detailImg: new_data,
detailImgCount: new_num
})
},
inputChange:function(e){
var PageThis = this;
var name = e.currentTarget.dataset.name;
var data = PageThis.data.goodsInfo;
data[name] = e.detail.value;
PageThis.setData({
"goodsInfo": data
})
},
cateChange:function(e){
var PageThis = this;
var id = e.detail.value;
var cateList = PageThis.data.cateList;
var cateValue = PageThis.data.cateValue;
var goodsInfo = PageThis.data.goodsInfo;
for(var i in cateValue){
if (cateValue[i]['c_title'] == cateList[id]){
goodsInfo['g_cate_id'] = cateValue[i]['c_id']
}
}
PageThis.setData({
"cateTitle": cateList[id],
"goodsInfo": goodsInfo
})
},
radioChange(e){
var PageThis = this;
var goodsInfo = PageThis.data.goodsInfo;
goodsInfo['g_money_type'] = e.detail.value;
PageThis.setData({
"goodsInfo":goodsInfo
})
},
uploadImgs:function(){
var PageThis = this;
var data = [PageThis.data.mainImg];
var detailImg = PageThis.data.detailImg;
for (var i in detailImg){
data.push(detailImg[i]);
}
wx.showToast({
title: '图片上传中',
icon: 'loading',
duration: 99999
})
var img_interval = setInterval(function () {
var flag = true;
for (var i in data) {
if (data[i].isUpload != 1) {
flag = false;
}
}
if (flag) {
clearInterval(img_interval);
var detailImgs = [];
for (var i in data){
if (data[i]['type'] == "main"){
PageThis.setData({
"mainImg": data[i]
})
}else{
detailImgs.push(data[i])
}
}
PageThis.setData({
"detailImg": detailImgs
})
wx.hideLoading();
PageThis.createGood();
}
}, 500)
for(var i in data){
if(data[i].isUpload != 1){
wx.uploadFile({
url: app.globalData.serverInfo.uploadFileUrl,
filePath: data[i].filePath,
name: 'file',
success: function (res) {
res = JSON.parse(res.data);
if(res.state == 1){
for(var j in data){
if(data[j].size == res.data.file_size){
data[j]['isUpload'] = 1;
data[j]['uploadPath'] = res.data.file_url;
}
}
}else{
clearInterval(img_interval);
wx.hideLoading();
wx.showToast({
title: '图片上传失败',
icon: 'none',
duration: 2000
})
}
}
})
}
}
},
createGood:function(){
var PageThis = this;
var goodsInfo = PageThis.data.goodsInfo;
goodsInfo['g_cover'] = PageThis.data.mainImg.uploadPath;
goodsInfo['g_pic'] = PageThis.data.detailImg;
goodsInfo['api_name'] = "create_goods";
goodsInfo['login_manager_id'] = PageThis.data.userInfo.manager_id
wx.request({
url: app.globalData.serverInfo.gateWayUrl,
header: {
'content-type': 'application/json'
},
method: 'POST',
data: goodsInfo,
success:function(res){
res = res.data;
if (Number(res.state) == 1){
wx.showToast({
title: '创建成功',
icon: 'success',
duration: 2000,
success:function(){
wx.navigateTo({
url: '../goodsList/index',
})
}
})
}else{
wx.showToast({
title: res.msg,
icon: 'none',
duration: 2000
})
}
}
})
}
})
\ No newline at end of file
{
"usingComponents": {}
}
\ No newline at end of file
<view class="info_item">
<view class="info_title"><span class="red_color">*</span>商品名称</view>
<input placeholder="请输入商品名称" bindinput="inputChange" data-name="g_title"></input>
</view>
<view class="info_item">
<view class="info_title">商品编号</view>
<input placeholder="请输入商品编号" bindinput="inputChange" data-name="g_no"></input>
</view>
<view class="info_item">
<view class="info_title"><span class="red_color">*</span>分成方式</view>
<radio-group bindchange="radioChange">
<label class="radio" wx:for="{{radioList}}" wx:key="k">
<radio value="{{item.value}}" checked="{{item.checked}}" color="#387ee8"/>{{item.name}}
</label>
</radio-group>
</view>
<view class="info_item">
<view class="info_title"><span class="red_color">*</span>进货价格</view>
<input placeholder="请输入进货价格" bindinput="inputChange" data-name="g_cost_price"></input>
</view>
<view class="info_item">
<view class="info_title"><span class="red_color">*</span>下级进货价</view>
<input placeholder="请输入下级进货价" bindinput="inputChange" data-name="g_son_cost_price"></input>
</view>
<view class="info_item">
<view class="info_title"><span class="red_color">*</span>销售价格</view>
<input placeholder="请输入商品销售价" type="digit" bindinput="inputChange" data-name="g_sale_price"></input>
</view>
<view class="info_item info_image_item">
<view class="info_title"><span class="red_color">*</span>商品主图</view>
<view class="cb"></view>
<view class="img_content">
<view class="image_item">
<image src="{{mainImg.filePath}}" data-type="main" bindtap="chooseImage"></image>
</view>
</view>
<view class="cb"></view>
</view>
<view class="info_item">
<view class="info_title"><span class="red_color">*</span>商品分类</view>
<view class="info_content">
<picker range="{{cateList}}" bindchange="cateChange">
<span>{{cateTitle}}</span>
<image class="info_content_img" src="../../images/icons/icon(55).png"></image>
</picker>
</view>
</view>
<view class="info_item">
<view class="info_title">商品描述</view>
<input placeholder="请输入商品描述" bindinput="inputChange" data-name="g_introduce"></input>
</view>
<view class="info_item info_image_item">
<view class="info_title">商品详情</view>
<view class="info_content right_tips">(最多上传10张详情图)</view>
<view class="cb"></view>
<view class="img_content" wx:for="{{detailImg}}" wx:key="k">
<view class="image_item">
<image src="{{item.filePath}}"></image>
<image bindtap="delImage" data-type="detail" class="del_img_btn" src="../../images/icons/icon(49).png" data-name="{{item.filePath}}"></image>
</view>
</view>
<view class="img_content" wx:if="{{detailImgCount <= 9}}">
<view class="image_item" bindtap="chooseImage" data-type="detail">
<image src="../../images/icons/add_img.png"></image>
</view>
</view>
<view class="cb"></view>
</view>
<view class="main_btn" bindtap="uploadImgs">保存</view>
\ No newline at end of file
.del_img_btn{
position: absolute;
width: 5vw !important;
height: 5vw !important;
background-size: 100% 100%;
right: -2vw;
top: -2vw;
border-radius: 50%;
background-color: #FFFFFF;
}
.right_tips{
font-size: 3vw;
text-align: right;
color: #cccccc;
}
\ No newline at end of file
// pages/createGoodsPlan/index.js
const app = getApp();
Page({
data: {
userInfo: wx.getStorageSync('userInfo'),
lat_type:[],
lat_type_value: [],
lat_type_name:"请选择格子机型",
goods_list:[],
goods_list_value:[],
planInfo:{
"gp_title":"",
"gp_lat_type_id":0,
"gp_content":{}
}
},
onLoad: function (options) {
var PageThis = this;
PageThis.setData({
userInfo:wx.getStorageSync('userInfo')
})
this.getLatticeType();
this.getGoodsList();
},
getLatticeType:function(){
var PageThis = this;
wx.request({
url: app.globalData.serverInfo.gateWayUrl,
header: {
'content-type': 'application/json'
},
method: 'POST',
data: {
api_name: "lattice_type",
login_manager_id: PageThis.data.userInfo.manager_id
},
success:function(res){
var data = res.data.data;
console.log(data);
var lat_list = [];
for (var i in data){
lat_list.push(data[i].lt_title);
}
PageThis.setData({
"lat_type_value":data,
"lat_type": lat_list
})
}
})
},
getGoodsList:function(){
var PageThis = this;
wx.request({
url: app.globalData.serverInfo.gateWayUrl,
header: {
'content-type': 'application/json'
},
method: 'POST',
data: {
api_name: "goods_list",
search_title: PageThis.data.searchTitle,
login_manager_id: PageThis.data.userInfo.manager_id
},
success:function(res){
var data = res.data.data;
var goods_list = [];
for (var i in data){
goods_list.push(data[i].g_title);
}
PageThis.setData({
"goods_list_value": data,
"goods_list": goods_list
})
}
})
},
changeName:function(e){
var PageThis = this;
var planInfo = PageThis.data.planInfo;
planInfo['gp_title'] = e.detail.value;
PageThis.setData({
"planInfo": planInfo
})
},
latTypeChange:function(e){
var PageThis = this;
var index = e.detail.value;
var lat_type = PageThis.data.lat_type_value;
var obj = lat_type[index];
var planInfo = PageThis.data.planInfo;
var new_content = [];
for(var i = 0;i<obj.lt_num;i++){
var item = planInfo.gp_content[0] ? planInfo.gp_content[0] : { "plan_goods_id": 0, "plan_goods_title": "请选择商品","plan_goods_price":0 };
new_content.push(item);
}
planInfo['gp_lat_type_id'] = obj['lt_id'];
planInfo['gp_content'] = new_content;
console.log(planInfo);
PageThis.setData({
"lat_type_name": obj['lt_title'],
"planInfo": planInfo
})
},
goodsChange:function(e){
var PageThis = this;
var index = e.target.dataset.index;
var val = e.detail.value;
var planInfo = PageThis.data.planInfo;
var goodsInfo = PageThis.data.goods_list_value[val];
planInfo['gp_content'][index]['plan_goods_title'] = goodsInfo['g_title'];
planInfo['gp_content'][index]['plan_goods_id'] = goodsInfo['g_id'];
planInfo['gp_content'][index]['plan_goods_price'] = goodsInfo['g_sale_price'];
PageThis.setData({
"planInfo": planInfo
});
},
createPlan:function(){
var PageThis = this;
var planInfo = PageThis.data.planInfo;
planInfo['api_name'] = "create_goods_plan";
planInfo['login_manager_id'] = PageThis.data.userInfo.manager_id
wx.request({
url: app.globalData.serverInfo.gateWayUrl,
header: {
'content-type': 'application/json'
},
method: 'POST',
data: planInfo,
success:function(res){
res = res.data;
if(res.state == 1){
wx.showToast({
title: "创建成功",
icon: 'success',
duration: 2000,
success:function(){
setTimeout(function(){
wx.navigateBack({
url: "../goodsPlan/index"
})
},1500);
}
})
}else{
wx.showToast({
title: res.msg,
icon: 'fail',
duration: 2000
})
}
}
})
}
})
\ No newline at end of file
{
"usingComponents": {}
}
\ No newline at end of file
<view class="info_item">
<view class="info_title">方案名称</view>
<input placeholder="请输入方案名称" bindinput="changeName"></input>
</view>
<view class="info_item">
<view class="info_title">格子机型</view>
<view class="info_content">
<picker range="{{lat_type}}" bindchange="latTypeChange">
<span>{{lat_type_name}}</span>
<image class="info_content_img" src="../../images/icons/icon(55).png"></image>
</picker>
</view>
</view>
<view class="top_line"></view>
<view class="info_item" wx:for="{{planInfo.gp_content}}" wx:key="k" wx:for-index="index">
<view class="info_title">{{index+1}}号格子</view>
<view class="info_plan">
<picker range="{{goods_list}}" data-index="{{index}}" bindchange="goodsChange">{{item.plan_goods_title}}</picker>
</view>
<view class="info_price">{{item.plan_goods_price}}元</view>
</view>
<view class="main_btn" bindtap="createPlan">创建方案</view>
\ No newline at end of file
// pages/createHotel/index.js
const app = getApp();
Page({
data: {
userInfo: wx.getStorageSync('userInfo'),
hotelInfo: {},
hotel_type_name:"请选择酒店类型",
hotel_type_list:[],
hotel_type_value:[],
plan_title:"请选择商品方案",
plan_list: [],
plan_list_value:[],
introduce_list:[],
rep_list:[],
user_list:[],
area_list:[],
area_val:0,
introduce_val:0,
user_val:0,
rep_val:0
},
onLoad: function (options) {
var PageThis = this;
PageThis.setData({
userInfo:wx.getStorageSync('userInfo')
})
this.getHotelType();
this.getPlanList();
this.getHotelManager();
this.getArea();
},
getHotelType:function(){
var PageThis = this;
wx.request({
url: app.globalData.serverInfo.gateWayUrl,
header: {
'content-type': 'application/json'
},
method: 'POST',
data: {
api_name: "hotel_type",
login_manager_id: PageThis.data.userInfo.manager_id
},
success:function(res){
var data = res.data.data;
var hotel_type_list = [];
for (var i in data) {
hotel_type_list.push(data[i].t_title);
}
PageThis.setData({
"hotel_type_value": data,
"hotel_type_list": hotel_type_list
})
}
})
},
getPlanList: function () {
var PageThis = this;
wx.request({
url: app.globalData.serverInfo.gateWayUrl,
header: {
'content-type': 'application/json'
},
method: 'POST',
data: {
api_name: "goods_plan",
login_manager_id: PageThis.data.userInfo.manager_id
},
success: function (ret) {
var data = ret.data.data;
var plan_list = [];
for (var i in data){
plan_list.push(data[i].gp_title);
}
PageThis.setData({
"plan_list_value": data,
"plan_list": plan_list
})
}
})
},
changeInput:function(e){
var PageThis = this;
var name = e.currentTarget.dataset.name;
var data = PageThis.data.hotelInfo;
data[name] = e.detail.value;
PageThis.setData({
"hotelInfo": data
})
},
changePicker:function(e){
var PageThis = this;
var name = e.currentTarget.dataset.name;
var data = PageThis.data.hotelInfo;
var value = e.detail.value;
switch (name){
case "h_type_id":
var typeId = PageThis.data.hotel_type_value[value].t_id;
data['h_type_id'] = typeId;
PageThis.setData({
"hotel_type_name": PageThis.data.hotel_type_value[value].t_title,
"hotelInfo": data
})
break;
case "h_default_goods_plan":
var planId = PageThis.data.plan_list_value[value].gp_id;
data['h_default_goods_plan'] = planId;
PageThis.setData({
"plan_title": PageThis.data.plan_list_value[value].gp_title,
"hotelInfo": data
})
break;
case "h_introduce_id":
var introduce_list = PageThis.data.introduce_list;
data['h_introduce_id'] = introduce_list[value].manager_id;
PageThis.setData({
"hotelInfo": data,
"introduce_val":value
})
break;
case "h_rep_id":
var rep_list = PageThis.data.rep_list;
data['h_rep_id'] = rep_list[value].manager_id;
PageThis.setData({
"hotelInfo": data,
"rep_val":value
})
break;
case "h_user_id":
var user_list = PageThis.data.user_list;
data['h_user_id'] = user_list[value].manager_id;
PageThis.setData({
"hotelInfo": data,
"user_val":value
})
break;
case "h_lot_id":
var area_list = PageThis.data.area_list;
data['h_lot_id'] = area_list[value].lot_id;
PageThis.setData({
"hotelInfo": data,
"area_val":value
})
break;
}
},
/**
* 获取酒店管理人员
*/
getHotelManager(){
var PageThis = this;
wx.request({
url: app.globalData.serverInfo.gateWayUrl,
header: {
'content-type': 'application/json'
},
method: 'POST',
data: {
api_name: "get_hotel_manager",
login_manager_id: PageThis.data.userInfo.manager_id
},
success: function (ret) {
var data = ret.data.data;
data['introduce'].unshift({
"manager_id":0,
"manager_nickname":"请选择介绍人"
});
data['manager_hotel'].unshift({
"manager_id":0,
"manager_nickname":"请选择酒店管理员"
});
data['rep'].unshift({
"manager_id":0,
"manager_nickname":"请选择补货员"
});
PageThis.setData({
introduce_list: data['introduce'],
user_list: data['manager_hotel'],
rep_list: data['rep'],
})
}
})
},
/**
* 获取位置地段
*/
getArea(){
var PageThis = this;
wx.request({
url: app.globalData.serverInfo.gateWayUrl,
header: {
'content-type': 'application/json'
},
method: 'POST',
data:{
api_name: "get_hotel_lot",
},
success:function(res){
var ret = res.data;
if(Number(ret.state) === 1){
var obj = {
lot_id:0,
lot_title:"请选择位置地段"
}
ret.data.unshift(obj);
PageThis.setData({
"area_list": ret.data
})
}
}
})
},
/**
* 创建酒店
*/
createHotel:function(){
var PageThis = this;
var hotelInfo = PageThis.data.hotelInfo;
hotelInfo['api_name'] = "create_hotel";
hotelInfo['login_manager_id'] = PageThis.data.userInfo.manager_id;
wx.request({
url: app.globalData.serverInfo.gateWayUrl,
header: {
'content-type': 'application/json'
},
method: 'POST',
data: hotelInfo,
success:function(res){
res = res.data;
if (Number(res.state) == 1) {
wx.showToast({
title: '创建成功',
icon: 'success',
duration: 2000,
success: function () {
wx.navigateBack({
url: '../hotelList/index',
})
}
})
} else {
wx.showToast({
title: res.msg,
icon: 'none',
duration: 2000
})
}
}
})
}
})
\ No newline at end of file
{
"usingComponents": {}
}
\ No newline at end of file
<view class="info_item">
<view class="info_title">酒店名称</view>
<input placeholder="请输入酒店名称" data-name="h_title" bindinput="changeInput"></input>
</view>
<view class="info_item">
<view class="info_title">营业执照编码</view>
<input placeholder="请输入营业执照编码" data-name="h_code" bindinput="changeInput"></input>
</view>
<view class="info_item">
<view class="info_title">酒店负责人</view>
<input placeholder="请输入酒店负责人名称" data-name="h_lead" bindinput="changeInput"></input>
</view>
<view class="info_item">
<view class="info_title">酒店类型</view>
<view class="info_content">
<picker range="{{hotel_type_list}}" bindchange="changePicker" data-name="h_type_id">
<span>{{hotel_type_name}}</span>
<image class="info_content_img" src="../../images/icons/icon(55).png"></image>
</picker>
</view>
</view>
<view class="info_item">
<view class="info_title">介绍人</view>
<view class="info_content">
<picker range="{{introduce_list}}" value="{{introduce_val}}" range-key="manager_nickname" bindchange="changePicker" data-name="h_introduce_id">
<span>{{introduce_list[introduce_val].manager_nickname}}</span>
<image class="info_content_img" src="../../images/icons/icon(55).png"></image>
</picker>
</view>
</view>
<view class="info_item">
<view class="info_title">酒店管理员</view>
<view class="info_content">
<picker range="{{user_list}}" value="{{user_val}}" range-key="manager_nickname" bindchange="changePicker" data-name="h_user_id">
<span>{{user_list[user_val].manager_nickname}}</span>
<image class="info_content_img" src="../../images/icons/icon(55).png"></image>
</picker>
</view>
</view>
<view class="info_item">
<view class="info_title">补货员</view>
<view class="info_content">
<picker range="{{rep_list}}" value="{{rep_val}}" range-key="manager_nickname" bindchange="changePicker" data-name="h_rep_id">
<span>{{rep_list[rep_val].manager_nickname}}</span>
<image class="info_content_img" src="../../images/icons/icon(55).png"></image>
</picker>
</view>
</view>
<view class="info_item">
<view class="info_title">负责人电话</view>
<input type="number" placeholder="请输入酒店负责人手机号" data-name="h_mobile" bindinput="changeInput"></input>
</view>
<view class="info_item">
<view class="info_title">酒店电话</view>
<input type="number" placeholder="请输入酒店电话" data-name="h_phone" bindinput="changeInput"></input>
</view>
<view class="info_item">
<view class="info_title">酒店地址</view>
<view class="info_content">
<input placeholder="请输入酒店地址" data-name="h_address" style="width:60vw;float:left;" bindinput="changeInput"></input>
<image class="info_content_img" src="../../images/icons/icon(50).png"></image>
</view>
</view>
<view class="info_item">
<view class="info_title">位置地段</view>
<view class="info_content">
<picker range="{{area_list}}" value="{{area_val}}" range-key="lot_title" bindchange="changePicker" data-name="h_lot_id">
<span>{{area_list[area_val].lot_title}}</span>
<image class="info_content_img" src="../../images/icons/icon(55).png"></image>
</picker>
</view>
</view>
<view class="info_item">
<view class="info_title">房间数量</view>
<view class="info_content">
<input placeholder="请输入房间数量" data-name="h_room_num" bindinput="changeInput"></input>
</view>
</view>
<view class="info_item">
<view class="info_title">默认方案</view>
<view class="info_content">
<picker range="{{plan_list}}" bindchange="changePicker" data-name="h_default_goods_plan">
<span>{{plan_title}}</span>
<image class="info_content_img" src="../../images/icons/icon(55).png"></image>
</picker>
</view>
</view>
<view class="main_btn" bindtap="createHotel">创建酒店</view>
\ No newline at end of file
.info_content input{
height: 4vw;
line-height: 4vw;
font-size: 3.5vw;
margin-top: 3vw;
padding: 0;
}
.map_item{
width: 95vw;
height: 60vw;
border-radius: 5px;
margin: 2.5vw;
}
\ No newline at end of file
// pages/createRepair/index.js
const app = getApp();
Page({
data: {
userInfo: {},
deviceList: [],
deliveryInfo:{
pay_method:2,
delivery_company:"",
delivery_number:"",
receive_back_address:""
},
sendTypeValue:2,
paymentTypeValue:2,
sendTypeList:[
{
"name":"自取",
"value":1,
"checked":false
},
{
"name":"快递",
"value":2,
"checked":true
}
],
paymentTypeList:[
{
"name":"到付",
"value":1,
"checked":false
},
{
"name":"寄付",
"value":2,
"checked":true
}
]
},
onLoad: function (options) {
this.setData({
userInfo:wx.getStorageSync('userInfo')
})
},
radioChange(e){
var PageThis = this;
var goodsInfo = PageThis.data.goodsInfo;
goodsInfo['g_money_type'] = e.detail.value;
PageThis.setData({
"goodsInfo":goodsInfo
})
},
quickScan(){
var PageThis = this;
wx.scanCode({
scanType:"qrCode",
success (res) {
var scan_url = res.result;
var thisDevNo = scan_url.replace(app.globalData.serverInfo.qrReplaceUrl, '');
if(thisDevNo != "" ){
var deviceList = PageThis.data.deviceList;
for(var i in deviceList){
if(deviceList[i].dev_no == thisDevNo){
wx.showToast({
title: '此设备已记录',
icon: 'none'
})
return;
}
}
var obj = {
dev_no:thisDevNo,
repair_content:{
'reason':""
}
}
deviceList.unshift(obj);
PageThis.setData({
deviceList:deviceList
})
}else{
wx.showToast({
title: '无效二维码',
icon:"none"
})
}
}
})
},
inputChange:function(e){
var PageThis = this;
var name = e.currentTarget.dataset.name;
var code = e.currentTarget.dataset.code;
var val = e.detail.value;
var devList = PageThis.data.deviceList;
var deliveryInfo = PageThis.data.deliveryInfo;
console.log(e);
switch(name){
case "delivery_company":
case "delivery_number":
case "receive_back_address":
deliveryInfo[name] = val;
PageThis.setData({
deliveryInfo:deliveryInfo
})
break;
// case "errro_detail":
// console.log(devList);
// for(var i in devList){
// if(devList[i].dev_no == code){
// devList[i].repair_content.reason = val;
// break;
// }
// }
// PageThis.setData({
// deviceList:devList
// })
// break;
}
},
radioChange(e){
var PageThis = this;
var name = e.currentTarget.dataset.name;
var val = e.detail.value;
var deliveryInfo = PageThis.data.deliveryInfo;
switch(name){
case "repair_delivery_type":
PageThis.setData({
sendTypeValue:val
})
break;
case "pay_method":
deliveryInfo[name] = val;
PageThis.setData({
deliveryInfo:deliveryInfo,
paymentTypeValue:val
})
break;
}
},
del_dev(e){
var PageThis = this;
var code = e.currentTarget.dataset.code;
var devList = PageThis.data.deviceList;
for(var i in devList){
if(devList[i].dev_no == code){
devList.splice(i,1);
break;
}
}
PageThis.setData({
deviceList:devList
})
},
applyRepair(e){
var PageThis = this;
var repair_delivery_type = PageThis.data.sendTypeValue;
var dev_list = PageThis.data.deviceList;
var repair_delivery_content = PageThis.data.deliveryInfo;
var value = e.detail.value;
if(dev_list.length <= 0){
wx.showToast({
title: '无故障设备信息',
icon:"none"
})
return;
}
for(var i=0;i<99;i++){
if(typeof(value['dev_code['+i+']']) != "undefined"){
for(var j in dev_list){
if(dev_list[j].dev_no == value['dev_code['+i+']']){
dev_list[j].repair_content.reason = value['reason['+i+']'];
break;
}
}
}else{
break;
}
}
for(var i in dev_list){
if(dev_list[i].repair_content.reason == ""){
wx.showToast({
title: '未输入设备故障信息',
icon:"none"
})
return;
}
}
if(Number(repair_delivery_type) == 2){
var str = "";
console.log(repair_delivery_content);
if(repair_delivery_content.delivery_company == ""){
str = "未输入快递公司名称";
}else if(repair_delivery_content.delivery_number == ""){
str = "未输入快递单号";
}else if(repair_delivery_content.receive_back_address == ""){
str = "未输入寄回地址";
}
if(str != ""){
wx.showToast({
title: str,
icon:"none"
})
return;
}
}
var send = {
api_name: "apply_device_repair",
repair_delivery_type:repair_delivery_type,
dev_list:dev_list,
repair_delivery_content:repair_delivery_content,
login_manager_id: PageThis.data.userInfo.manager_id
}
wx.request({
url: app.globalData.serverInfo.gateWayUrl,
header: {
'content-type': 'application/json'
},
method: 'POST',
data: send,
success:function(res){
var ret = res.data;
if(Number(ret.state) === 1){
wx.showToast({
title: '保存成功',
success(res){
wx.redirectTo({
url: '../afterSaleList/index',
})
}
})
}else{
wx.showToast({
title: ret.msg,
icon:"none"
})
return;
}
}
})
},
scanDelivery(){
var PageThis = this;
var deliveryInfo = PageThis.data.deliveryInfo;
wx.scanCode({
scanType:"barCode",
success (res) {
deliveryInfo['delivery_number'] = res.result;
console.log(deliveryInfo);
PageThis.setData({
deliveryInfo:deliveryInfo
})
}
})
}
})
\ No newline at end of file
{
"usingComponents": {}
}
\ No newline at end of file
<view class="specialTitleBox">
<view class="specialTitle">快递信息</view>
</view>
<view class="info_item">
<view class="info_title"><span class="red_color">*</span>寄送方式</view>
<radio-group bindchange="radioChange" data-name="repair_delivery_type">
<label class="radio" wx:for="{{sendTypeList}}" wx:key="k">
<radio value="{{item.value}}" checked="{{item.checked}}"/>{{item.name}}
</label>
</radio-group>
</view>
<view class="info_item" wx:if="{{sendTypeValue == 2}}">
<view class="info_title"><span class="red_color">*</span>快递公司</view>
<input placeholder="请输入快递公司" bindinput="inputChange" data-name="delivery_company"></input>
</view>
<view class="info_item" wx:if="{{sendTypeValue == 2}}">
<view class="info_title"><span class="red_color">*</span>快递单号</view>
<input placeholder="请扫描快递单号" bindinput="inputChange" data-name="delivery_number" value="{{deliveryInfo.delivery_number}}"></input>
<image bindtap="scanDelivery" src="../../images/icons/scan.png"></image>
</view>
<view class="info_item" wx:if="{{sendTypeValue == 2}}">
<view class="info_title"><span class="red_color">*</span>付费方式</view>
<radio-group bindchange="radioChange" data-name="pay_method">
<label class="radio" wx:for="{{paymentTypeList}}" wx:key="k">
<radio value="{{item.value}}" checked="{{item.checked}}"/>{{item.name}}
</label>
</radio-group>
</view>
<view class="info_item" wx:if="{{sendTypeValue == 2}}">
<view class="info_title"><span class="red_color">*</span>寄回地址</view>
<input placeholder="修好寄回地址" bindinput="inputChange" data-name="receive_back_address"></input>
</view>
<view class="specialTitleBox">
<view class="specialTitle">设备列表</view>
</view>
<form catchsubmit="applyRepair">
<view class="dev_box" wx:for="{{deviceList}}" wx:key="k">
<view class="dev_box_del" bindtap="del_dev" data-code="{{item.dev_no}}">删除</view>
<view class="info_item">
<view class="info_title"><span class="red_color">*</span>设备编号</view>
<input name="dev_code[{{index}}]" placeholder="请输入设备编号" disabled="disable" value="{{item.dev_no}}"></input>
</view>
<view class="info_item">
<view class="info_title"><span class="red_color">*</span>故障详情</view>
<textarea name="reason[{{index}}]" placeholder="请输入设备故障详情"/>
</view>
<view class="cb"></view>
</view>
<button class="main_btn" form-type="submit">保存</button>
</form>
<image id="quickScan" bindtap="quickScan" src="../../images/icons/qrScan.png"></image>
\ No newline at end of file
.specialTitleBox{
width: 100%;
border-bottom: 1px solid #eeeeee;
height: 5vw;
margin-bottom: 5vw;
position: relative;
}
.specialTitle{
position: absolute;
top: 2.5vw;
left: 8vw;
background-color: #FFFFFF;
padding: 0 3vw;
font-size: 4vw;
color: #bbbbbb;
}
#quickScan{
position: fixed;
bottom: 10vw;
right: 5vw;
width: 6vw;
height: 6vw;
background-color: #387ee8;
border-radius: 50%;
padding: 4vw;
}
.dev_box{
width: 100%;
border-bottom: 1px solid #eeeeee;
height: 37vw;
padding-top: 2vw;
position: relative;
}
.dev_box .info_item{
border: none;
height: 8vw;
line-height: 8vw;
}
.dev_box .info_item input{
padding: 0;
}
textarea{
height: 15vw;
background-color: rgba(220,220,220,0.3);
border-radius: 5px;
}
.dev_box_del{
color: #FFFFFF;
position: absolute;
background-color: #DD4F42;
text-align: center;
line-height: 3vw;
font-size: 3.5vw;
right: 5vw;
top: 3.5vw;
padding: 1vw 2vw;
z-index: 10;
}
.info_item image{
position: absolute;
right: 5vw;
width: 5vw;
height: 5vw;
background-size: 100% 100%;
background-color: #FFFFFF;
z-index: 100;
margin-top: -8.5vw;
}
.main_btn{
width: 95vw !important;
margin: 0 auto;
}
\ No newline at end of file
// pages/managerUser/index.js
const app = getApp();
Page({
/**
* 页面的初始数据
*/
data: {
userInfo:[],
manager_type:[],
type_index:0,
type_id:0,
p_index:0,
p_id:0,
showPartner:0,
showProportion:0,
manager_username:0,
manager_password:0,
manager_nickname:0,
manager_percent:0,
manager_fee:0,
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
var PageThis = this;
var userInfo = wx.getStorageSync('userInfo');
var manager_type = [];
if(userInfo['manager_type'] == 1){
manager_type = [
{
type_title:"管理员",
type_id:1
},
{
type_title:"生产厂商",
type_id:2
},
{
type_title:"合伙人",
type_id:3
},
{
type_title:"运维人员",
type_id:4
},
{
type_title:"介绍人",
type_id:5
},
{
type_title:"酒店管理员",
type_id:6
},
{
type_title:"补货员",
type_id:7
},
]
}else if(userInfo['manager_type'] == 2){
wx.showToast({
title: '您没权限',
icon:'none'
});
return false;
}else if(userInfo['manager_type'] == 3 || userInfo['manager_type'] == 4){
manager_type = [
{
type_title:"合伙人",
type_id:3
},
{
type_title:"运维人员",
type_id:4
},
{
type_title:"介绍人",
type_id:5
},
{
type_title:"酒店管理员",
type_id:6
},
{
type_title:"补货员",
type_id:7
},
];
}else if(userInfo['manager_type'] == 5){
wx.showToast({
title: '您没权限',
icon:'none'
});
return false;
}else if(userInfo['manager_type'] == 6){
manager_type = [
{
type_title:"补货员",
type_id:7
},
]
}else if(userInfo['manager_type'] == 7){
wx.showToast({
title: '您没权限',
icon:'none'
});
return false;
}
PageThis.setData({
userInfo:wx.getStorageSync('userInfo'),
manager_type:manager_type
})
PageThis.getPartnerList();
},
changeInput:function(e){
var PageThis = this;
var name = e.currentTarget.dataset.name;
PageThis.setData({
[name]: e.detail.value
})
},
changePicker:function(e){
var PageThis = this;
var value = e.detail.value;
var type_id = PageThis.data.manager_type[value].type_id;
var userInfo = wx.getStorageSync('userInfo');
var pid = 0;
var showPartner = 0;
var showProportion = 0;
var need_arr = [3,4,5,6,7];
if((type_id == 3 || type_id == 4 || type_id == 5 || type_id == 6 || type_id == 7) && (userInfo['manager_type'] == 1 || userInfo['manager_type'] == 3)){
//需要展示合伙人
showPartner = 1;
}else if(userInfo['manager_type'] == 4 || userInfo['manager_type'] == 6){
pid = userInfo['manager_pid'];
//不展示合伙人选项
showPartner = 0;
}
if((type_id == 3|| type_id == 5 || type_id == 6 )){
//展示分账比例和提现手续费输入
showProportion = 1;
}else{
//不展示分账比例和提现手续费输入
showProportion = 0;
}
PageThis.setData({
"type_index": value,
"type_id":type_id,
"p_id":pid,
"showPartner":showPartner,
"showProportion":showProportion,
});
},
changePartnerPicker:function(e){
var PageThis = this;
var value = e.detail.value;
var p_id = PageThis.data.partner_list[value].manager_id;
PageThis.setData({
"p_index": value,
"p_id":p_id
})
},
getPartnerList:function(){
var PageThis = this;
wx.request({
url: app.globalData.serverInfo.gateWayUrl,
header: {
'content-type': 'application/json'
},
method: 'POST',
data:{
api_name: "get_partner_list",
login_manager_id: PageThis.data.userInfo.manager_id
},
success:function(res){
var data = res.data.data;
var unshiftData ={};
unshiftData={
'manager_id':0,
'manager_nickname':'顶级合伙人'
}
data.unshift(unshiftData);
PageThis.setData({
"partner_list": data
})
console.log(data);
}
})
},
createManager:function(){
var PageThis = this;
var manager_username = PageThis.data.manager_username;
var manager_password = PageThis.data.manager_password;
var manager_nickname = PageThis.data.manager_nickname;
if(manager_nickname =="" || manager_nickname.length<2){
wx.showToast({
title: '请输入正确的用户名',
icon: 'none',
duration: 2000
})
return false;
}
if(manager_username=="" || manager_username.length < 5){
wx.showToast({
title: '请输入大于5位的登录账号',
icon: 'none',
duration: 2000
})
return false;
}
if(manager_password=="" || manager_password.length<6){
wx.showToast({
title: '请输入大于6位的登录密码',
icon: 'none',
duration: 2000
})
return false;
}
wx.request({
url: app.globalData.serverInfo.gateWayUrl,
header: {
'content-type': 'application/json'
},
method: 'POST',
data: {
api_name: "create_manager",
manager_pid: PageThis.data.p_id,
manager_type: PageThis.data.type_id,
manager_username: PageThis.data.manager_username,
manager_password: PageThis.data.manager_password,
manager_nickname: PageThis.data.manager_nickname,
manager_percent: PageThis.data.manager_percent,
manager_fee: PageThis.data.manager_fee,
login_manager_id: PageThis.data.userInfo.manager_id
},
success:function(res){
res = res.data;
wx.showToast({
title: res.msg,
icon: 'none',
duration: 2000
})
if(res.state==1){
setTimeout(function () {
wx.switchTab({
url: '../index/index',
})
}, 2000);
}
}
})
}
})
\ No newline at end of file
{
"usingComponents": {}
}
\ No newline at end of file
<view class="info_item">
<view class="info_title">账号类型</view>
<view class="info_content">
<picker range="{{manager_type}}" value="{{type_index}}" range-key="type_title" bindchange="changePicker">
<span> {{manager_type[type_index].type_title}}</span>
<image class="info_content_img" src="../../images/icons/icon(55).png"></image>
</picker>
</view>
</view>
<view class="info_item" wx:if="{{showPartner == 1}}">
<view class="info_title">所属合伙人</view>
<view class="info_content">
<picker range="{{partner_list}}" value="{{p_index}}" range-key="manager_nickname" bindchange="changePartnerPicker">
<span> {{partner_list[p_index].manager_nickname}}</span>
<image class="info_content_img" src="../../images/icons/icon(55).png"></image>
</picker>
</view>
</view>
<view class="info_item">
<view class="info_title">用户名称</view>
<input placeholder="请输入用户名称" data-name="manager_nickname" bindinput="changeInput"></input>
</view>
<view class="info_item">
<view class="info_title">登陆账号</view>
<input placeholder="请输入登陆账号" data-name="manager_username" bindinput="changeInput"></input>
</view>
<view class="info_item">
<view class="info_title">登陆密码</view>
<input placeholder="请输入登陆密码" data-name="manager_password" bindinput="changeInput"></input>
</view>
<view class="info_item" wx:if="{{showProportion == 1}}">
<view class="info_title">分成比例(%)</view>
<input placeholder="请输入分成比例" data-name="manager_percent" bindinput="changeInput"></input>
</view>
<view class="info_item" wx:if="{{showProportion == 1}}">
<view class="info_title">提现手续费</view>
<input placeholder="请输入提现手续费" data-name="manager_fee" bindinput="changeInput"></input>
</view>
<view class="main_btn" bindtap="createManager">创建账号</view>
\ No newline at end of file
/* pages/createUser/index.wxss */
\ No newline at end of file
// pages/daySheet/index.js
const app = getApp();
Page({
data: {
userInfo:{},
pageData:{}
},
onLoad: function (options) {
this.setData({
userInfo:wx.getStorageSync('userInfo')
})
},
onShow: function () {
this.getData();
},
getData: function () {
var PageThis = this;
wx.request({
url: app.globalData.serverInfo.gateWayUrl,
header: {
'content-type': 'application/json'
},
method: 'POST',
data: {
api_name: "get_day_sheet",
login_manager_id: PageThis.data.userInfo.manager_id
},
success: function (res) {
console.log(res);
PageThis.setData({
pageData:res.data.data
})
}
})
},
})
\ No newline at end of file
{
"usingComponents": {}
}
\ No newline at end of file
<view id="tips_bar">
<image src="../../images/icons/data.png"></image>
<view style="font-size:3.5vw;color:#000">运营数据</view>
<view>(该数据位截止到昨天24点统计数据,非实时数据)</view>
</view>
<view class="data_item">
<view>昨日营业额</view>
<view>¥{{pageData.yesterday_turnover}}</view>
</view>
<view class="data_item">
<view>昨日订单数</view>
<view>{{pageData.yesterday_orders_number}}</view>
</view>
<view class="data_item">
<view>昨日分成额</view>
<view>¥{{pageData.yesterday_sep_money}}</view>
</view>
<view class="data_item">
<view>昨日成交率</view>
<view>{{pageData.yesterday_turnover_rate}}</view>
</view>
<view class="data_item">
<view>昨日扫码量</view>
<view>{{pageData.yesterday_scan_number}}</view>
</view>
<view class="data_item">
<view>昨日有效扫码量</view>
<view>{{pageData.yesterday_valid_scan_number}}</view>
</view>
<view class="data_item">
<view>运营设备数</view>
<view>{{pageData.total_device_number}}</view>
</view>
<view class="data_item">
<view>昨日设备产值</view>
<view>¥{{pageData.yesterday_device_output_value}}</view>
</view>
<view class="data_item">
<view>退款订单数</view>
<view>{{pageData.yesterday_refund_orders_number}}</view>
</view>
<view class="data_item">
<view>退款金额</view>
<view>¥{{pageData.yesterday_refund_orders_money}}</view>
</view>
<view class="data_item">
<view>产出订单设备数</view>
<view>{{pageData.yesterday_orders_device_number}}</view>
</view>
<view class="data_item">
<view>昨日补货数</view>
<view>{{pageData.yesterday_rep_number}}</view>
</view>
<view class="data_item">
<view>补货率</view>
<view>{{pageData.yesterday_rep_rate}}</view>
</view>
\ No newline at end of file
#tips_bar{
width: 95vw;
margin: 0 2.5vw;
height: 8vw;
line-height: 8vw;
}
#tips_bar image{
float: left;
width: 6vw;
height: 6vw;
background-size: 100% 100%;
margin: 1vw;
}
#tips_bar view{
float: left;
font-size: 3vw;
color: #999999;
}
.data_item{
width: calc(50vw - 1px);
float: left;
text-align: center;
padding: 5vw 0;
font-size: 3.5vw;
border: 1px solid #eeeeee;
margin-left: -1px;
margin-top: -1px;
line-height: 7vw;
}
.data_item view:nth-child(1){
}
.data_item view:nth-child(2){
font-weight: bold;
color: #05BC82;
}
\ No newline at end of file
const app = getApp()
Page({
data: {
UUID:"6E400001-B5A3-F393-E0A9-E50E24DCCA9E",
deviceId:"",
devMac:"",
deviceNum:"0000000000",
serviceId:"6E400001-B5A3-F393-E0A9-E50E24DCCA9E",
readCharacteristic:"6E400003-B5A3-F393-E0A9-E50E24DCCA9E",
writeCharacteristic:"6E400002-B5A3-F393-E0A9-E50E24DCCA9E",
timer:0,
pwdCode:"",
pwdEncode:"",
encodeKey:"aabbccdd20191210aabbccdd20191210",
deviceList:[],
listDisplay:"block",
listType:"listActive",
openBoxShow:"none",
isConnect:0,
viewData:{
dev_mac:"",
dev_num:"",
dev_power:"",
dev_lat:"",
dev_stock:"",
lat_1_code:"",
lat_2_code:"",
lat_3_code:"",
lat_4_code:"",
manager_code:"",
stock_code:"",
charge_time:""
},
deviceInfo:[]
},
onLoad: function (options) {
this.openBluetoothAdapter();
},
onUnload: function(){
clearInterval(this.data.timer);
this.stopBluetoothDevicesDiscovery();
this.closeBLEConnection();
this.closeBluetoothAdapter();
},
/**
* 筛选设备列表
*/
selectDevice:function(){
var that = this;
var listType = that.data.listType;
if(listType == "listActive"){
listType = "";
}else{
listType = "listActive"
}
that.setData({
listType:listType
})
},
//连接蓝牙
connectDevice(e){
var that = this;
var deviceId = e.currentTarget.dataset.id;
var deviceList = that.data.deviceList;
if(deviceId != "" && typeof(deviceId) != "undefined"){
for(var i in deviceList){
if(deviceList[i].deviceId == deviceId){
that.setData({
btInfo:deviceList[i],
})
break;
}
}
that.setData({
deviceId:deviceId,
})
that.createBLEConnection(deviceId);
}
},
//设置设备编号
setDevNum:function(code){
var that = this;
let hex = [];
hex.push(parseInt('AA',16));
hex.push(parseInt('01',16));
console.log(typeof(Number(code)));
if(code.length != 10 && typeof(Number(code)) != "number"){
wx.showToast({
icon:"none",
title:"格式错误"
})
return;
}
for(var i in code){
hex.push(code.charCodeAt(i));
}
that.writeBLECharacteristicValue(hex);
},
//打开格子
openLat:function(e){
console.log(e);
var that = this;
var device_num = that.data.deviceNum;
var lat = e.currentTarget.dataset.lat;
var hex = [];
hex.push(parseInt('AA',16));
hex.push(parseInt('02',16));
for(var i in device_num){
hex.push(parseInt(device_num[i],16));
}
hex.push(parseInt(Number(lat),16))
that.writeBLECharacteristicValue(hex);
},
//打开缺货格子
openNoStockLat(){
var that = this;
var device_num = that.data.deviceNum;
var hex = [];
hex.push(parseInt('AA',16));
hex.push(parseInt('03',16));
for(var i in device_num){
hex.push(parseInt(device_num[i],16));
}
that.writeBLECharacteristicValue(hex);
},
//打开全部格子
openAllLat(){
var that = this;
var device_num = that.data.deviceNum;
var hex = [];
hex.push(parseInt('AA',16));
hex.push(parseInt('04',16));
for(var i in device_num){
hex.push(parseInt(device_num[i],16));
}
that.writeBLECharacteristicValue(hex);
},
//读取设备库存
readDeviceStock(){
var that = this;
var device_num = that.data.deviceNum;
var hex = [];
hex.push(parseInt('AA',16));
hex.push(parseInt('05',16));
for(var i in device_num){
hex.push(parseInt(device_num[i],16));
}
that.writeBLECharacteristicValue(hex);
},
//读取电池电量
readPower(){
var that = this;
var device_num = that.data.deviceNum;
var hex = [];
hex.push(parseInt('AA',16));
hex.push(parseInt('06',16));
for(var i in device_num){
hex.push(parseInt(device_num[i],16));
}
that.writeBLECharacteristicValue(hex);
},
//读取货道数量
readLatNum(){
var that = this;
var device_num = that.data.deviceNum;
var hex = [];
hex.push(parseInt('AA',16));
hex.push(parseInt('07',16));
for(var i in device_num){
hex.push(parseInt(device_num[i],16));
}
that.writeBLECharacteristicValue(hex);
},
//设置充电时长
setChargeTime(time){
var that = this;
var device_num = that.data.deviceNum;
var hex = [];
hex.push(parseInt('AA',16));
hex.push(parseInt('08',16));
var time_hex = time.toString(16).padStart(4,'0');
console.log(time_hex);
hex.push(parseInt(time_hex.substr(0,2),16));
hex.push(parseInt(time_hex.substr(2,2),16));
for(var i in device_num){
hex.push(parseInt(device_num[i],16));
}
that.writeBLECharacteristicValue(hex);
},
//配置取货码
setSetGoodsCode:function(port,code){
var that = this;
var device_num = that.data.deviceNum;
var hex = [];
hex.push(parseInt('AA',16));
hex.push(parseInt('09',16));
hex.push(parseInt(port,16));
for(var i=0;i<4;i++){
hex.push(parseInt(code.substr(Number(i*2),2),16));
}
for(var i in device_num){
hex.push(parseInt(device_num[i],16));
}
wx.showLoading({
title: '写入中',
})
that.writeBLECharacteristicValue(hex);
},
//配置补货员
setSetManagerCode:function(socketCode,managerCode){
var that = this;
var device_num = that.data.deviceNum;
var hex = [];
hex.push(parseInt('AA',16));
hex.push(parseInt('0A',16));
for(var i=0;i<4;i++){
hex.push(parseInt(socketCode.substr(Number(i*2),2),16));
}
for(var i=0;i<4;i++){
hex.push(parseInt(managerCode.substr(Number(i*2),2),16));
}
for(var i in device_num){
hex.push(parseInt(device_num[i],16));
}
that.writeBLECharacteristicValue(hex);
},
// 初始化蓝牙适配器
openBluetoothAdapter() {
var that = this;
that.closeBluetoothAdapter();
that.closeBLEConnection();
wx.openBluetoothAdapter({
success: function (res) {
console.log("初始化蓝牙适配器成功");
that.startBluetoothDevicesDiscovery();
},
fail: function (err) {
wx.showModal({
title: '温馨提示',
content: '请先打开手机蓝牙,再点击确定重新连接',
cancelText:"已开蓝牙",
confirmText: "重新连接",
success (res) {
if (res.confirm) {
that.openBluetoothAdapter();
} else if (res.cancel) {
console.log('用户点击取消');
that.openBluetoothAdapter();
}
}
})
console.log(err, "初始化蓝牙适配器失败");
}
})
},
// 开始搜索蓝牙设备
startBluetoothDevicesDiscovery() {
var that = this;
wx.startBluetoothDevicesDiscovery({
success: function (res) {
console.log("蓝牙搜索中...");
wx.showLoading({
title: '设备搜索中',
})
setTimeout(function(){
wx.hideLoading()
},2000);
that.getBluetoothDevices();
var timer = setInterval(() => {
that.getBluetoothDevices();
},2000);
that.setData({
timer:timer
})
}
})
},
//获取已发现的蓝牙设备列表
getBluetoothDevices() {
var that = this;
wx.getBluetoothDevices({
success: function (res) {
var list = [];
res.devices.forEach(item => {
if(typeof(item.advertisServiceUUIDs) != "undefined" && item.advertisServiceUUIDs[0] == that.data.UUID){
// clearInterval(that.data.timer);
// that.stopBluetoothDevicesDiscovery();
// that.createBLEConnection(item.deviceId);
list.push(item);
}
});
that.setData({
deviceList:list
})
}
})
},
//停止搜索设备
stopBluetoothDevicesDiscovery() {
wx.stopBluetoothDevicesDiscovery({
success: function (res) {
console.log("停止搜索设备" + JSON.stringify(res.errMsg))
}
})
},
connectFail(){
wx.hideLoading({
success: (res) => {
wx.showToast({
title: '连接失败',
icon: "none"
})
},
})
},
//创建蓝牙连接
createBLEConnection(deviceId) {
console.log(deviceId);
var that = this;
var device_list = that.data.deviceList;
var item = null;
for(var i in device_list){
if(deviceId == device_list[i].deviceId){
item = device_list[i];
break;
}
}
if(!item){
wx.showToast({
icon:"none",
title: '找不到设备信息',
})
return;
}else{
var mac = that.buf2hex(item.advertisData);
console.log(mac);
that.setData({
devMac:mac,
deviceNum:item.localName
})
}
wx.showLoading({
title: '设备连接中',
duration: 99999,
mask: true
})
wx.createBLEConnection({
deviceId: deviceId,
success: function () {
that.setData({
"deviceId":deviceId
})
wx.getBLEDeviceServices({
deviceId: deviceId,
success: function () {
that.getBLEDeviceCharacteristics()
},
fail: function (err) {
that.connectFail();
console.log(err, "蓝牙连接失败getBLEDeviceServices");
}
})
},
fail: function (err) {
that.connectFail();
console.log(err, "蓝牙连接失败createBLEConnection");
}
})
},
// 获取该服务的特征值
getBLEDeviceCharacteristics() {
var that = this;
wx.getBLEDeviceCharacteristics({
deviceId: that.data.deviceId,
serviceId: that.data.serviceId,
success: function (res) {
console.log(res);
that.notifyBLECharacteristicValueChange(that.data.deviceId, that.data.serviceId, that.data.readCharacteristic);
},
fail: function (err) {
that.connectFail();
console.log(err, "获取该服务失败getBLEDeviceCharacteristics");
}
})
},
// 监听蓝牙返回值
notifyBLECharacteristicValueChange(deviceId, serviceId, characteristicId) {
var that = this;
wx.notifyBLECharacteristicValueChange({
deviceId: deviceId,
serviceId: serviceId,
characteristicId: characteristicId,
state: true,
success: function (res) {
console.log('使能成功', res);
wx.showToast({
icon: "success",
title: '连接成功',
})
that.onBLECharacteristicValueChange();
let pwd = that.getRandomString(16);
var hex = [];
for(var i in pwd){
hex.push(pwd.charCodeAt(i))
}
hex.unshift(parseInt("01",16));
hex.unshift(parseInt("AE",16));
that.writeBLECharacteristicValue(hex);
var mac = that.data.devMac;
var view_data = that.data.viewData;
mac = that.hexEncode(mac);
mac = mac.splice(2,6);
view_data['dev_mac'] = mac.join(":");
view_data['dev_num'] = that.data.deviceNum
that.setData({
pwdCode:pwd,
isConnect:1,
viewData:view_data,
openBoxShow:"block"
})
},
fail: function (err) {
that.connectFail();
}
})
},
// 获取返回值
onBLECharacteristicValueChange() {
var that = this;
wx.onBLECharacteristicValueChange(function (res) {
var turn_back = that.buf2hex(res.value);
console.log("接收=》"+turn_back);
turn_back = that.hexEncode(turn_back);
switch(turn_back[0]){
case "AE":
case "ae":
switch(Number(turn_back[1])){
case 2://接收到设备加密后的密文,App自己重新加密/解密认证,这是为重新对发出去的明文重新加密
var CryptoJS = require('../../utils/cryptojs-master/cryptojs.js').Crypto;
debugger
var pwdCode = that.data.pwdCode;
var pwdEncode = "";
for(var i=2;i<turn_back.length;i++){
pwdEncode += turn_back[i].toUpperCase();
}
var key = that.hexEncode(that.data.encodeKey);
var new_key = [];
for(let i in key){
new_key.push(parseInt(key[i],16));
}
var mode = new CryptoJS.mode.ECB(CryptoJS.pad.pkcs7);
var bytes = CryptoJS.AES.encrypt(pwdCode, new_key, {
asBpytes: true,
mode: mode
});
var encryptResult = wx.base64ToArrayBuffer(bytes);
encryptResult = that.buf2hex(encryptResult);
encryptResult = encryptResult.substr(0,32).toUpperCase();
//App自己加密密文与设备返回密文相同则为成功
if(pwdEncode == encryptResult){
console.log("第一遍认证成功");
}else{
//TODO:断开蓝牙连接
}
break;
case 3://接收到设备测试指令,App加密后返回设备进行认证
var CryptoJS = require('../../utils/cryptojs-master/cryptojs.js').Crypto;
var pwdEncode = "";
for(var i=2;i<turn_back.length;i++){
pwdEncode += turn_back[i].toUpperCase();
}
pwdEncode = that.hexEncode(pwdEncode);
for(var i in pwdEncode){
pwdEncode[i] = parseInt(pwdEncode[i],16);
}
var key = that.hexEncode(that.data.encodeKey);
var new_key = [];
for(let i in key){
new_key.push(parseInt(key[i],16));
}
var mode = new CryptoJS.mode.ECB(CryptoJS.pad.pkcs7);
var bytes = CryptoJS.AES.encrypt(pwdEncode, new_key, {
asBpytes: true,
mode: mode
});
var encryptResult = wx.base64ToArrayBuffer(bytes);
encryptResult = that.buf2hex(encryptResult);
encryptResult = encryptResult.substr(0,32).toUpperCase();
encryptResult = that.hexEncode(encryptResult);
console.log(encryptResult);
var hex = [];
for(var i in encryptResult){
hex.push(parseInt(encryptResult[i],16))
}
hex.unshift(parseInt("04",16));
hex.unshift(parseInt("AE",16));
that.writeBLECharacteristicValue(hex);//返回App加密后的指令
}
break;
case "BB":
case "bb":
var view_data = that.data.viewData;
switch(turn_back[1]){
case '01'://设置编号
wx.showToast({
title: '写入成功',
})
var num = "";
for(var i=2;i<turn_back.length;i++){
num += turn_back[i];
}
var dev_num = that.hex2str(num);
view_data['dev_num'] = dev_num;
that.setData({
viewData:view_data
})
var mac = that.data.devMac;
mac = that.hexEncode(that.data.devMac);
mac = mac.splice(2,6).join(":");
wx.request({
url: app.globalData.serverInfo.gateWayUrl,
method:'POST',
data:{
'api_name':'update_device_mac',
'dev_id': that.data.deviceInfo.dev_id,
'dev_mac': mac,
'login_manager_id':1
},
success:function(ret){
console.log(ret);
setTimeout(function(){
if(Number(ret.data.state) == 1){
wx.showToast({
title: '上报成功',
})
}else{
wx.showToast({
title: '上报失败',
})
}
},500)
}
})
break;
case '05'://读取设备库存
var data = turn_back[Number(turn_back.length-1)];
data = parseInt(data,16);
data = data.toString(2).padStart(8,'0');
view_data['dev_stock'] = data;
break;
case '06'://电量返回
var power = turn_back[Number(turn_back.length-1)];
power = parseInt(power,16)/10+"V";
view_data['dev_power'] = power;
break;
case "07"://格子数
if(Number(turn_back.length) == 13){
var lat_num = turn_back[Number(turn_back.length-1)];
lat_num = parseInt(lat_num,16);
view_data['dev_lat'] = lat_num;
}
break;
case "09"://配置取货码
wx.hideLoading();
wx.showToast({
title: '写入成功',
})
break;
case "0A"://配置取货码
wx.hideLoading();
wx.showToast({
title: '写入成功',
})
break;
}
that.setData({
viewData:view_data
})
break;
}
}, function (err) {
console.log(err)
})
},
// 发送指令API
writeBLECharacteristicValue(hex){
var that = this;
var buffer = new ArrayBuffer(Number(hex.length));
if(hex){
for(var i in hex){
new DataView(buffer).setInt8(Number(i),hex[i]);
}
}else{
console.log("未输入指令");
return;
}
console.log("发送=》"+that.buf2hex(buffer));
wx.writeBLECharacteristicValue({
deviceId: that.data.deviceId,
serviceId: that.data.serviceId,
characteristicId: that.data.writeCharacteristic,
value: buffer,
success: function (res) {
console.log("发送指令成功")
},
fail: function (err) {
console.log("指令发送失败", err)
}
})
},
closeBluetoothAdapter() {
wx.closeBluetoothAdapter({
success(res) {
console.log("断开蓝牙模块", res);
}
})
},
closeBLEConnection() {
var that = this;
wx.closeBLEConnection({
deviceId: that.data.deviceId,
success(res) {
console.log("断开蓝牙连接", res);
that.setData({
isConnect:0,
openBoxShow:"none"
})
wx.showToast({
title: '已断开连接',
icon:"none"
})
}
})
},
buf2hex: function (buffer) { // buffer is an ArrayBuffer
return Array.prototype.map.call(new Uint8Array(buffer), x => ('00' + x.toString(16)).slice(-2)).join('');
},
// 16进制转字符串
hex2str(hex) {
var rawStr = hex.substr(0, 2).toLowerCase() === "0x" ? hex.substr(2) : hex;
var len = rawStr.length;
if (len % 2 !== 0) {
console.log("Illegal Format ASCII Code!");
return "";
}
var curCharCode;
var resultStr = [];
for (var i = 0; i < len; i = i + 2) {
curCharCode = parseInt(rawStr.substr(i, 2), 16);
resultStr.push(String.fromCharCode(curCharCode));
}
return resultStr.join("");
},
// 字符串转16进制
str2hex(str) {
if (str === "") {
return "";
}
var arr = [];
// arr.push("0x");
for (var i = 0; i < str.length; i++) {
arr.push(str.charCodeAt(i).toString(16));
}
return arr.join('');
},
buf2hex: function (buffer) { // buffer is an ArrayBuffer
return Array.prototype.map.call(new Uint8Array(buffer), x => ('00' + x.toString(16)).slice(-2)).join('');
},
// 16进制转字符串
hex2str(hex) {
var rawStr = hex.substr(0, 2).toLowerCase() === "0x" ? hex.substr(2) : hex;
var len = rawStr.length;
if (len % 2 !== 0) {
console.log("Illegal Format ASCII Code!");
return "";
}
var curCharCode;
var resultStr = [];
for (var i = 0; i < len; i = i + 2) {
curCharCode = parseInt(rawStr.substr(i, 2), 16);
resultStr.push(String.fromCharCode(curCharCode));
}
return resultStr.join("");
},
// 字符串转16进制
str2hex(str) {
if (str === "") {
return "";
}
var arr = [];
// arr.push("0x");
for (var i = 0; i < str.length; i++) {
arr.push(str.charCodeAt(i).toString(16));
}
return arr.join('');
},
hexEncode(hex){
let hex_arr = [];
for(let i=0;i<hex.length;i+=2){
hex_arr.push(hex.substr(i,2).toUpperCase());
}
return hex_arr;
},
//生成随机字符串
getRandomString(len,chars = 'qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM1234567890') {
len = len || 16;
var maxPos = chars.length;
var pwd = '';
for (let i = 0; i < len; i++) {
pwd += chars.charAt(Math.floor(Math.random() * maxPos));
}
return pwd;
},
formSubmit(e){
console.log(e);
var that = this;
var type = e.detail.target.dataset.type;
var data = e.detail.value;
switch(type){
case "dev_num":
that.setDevNum(data.dev_num);
break;
case "lat_1_code":
that.setSetGoodsCode(1,data.lat_1_code);
break;
case "lat_2_code":
that.setSetGoodsCode(1,data.lat_2_code);
break;
case "lat_3_code":
that.setSetGoodsCode(1,data.lat_3_code);
break;
case "lat_4_code":
that.setSetGoodsCode(1,data.lat_4_code);
break;
case "manager_code":
case "stock_code":
that.setSetManagerCode(data.stock_code,data.manager_code);
break;
case "charge":
that.setChargeTime(Number(data.charge_time));
break;
case "codes":
var that = this;
var times = 0;
var timer;
timer = setInterval(function(){
switch(times){
case 0:
that.setSetGoodsCode(1,data['lat_1_code']);
break;
case 1:
that.setSetGoodsCode(2,data['lat_2_code']);
break;
case 2:
that.setSetGoodsCode(3,data['lat_3_code']);
break;
case 3:
that.setSetGoodsCode(4,data['lat_4_code']);
break;
case 4:
that.setSetManagerCode(data['stock_code'],data['manager_code']);
break;
}
times++
},300);
break;
}
},
//自动生成密码
generatePass(){
var that = this;
var chars = "1234";
var view_data = that.data.viewData;
var code = [];
for(var i=0;i<6;i++){
code.push(that.getRandomString(8,chars));
}
view_data['lat_1_code'] = code[0];
view_data['lat_2_code'] = code[1];
view_data['lat_3_code'] = code[2];
view_data['lat_4_code'] = code[3];
view_data['manager_code'] = code[4];
view_data['stock_code'] = code[5];
wx.showToast({
title: '生成成功',
})
that.setData({
viewData:view_data
})
},
/**
* 扫描设备二维码
*/
scanQrCode(){
var that = this;
wx.scanCode({
scanType:"qrCode",
success (res) {
var scan_url = res.result;
var thisDevNo = scan_url.replace(app.globalData.serverInfo.qrReplaceUrl, '');
if(thisDevNo != "" ){
wx.showLoading({
title: '查询中',
})
wx.request({
url: app.globalData.serverInfo.gateWayUrl,
method:'POST',
data:{
'api_name':'find_device',
'dev_no': thisDevNo
},
success:function(ret){
wx.hideLoading();
if(Number(ret.data.state) === 1){
var view_data = that.data.viewData;
var open_box_show = that.data.openBoxShow;
if(open_box_show != "block"){
var device_list = that.data.deviceList;
var flag = false;
for(var i in device_list){
if(device_list[i].localName == thisDevNo){
flag = true;
wx.showModal({
title:"温馨提示",
content:"是否连接该设备?",
success (res) {
if (res.confirm) {
that.createBLEConnection(device_list[i].deviceId);
} else if (res.cancel) {
}
}
})
break;
}
}
if(!flag){
wx.showToast({
icon:"none",
"title":"设备不在附近"
})
}
}else{
view_data['dev_num'] = thisDevNo;
}
that.setData({
deviceInfo:ret.data.data,
viewData:view_data
})
}else{
wx.showToast({
icon:"none",
title: '设备信息不存在',
})
}
}
})
}
}
})
}
})
\ No newline at end of file
{
"usingComponents": {}
}
\ No newline at end of file
<view id="listWin">
<view id="listBox">
<view id="deviceList">
<view class="deviceItem" wx:if="{{item.localName == '0000000000' || listType == ''}}" bindtap="connectDevice" wx:for="{{deviceList}}" wx:key="k" data-id="{{item.deviceId}}" data-index="{{index}}">
{{item.localName}}|RSSI:{{item.RSSI}}|{{item.deviceId.length>17?'iso':item.deviceId}}
</view>
</view>
<view id="disconnectBtn" bindtap="closeBLEConnection">断开连接</view>
</view>
<view id="listBottom" class="{{listType}}" bindtap="selectDevice">隐藏已注册设备</view>
</view>
<view id="openBox" style="display:{{openBoxShow}}">
<form bindsubmit="formSubmit">
<view class="info_title">基本信息</view>
<view class="info_item">
<view>Mac地址</view>
<input name="dev_mac" value="{{viewData.dev_mac}}" placeholder="Mac地址" disabled="disable"/>
<view class="cb"></view>
</view>
<view class="info_item">
<view>设备编号</view>
<input name="dev_num" value="{{viewData.dev_num}}" placeholder="设备编号"/>
<button formType="submit" data-type="dev_num">写入</button>
<view class="cb"></view>
</view>
<view class="info_item">
<view>电池电量</view>
<input name="dev_power" value="{{viewData.dev_power}}" placeholder="电池电量" disabled="disable"/>
<button bindtap="readPower">读取</button>
<view class="cb"></view>
</view>
<view class="info_item">
<view>货道数量</view>
<input name="dev_lat" value="{{viewData.dev_lat}}" placeholder="货道数量" disabled="disable"/>
<button bindtap="readLatNum">读取</button>
<view class="cb"></view>
</view>
<view class="info_item">
<view>库存状态</view>
<input name="dev_stock" value="{{viewData.dev_stock}}" placeholder="库存状态" disabled="disable"/>
<button bindtap="readDeviceStock">读取</button>
<view class="cb"></view>
</view>
<view class="info_title">密码配置</view>
<view class="info_item">
<view>1号取货码</view>
<input name="lat_1_code" value="{{viewData.lat_1_code}}" placeholder="1号取货码"/>
<button formType="submit" data-type="lat_1_code">写入</button>
<view class="cb"></view>
</view>
<view class="info_item">
<view>2号取货码</view>
<input name="lat_2_code" value="{{viewData.lat_2_code}}" placeholder="2号取货码"/>
<button formType="submit" data-type="lat_2_code">写入</button>
<view class="cb"></view>
</view>
<view class="info_item">
<view>3号取货码</view>
<input name="lat_3_code" value="{{viewData.lat_3_code}}" placeholder="3号取货码"/>
<button formType="submit" data-type="lat_3_code">写入</button>
<view class="cb"></view>
</view>
<view class="info_item">
<view>4号取货码</view>
<input name="lat_4_code" value="{{viewData.lat_4_code}}" placeholder="4号取货码"/>
<button formType="submit" data-type="lat_4_code">写入</button>
<view class="cb"></view>
</view>
<view class="info_item">
<view>管理密码</view>
<input name="manager_code" value="{{viewData.manager_code}}" placeholder="管理密码"/>
<button formType="submit" data-type="manager_code">写入</button>
<view class="cb"></view>
</view>
<view class="info_item">
<view>补货密码</view>
<input name="stock_code" value="{{viewData.stock_code}}" placeholder="补货密码"/>
<button formType="submit" data-type="stock_code">写入</button>
<view class="cb"></view>
</view>
<button class="full_btn" bindtap="generatePass">一键生成</button>
<button class="full_btn" formType="submit" data-type="codes">一键写入</button>
<view class="cb"></view>
<view class="info_title">功能测试</view>
<view class="info_item">
<view>充电时长</view>
<input name="charge_time" value="" placeholder="充电时长(分钟)"/>
<button formType="submit" data-type="charge">开始</button>
<view class="cb"></view>
</view>
<view class="test_btn" bindtap="openLat" data-lat="1">1号柜</view>
<view class="test_btn" bindtap="openLat" data-lat="2">2号柜</view>
<view class="test_btn" bindtap="openLat" data-lat="3">3号柜</view>
<view class="test_btn" bindtap="openLat" data-lat="4">4号柜</view>
<view class="cb"></view>
<view class="test_all_btn" bindtap="openNoStockLat">打开缺货格子</view>
<view class="test_all_btn" bindtap="openAllLat">打开全部格子</view>
</form>
</view>
<image id="scanAndLink" src="../../images/icons/icon(34).png" bindtap="scanQrCode"></image>
\ No newline at end of file
#listWin{
z-index: 10;
position: absolute;
left: 0;
width: 100%;
top: 0;
background-color: #FFFFFF;
}
#listBottom{
width: 100%;
height: 8vw;
line-height: 8vw;
text-align: center;
background-color: #efefef;
text-align: center;
}
.listActive{
background-color: #42A5F5 !important;
color: #FFFFFF;
}
#listBottom image{
width: 8vw;
height: 8vw;
background-size: 100% 100%;
margin: 0 auto;
}
#deviceList{
width: 95%;
padding: 0 2.5%;
height: 20vh;
overflow-y: scroll;
}
.deviceItem{
padding-left: 5vw;
height: 10vw;
line-height: 10vw;
font-size: 4vw;
border-top: 1px solid #efefef;
}
#disconnectBtn{
width: 100%;
height: 10vw;
line-height: 10vw;
font-size: 4.5vw;
font-weight: bold;
text-align: center;
border-top: 1px solid #efefef;
}
#openBox{
position: absolute;
top: 60vw;
left: 0;
width: 100%;
}
.info_title{
width: 90%;
padding: 0 5%;
float: none !important;
margin-top: 15px;
padding-bottom: 5px;
font-weight: bold;
}
.info_item{
width: 90%;
padding: 0 5%;
height: 45px !important;
line-height: 45px !important;
}
.info_item view,.info_item input,.info_item button{
float: left;
}
.info_item view{
width: 22%;
text-align: right;
height: 45px;
line-height: 45px;
}
.info_item input{
width: 45% !important;
text-align: left;
padding: 0 2.5% 0 7.5%;
height: 45px;
line-height: 45px;
}
.info_item button{
width: 20% !important;
text-align: center !important;
font-size: 14px !important;
padding: 0 !important;
background-color: #42A5F5 !important;
color: #FFFFFF !important;
font-weight: auto !important;
height: 25px !important;
line-height: 25px !important;
margin: 10px 0 !important;
}
#scanAndLink{
width: 15vw;
height: 15vw;
position: fixed;
bottom: 5vw;
right: 5vw;
background-size: 100% 100%;
}
.cb{
width: 0 !important;
height: 0 !important;
padding: 0 !important;
margin: 0 !important;
clear: both !important;
}
.full_btn{
width: 32vw !important;
text-align: center !important;
font-size: 14px !important;
padding: 0 !important;
background-color: #42A5F5 !important;
color: #FFFFFF !important;
font-weight: auto !important;
height: 35px !important;
line-height: 35px !important;
float: left !important;
margin-left: 12vw !important;
margin-top: 3vw !important;
}
.test_btn{
float: left;
width: 20vw;
text-align: center;
height: 35px;
line-height: 35px;
background-color: #42A5F5;
color: #FFFFFF;
font-size: 14px;
margin-left: 4vw;
border-radius: 5px;
margin-top: 3vw;
}
.test_all_btn{
margin-left: 4vw;
width: 92vw;
border-radius: 5px;
font-size: 14px;
background-color: #42A5F5;
color: #FFFFFF;
text-align: center;
height: 35px;
line-height: 35px;
margin-top: 3vw;
}
.test_all_btn:last-child{
margin-bottom: 30vw;
}
\ No newline at end of file
// pages/deviceDetail/index.js
const app = getApp();
Page({
/**
* 页面的初始数据
*/
data: {
userInfo: wx.getStorageSync('userInfo'),
deviceDetail:{},
deviceId: 0
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
var PageThis = this;
PageThis.setData({
userInfo:wx.getStorageSync('userInfo')
})
var id = options.id;
this.setData({
"deviceId":id
})
this.getDeviceDetail();
},
//**页面跳转 */
navigateTo: function (e) {
var _url = e.currentTarget.dataset.url;
var _id = e.currentTarget.dataset.id;
wx.navigateTo({
url: _url + "?id=" + _id,
})
},
/**获取设备 */
getDeviceDetail:function(){
var PageThis = this;
var id = PageThis.data.deviceId;
wx.request({
url: app.globalData.serverInfo.gateWayUrl,
header: {
'content-type': 'application/json'
},
method: 'POST',
data:{
api_name: "device_detail",
device_id:id,
login_manager_id: PageThis.data.userInfo.manager_id
},
success:function(res){
for(var i in res.data.data){
if (i != "dev_no_stock_lattice" && (res.data.data[i] == null || res.data.data[i] == "")){
res.data.data[i] = "--";
}
}
PageThis.setData({
"deviceDetail": res.data.data
})
}
})
},
unbindDevice(){
var PageThis = this;
wx.showModal({
title: '温馨提示',
content: '确定要解绑该设备?解绑后将会抹除所有绑定信息',
success:function(res){
if (res.confirm){
wx.request({
url: app.globalData.serverInfo.gateWayUrl,
header: {
'content-type': 'application/json'
},
method: 'POST',
data:{
api_name: "unbind_device",
dev_no:PageThis.data.deviceDetail.dev_no,
login_manager_id: PageThis.data.userInfo.manager_id
},
success:function(res){
wx.showToast({
title: '解绑成功',
})
PageThis.getDeviceDetail();
}
})
}
}
})
}
})
\ No newline at end of file
{
"usingComponents": {}
}
\ No newline at end of file
<view class="info_item">
<view class="info_title">设备号</view>
<view class="info_content">{{deviceDetail.dev_no}}</view>
</view>
<view class="info_item">
<view class="info_title">机型</view>
<view class="info_content">{{deviceDetail.dt_title}}</view>
</view>
<view class="info_item">
<view class="info_title">蓝牙ID</view>
<view class="info_content">{{deviceDetail.dev_mac}}</view>
</view>
<view class="info_item top_line">
<view class="info_title">合伙人</view>
<view class="info_content">{{deviceDetail.partner_nickname}}</view>
</view>
<view class="info_item">
<view class="info_title">酒店管理员</view>
<view class="info_content">{{deviceDetail.hotel_manager_nickname}}</view>
</view>
<view class="info_item">
<view class="info_title">酒店</view>
<view class="info_content">{{deviceDetail.hotel_title}}</view>
</view>
<view class="info_item">
<view class="info_title">房间号</view>
<view class="info_content">{{deviceDetail.dev_hotel_room}}</view>
</view>
<view class="info_item">
<view class="info_title">房间位置</view>
<view class="info_content">{{deviceDetail.dev_room_address}}</view>
</view>
<view class="info_item">
<view class="info_title">商品方案</view>
<view class="info_content">
<span>{{deviceDetail.gp_title}}</span>
<image class="info_content_img" src="../../images/icons/icon(55).png"></image>
</view>
</view>
<view class="info_item top_line">
<view class="info_title">设备状态</view>
<view class="info_content" wx:if="{{deviceDetail.dev_state == 1}}">在线</view>
<view class="info_content" wx:elif="{{deviceDetail.dev_state == 2}}">离线</view>
<view class="info_content" wx:elif="{{deviceDetail.dev_state == 3}}">故障</view>
</view>
<view class="info_item">
<view class="info_title">绑定状态</view>
<view class="info_content" wx:if="{{deviceDetail.dev_hotel_id == 0}}">未绑定</view>
<view class="info_content" wx:else>已绑定</view>
</view>
<view class="info_item">
<view class="info_title">缺货格子</view>
<view class="info_content">
<view class="ball_item" wx:for="{{deviceDetail.dev_no_stock_lattice}}" wx:key="k">{{item.lat_title*1}}</view>
</view>
</view>
<view class="info_item">
<view class="info_title">设备电量</view>
<view class="info_content">
<view class="battery_detail">
<image src="../../images/icons/icon(54).png"></image>
<view>{{deviceDetail.dev_electric_quantity}}%</view>
</view>
</view>
</view>
<view class="main_btn" bindtap="unbindDevice">解绑设备</view>
\ No newline at end of file
.battery_detail{
color: rgb(94,201,72);
float: right;
}
.battery_detail view{
float: left;
}
.battery_detail image{
width: 6vw;
height: 3vw;
background-size: 100% 100%;
float: left;
margin-right: 2vw;
margin-top: 4.8vw;
}
\ No newline at end of file
const app = getApp();
Page({
data: {
userInfo: wx.getStorageSync('userInfo'),
deviceList: [],
search_type: 0,
search_value: "",
bind_value: -1,
state_value: -1,
searchArray: ['酒店','合伙人','设备号'],
apiName:"device_list",
select_arr:[],
selectValue:0,
showSelect:false,
searchBoxHeight:14,
},
onLoad: function (options) {
var type = options.type;
console.log(type);
this.setData({
userInfo:wx.getStorageSync('userInfo')
})
if (type == "undefined" || typeof(type) == "undefined"){
this.setData({
showSelect: false,
searchBoxHeight:14
})
type = "device_list";
}else if(type != "lower_electric_device"){
var select_arr = [];
switch(type){
case "one_month_no_orders_device":
select_arr = ['七天未成交','一月未成交','两月未成交'];
break;
case "three_day_no_rep_device":
select_arr = ['三天未补货','四天未补货','五天未补货','六天未补货','七天未补货'];
break;
case "one_week_no_scan_device":
select_arr = ['一周未扫码','两周未扫码','三周未扫码','一月未扫码','两月未扫码'];
break;
}
this.setData({
select_arr: select_arr,
showSelect: true,
searchBoxHeight:24,
})
}
this.setData({
apiName:type
})
this.getDeviceList();
},
/**页面跳转 */
navigateTo: function (e) {
var _url = e.currentTarget.dataset.url;
var _id = e.currentTarget.dataset.id;
wx.navigateTo({
url: _url + "?id=" + _id,
})
},
/**获取设备列表 */
getDeviceList:function(){
var PageThis = this;
wx.showLoading({
title: '数据加载中',
})
wx.request({
url: app.globalData.serverInfo.gateWayUrl,
header: {
'content-type': 'application/json'
},
method: 'POST',
data: {
api_name: PageThis.data.apiName,
search_type: Number(PageThis.data.search_type)+1,
search_value: PageThis.data.search_value,
time_type:Number(PageThis.data.selectValue)+1,
bind_value: PageThis.data.bind_value,
state_value: PageThis.data.state_value,
login_manager_id: PageThis.data.userInfo.manager_id
},
success: function (res) {
var data = res.data.data;
for(var i in data){
data[i]['show_list'] = "false";
data[i]['hotel_img'] = "../../images/icons/arrow_down.png";
for(var k in data[i].dev_list){
var device_title = "未分配酒店设备";
var rep_nickname = "未分配补货员";
var lattice_arr = [];
for(var x in data[i].dev_list[k].dev_no_stock_lattice){
lattice_arr.push(Number(data[i].dev_list[k].dev_no_stock_lattice[x].lat_title))
}
if (Number(data[i].dev_list[k].dev_hotel_id) > 0 && data[i].dev_list[k].dev_hotel_room != "") {
device_title = data[i].dev_list[k].hotel_title + data[i].dev_list[k].dev_hotel_room;
} else if (data[i].dev_list[k].dev_room_address != "") {
device_title = data[i].dev_list[k].dev_room_address;
}else if(Number(data[i].dev_list[k].dev_hotel_id) > 0){
device_title = "未分配房间设备";
}
if (data[i].rep_nickname != "" && data[i].rep_nickname != null){
rep_nickname = data[i].rep_nickname;
}
var obj = {
"dev_id": data[i].dev_list[k].dev_id,
"dev_no": data[i].dev_list[k].dev_no,
"dev_no_stock_lattice": lattice_arr,
"dev_state": data[i].dev_list[k].dev_state,
"device_title": device_title,
"rep_nickname": rep_nickname
}
data[i].dev_list[k] = obj;
}
}
PageThis.setData({
"deviceList": data
})
wx.hideLoading({
success: (res) => {},
})
}
})
},
changeSearchType:function(e){
var PageThis = this;
var id = e.detail.value;
PageThis.setData({
"search_type": id
})
},
searchValueChange:function(e){
var PageThis = this;
PageThis.setData({
"search_value": e.detail.value
})
},
//扫描二维码
scanCode(){
var PageThis = this;
wx.scanCode({
scanType:"qrCode",
success (res) {
var scan_url = res.result;
var thisDevNo = scan_url.replace(app.globalData.serverInfo.qrReplaceUrl, '');
if(thisDevNo != "" ){
PageThis.setData({
"search_value":thisDevNo,
"search_type":2
})
PageThis.getDeviceList();
}else{
wx.showToast({
title: '无效二维码',
icon:"none"
})
}
}
})
},
hotel_click(e){
var PageThis = this;
var deviceList = PageThis.data.deviceList
var id = e.currentTarget.dataset.id;
var type = e.currentTarget.dataset.type;
for(var i in deviceList){
if(Number(deviceList[i]['hotel_id']) == Number(id)){
if(type == "true"){
deviceList[i]['show_list'] = "false";
deviceList[i]['hotel_img'] = "../../images/icons/arrow_down.png";
}else{
deviceList[i]['show_list'] = "true";
deviceList[i]['hotel_img'] = "../../images/icons/arrow_up.png";
}
}else{
deviceList[i]['show_list'] = "false";
deviceList[i]['hotel_img'] = "../../images/icons/arrow_down.png";
}
}
PageThis.setData({
deviceList:deviceList
})
},
pickerChange:function(e){
var PageThis = this;
var val = e.detail.value;
var name = e.currentTarget.dataset.name;
switch(name){
case "select":
PageThis.setData({
selectValue:val
})
break;
}
},
})
\ No newline at end of file
{
"usingComponents": {}
}
\ No newline at end of file
<view id="search_box" style="height:{{searchBoxHeight}}vw">
<view id="search_content_box">
<view class="select_item">
<picker id="searchPicker" bindchange="changeSearchType" range="{{searchArray}}" value="{{search_type}}">
<image src="../../images/icons/icon(58).png"></image>
<span>{{searchArray[search_type]}}</span>
</picker>
</view>
<image src="../../images/icons/icon(51).png"></image>
<input placeholder="请输入需要搜索的字段" bindinput="searchValueChange"></input>
<image class="input_scan_icon" src="../../images/scan.png" bindtap="scanCode"></image>
</view>
<view id="search_btn" bindtap="getDeviceList">搜索</view>
<view class="cb"></view>
<view class="input_box_item" wx:if="{{showSelect}}">
<view class="input_title">搜索选项</view>
<picker range="{{select_arr}}" data-name="select" style="background-color:rgba(0,0,0,0);padding-left:0;margin-top:0 !important;" bindchange="pickerChange" value="{{selectValue}}">
<input placeholder="{{select_arr[selectValue]}}" disabled="true"></input>
</picker>
</view>
</view>
<view class="hotel_box" wx:for="{{deviceList}}" wx:key="k">
<view class="hotel_name_item" bindtap="hotel_click" data-id="{{item.hotel_id}}" data-type="{{item.show_list}}">
<image src="../../images/icons/hotel.png"></image>
<view class="hotel_name_text">{{item.hotel_title}}[{{item.dev_list.length}}台]</view>
<image class="hotel_name_arrow" src="{{item.hotel_img}}"></image>
<view class="cb"></view>
</view>
<block wx:if="{{item.show_list == 'true'}}">
<view class="hotel_item" wx:for="{{item.dev_list}}" wx:key="k" bindtap="navigateTo" data-id="{{item.dev_id}}" data-url="../deviceDetail/index">
<view>
<view class="hotel_name">{{item.device_title}}</view>
<image src="../../images/icons/icon(45).png"></image>
<view class="cb"></view>
</view>
<view class="hotel_content_item">
<view>缺货格子:</view>
<view class="ball_item" wx:for="{{item.dev_no_stock_lattice}}" wx:key="k1">{{item}}</view>
<view class="cb"></view>
</view>
<view class="hotel_content_item">
<view>设备号:{{item.dev_no}}</view>
<view>{{item.rep_nickname}}</view>
<view class="cb"></view>
</view>
</view>
</block>
</view>
\ No newline at end of file
#search_content_box{
border-radius: 5px;
}
#search_box{
background-color: #FFFFFF;
}
.input_box_item{
position: absolute;
top: 12vw;
left: 0;
width: 100%;
height: 10vw;
background-color: #FFFFFF;
}
.input_box_item picker{
float: left;
width: 31vw;
height: 8vw;
background-color: #FFFFFF;
color: gray;
border-radius: 5px;
margin-top: 2vw !important;
margin-left: 0;
line-height: 8vw;
padding-left: 2vw;
font-size: 3.5vw;
}
.input_box_item input{
background-color: rgb(248,248,248);
padding-left: 2vw;
width: 69.5vw;
height: 8vw !important;
line-height: 8vw !important;
border-radius: 5px;
margin-top: 1vw !important;
}
.input_box_item .input_title{
width: 20vw;
margin-left: 2vw;
height: 100%;
line-height: 10vw;
}
.select_item{
float: left;
width: 18vw;
border-right: 1px solid rgb(248,248,248);
height: 6vw;
margin: 1.5vw 0;
position: relative;
}
#searchPicker{
width: 100%;
height: 100%;
position: absolute;
left: 0;
top: 0;
z-index: 10;
}
.select_item span{
float: right;
font-size: 3.5vw;
height: 100%;
line-height: 6vw;
color: #999999;
margin-left: 2vw;
text-align: right;
}
.select_item image{
float: right !important;
width: 2vw !important;
height: 2vw !important;
background-size: 100% 100%;
margin-top: 2vw !important;
margin-left: 1vw !important;
}
.select_box{
width: 100%;
border-bottom: 1px solid rgb(248,248,248);
height: 12vw;
}
.select_box .select_item{
width: calc(100vw/3);
border: none;
color: #999999;
font-size: 3.5vw;
}
.select_box .select_item span{
margin-top: 1.5vw !important;
margin-left: 12vw !important;
float: left !important;
}
.select_box .select_item image{
margin-top: 3.5vw !important;
float: left !important;
}
.hotel_item{
width: 92vw;
padding: 6vw 4vw;
border-bottom: 1px solid rgb(248,248,248);
color: #999999;
font-size: 3.5vw;
}
.hotel_item image{
width: 6vw;
height: 6vw;
background-size: 100% 100%;
float: right;
}
.hotel_name{
font-size: 4vw;
font-weight: bold;
float: left;
color: #000000;
}
.hotel_content_item{
margin-top: 2vw;
}
.hotel_content_item view:nth-child(1){
float: left;
}
.hotel_content_item view:nth-child(2){
float: right;
}
.ball_item{
margin-top: 0.5vw !important;
}
\ No newline at end of file
// pages/deviceOrdersCount/index.js
const app = getApp();
Page({
/**
* 页面的初始数据
*/
data: {
scanList:[],
dev_no:"",
hotel_name:"",
start_time:"请选择开始时间",
end_time: "请选择结束时间",
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
this.setData({
userInfo:wx.getStorageSync('userInfo')
})
this.getScanList();
},
pickerChange: function (e) {
var PageThis = this;
var val = e.detail.value;
var name = e.target.dataset.name;
switch (name) {
case "start_time":
PageThis.setData({
start_time: val
})
break;
case "end_time":
PageThis.setData({
end_time: val
})
break;
}
},
getScanList(){
var PageThis = this;
wx.showLoading({
title: '数据加载中',
})
wx.request({
url: app.globalData.serverInfo.gateWayUrl,
header: {
'content-type': 'application/json'
},
method: 'POST',
data: {
api_name: "get_device_scan_list",
dev_no: PageThis.data.dev_no,
hotel_title: PageThis.data.hotel_name,
start_time: PageThis.data.start_time == "请选择开始时间" ? "" : PageThis.data.start_time,
end_time: PageThis.data.end_time == "请选择结束时间" ? "" : PageThis.data.end_time,
login_manager_id: PageThis.data.userInfo.manager_id
},
success:function(res){
wx.hideLoading();
var data = res.data.data;
PageThis.setData({
"scanList": data
})
console.log(data);
}
})
},
reset:function(){
var PageThis = this;
PageThis.setData({
dev_no: "",
hotel_name: "",
start_time: "请选择开始时间",
end_time: "请选择结束时间",
})
}
})
\ No newline at end of file
{
"usingComponents": {}
}
\ No newline at end of file
<view class="input_box_item">
<view class="input_title">设备号</view>
<input placeholder="请输入设备号" data-name="dev_no" value="{{dev_no}}"></input>
</view>
<view class="input_box_item">
<view class="input_title">酒店名称</view>
<input placeholder="请输入酒店名称" data-name="hotel_name" value="{{hotel_name}}"></input>
</view>
<view class="input_box_item">
<view class="input_title">扫码时间</view>
<picker mode="date" fields="day" data-name="start_time" bindchange="pickerChange">
<span>{{start_time}}</span>
</picker>
<view class="link_icon">~</view>
<picker mode="date" fields="day" data-name="end_time" bindchange="pickerChange">
<span>{{end_time}}</span>
</picker>
</view>
<view class="serach_form_btn_box">
<view class="serach_form_btn active" bindtap="getScanList">搜索</view>
<view class="serach_form_btn" bindtap="reset">重置</view>
</view>
<view class="listBox">
<view class="scan_item" wx:for="{{scanList}}" wx:key="k">
<view class="scan_item_top">
<view>{{item.dev_no}}</view>
<view>{{item.hotel_title}} {{item.dev_hotel_room}}</view>
<view class="cb"></view>
</view>
<view class="scan_item_bottom">
<view>{{item.partner_nickname}}</view>
<view>{{item.scan_time}}</view>
<view class="cb"></view>
</view>
</view>
</view>
\ No newline at end of file
picker{
float: left;
width: 31vw;
height: 8vw;
background-color: rgb(248,248,248);
color: gray;
border-radius: 5px;
margin-top: 2vw !important;
margin-left: 0;
line-height: 8vw;
padding-left: 2vw;
font-size: 3.5vw;
}
input{
background-color: rgb(248,248,248);
padding-left: 2vw;
width: 69.5vw;
height: 8vw !important;
line-height: 8vw !important;
border-radius: 5px;
margin-top: 1vw !important;
}
.input_box_item{
width: 100%;
border-bottom: none;
height: 10vw;
line-height: 10vw;
overflow-x: hidden;
}
.input_title{
width: 20vw;
margin-left: 2vw;
height: 100%;
line-height: 10vw;
}
.link_icon{
height: 10vw;
line-height: 10vw;
float: left;
padding: 0 2vw;
}
.scan_item{
width: 100%;
padding: 3vw 0;
border-bottom: 1px solid #EEEEEE;
line-height: 8vw;
}
.scan_item:nth-child(1){
border-top: 1px solid #EEEEEE;
}
.scan_item_top{
width: 100%;
font-size: 3.5vw;
}
.scan_item_bottom{
width: 100%;
font-size: 3vw;
color: #666666;
}
.scan_item_top view:nth-child(1),.scan_item_bottom view:nth-child(1){
margin-left: 10vw;
float: left;
}
.scan_item_top view:nth-child(2),.scan_item_bottom view:nth-child(2){
text-align: right;
margin-right: 5vw;
float: right;
}
\ No newline at end of file
// pages/deviceSalesStatistics/index.js
const app = getApp();
Page({
data: {
userInfo: wx.getStorageSync('userInfo'),
start_time: "请选择开始时间",
end_time: "请选择结束时间",
hotelValue: [], //酒店列表数组
hotelIndex:0, //酒店列表数组picker选中【键值】
hotelId: 0,//存储的酒店ID
userName:"",
device_list: [],
devNo:"",
total_orders_money: 0,
total_orders_goods: 0,
total_scan_num:0,
device_number:0
},
onLoad: function (options) {
var PageThis = this;
PageThis.setData({
userInfo:wx.getStorageSync('userInfo')
})
this.getData();
this.getHotelList();
},
getData: function () {
var PageThis = this;
wx.request({
url: app.globalData.serverInfo.gateWayUrl,
header: {
'content-type': 'application/json'
},
method: 'POST',
data: {
api_name: "device_data_count",
dev_no: PageThis.data.devNo,
hotel_id: PageThis.data.hotelId,
start_time: PageThis.data.start_time == "请选择开始时间" ? "" : PageThis.data.start_time,
end_time: PageThis.data.end_time == "请选择结束时间" ? "" : PageThis.data.end_time,
login_manager_id: PageThis.data.userInfo.manager_id,
username:PageThis.data.userName
},
success: function (res) {
var res = res.data;
if (res.state == 1) {
PageThis.setData({
"total_orders_money": res.data.total_orders_money,
"total_orders_goods": res.data.total_orders_goods,
"total_scan_num": res.data.total_scan_num,
"device_number": res.data.device_number,
"device_list": res.data.device_list
})
}else{
PageThis.setData({
"total_orders_money": 0,
"total_orders_goods": 0,
"total_scan_num": 0,
"device_number": 0,
"device_list": ""
})
}
}
})
},
getHotelList: function () {
var PageThis = this;
wx.request({
url: app.globalData.serverInfo.gateWayUrl,
header: {
'content-type': 'application/json'
},
method: 'POST',
data: {
api_name: "hotel_list_value",
login_manager_id: PageThis.data.userInfo.manager_id
},
success: function (res) {
var data = res.data.data;
PageThis.setData({
"hotelValue": data
})
}
})
},
inputChange:function(e){
var PageThis = this;
var name = e.currentTarget.dataset.name;
switch(name){
case "devNo":
PageThis.setData({
"devNo":e.detail.value
})
break;
case "userName":
PageThis.setData({
"userName":e.detail.value
})
break;
}
},
pickerChange: function (e) {
var PageThis = this;
var val = e.detail.value;
var name = e.target.dataset.name;
switch (name) {
case "start_time":
PageThis.setData({
start_time: val
})
break;
case "end_time":
PageThis.setData({
end_time: val
})
break;
case "hotel":
//hotelIndex存储picker选中【键值】
//hotelId存储picker选中【h_id】
PageThis.setData({
hotelIndex: e.detail.value,
hotelId: this.data.hotelValue[e.detail.value].h_id
})
break;
}
},
reset: function () {
var PageThis = this;
PageThis.setData({
start_time: "请选择开始时间",
end_time: "请选择结束时间",
hotelName: "请选择酒店",
hotelId: 0,
devNo: ""
})
}
})
\ No newline at end of file
{
"usingComponents": {}
}
\ No newline at end of file
<view class="input_box_item">
<view class="input_title">设备号</view>
<input placeholder="请输入设备号" value="{{devNo}}" data-name="devNo" bindinput="inputChange"></input>
</view>
<view class="input_box_item">
<view class="input_title">酒店</view>
<picker range="{{hotelValue}}" value="{{hotelIndex}}" range-key="h_title" data-name="hotel" style="background-color:rgba(0,0,0,0);padding-left:0;margin-top:0 !important;" bindchange="pickerChange">
<input placeholder="{{hotelValue[hotelIndex].h_title}}" disabled="true"></input>
</picker>
</view>
<view class="input_box_item">
<view class="input_title">用户名</view>
<input placeholder="请输入用户名" value="{{userName}}" data-name="userName" bindinput="inputChange"></input>
</view>
<view class="input_box_item">
<view class="input_title">交易时间</view>
<picker mode="date" fields="day" data-name="start_time" bindchange="pickerChange">
<span>{{start_time}}</span>
</picker>
<view class="link_icon">~</view>
<picker mode="date" fields="day" data-name="end_time" bindchange="pickerChange">
<span>{{end_time}}</span>
</picker>
</view>
<view class="serach_form_btn_box">
<view class="serach_form_btn active" bindtap="getData">搜索</view>
<view class="serach_form_btn" bindtap="reset">重置</view>
</view>
<view class="data_box">
<view class="data_item">
<view>{{device_number}}</view>
<view>运营设备数</view>
</view>
<view class="data_item">
<view>{{total_orders_money}}</view>
<view>总成交额</view>
</view>
<view class="data_item">
<view>{{total_orders_goods}}</view>
<view>总成交量</view>
</view>
<view class="data_item">
<view>{{total_scan_num}}</view>
<view>总扫码量</view>
</view>
</view>
<view class="device_statistics_list">
<view class="device_statistics_item" wx:for="{{device_list}}" wx:key="k">
<view>{{item.dev_no}}</view>
<view>{{item.hotel_title}} {{item.dev_hotel_room}}</view>
<view>成交金额(元):<span class="blue_color">{{item.total_orders_money}}</span></view>
<view>扫码次数(次):<span class="blue_color">{{item.total_scan_num}}</span></view>
<view>成交数量(次):<span class="blue_color">{{item.total_orders_num}}</span></view>
<!-- <view>在线时长:<span class="blue_color">一直在线</span></view> -->
<view>所属合伙人:<span class="blue_color">{{item.partner_nickname}}</span></view>
<view class="cb"></view>
</view>
</view>
\ No newline at end of file
picker{
float: left;
width: 31vw;
height: 8vw;
background-color: rgb(248,248,248);
color: #999999;
border-radius: 5px;
margin-top: 2vw !important;
margin-left: 0;
line-height: 8vw;
padding-left: 2vw;
font-size: 3.5vw;
}
input{
background-color: rgb(248,248,248);
padding-left: 2vw;
width: 69.5vw;
height: 8vw !important;
line-height: 8vw !important;
border-radius: 5px;
margin-top: 1vw !important;
}
.input_box_item{
width: 100%;
border-bottom: none;
height: 10vw;
line-height: 10vw;
}
.input_title{
width: 20vw;
margin-left: 2vw;
height: 100%;
line-height: 10vw;
}
.link_icon{
height: 10vw;
line-height: 10vw;
float: left;
padding: 0 2vw;
}
.data_box{
width: calc(90vw + 3px);
height: 24vw;
border-radius: 15px;
background-image: linear-gradient(90deg, #77adff 0%, #387ee8 100%);
color: #FFFFFF;
margin: 8vw auto;
}
.data_item{
width: calc(90vw / 4);
text-align: center;
float: left;
margin-top: 5vw;
}
.data_item:nth-child(2){
border-left: 1px solid rgb(128, 174, 248);
border-right: 1px solid rgb(106,160,245);
}
.data_item:nth-child(3){
border-right: 1px solid rgb(106,160,245);
}
.data_item view:nth-child(1){
font-size: 4.5vw;
height: 8vw;
line-height: 8vw;
}
.data_item view:nth-child(2){
font-size: 3vw;
height: 6vw;
line-height: 6vw;
}
.device_statistics_list{
width: 100%;
border-top: 3vw solid rgb(248,248,248);
}
.device_statistics_item{
color: #999999;
font-size: 3.5vw;
width: 94vw;
padding: 3vw;
border-bottom: 1px solid rgb(248,248,248);
}
.device_statistics_item view{
width: 50%;
float: left;
height: 8vw;
line-height: 8vw;
}
.device_statistics_item view:nth-child(1){
font-size: 4vw;
color: #000000;
}
.device_statistics_item view:nth-child(2){
color: #000000;
}
.device_statistics_item view:nth-child(2n){
text-align: right;
}
.blue_color{
color: rgb(55,126,232) !important;
}
\ No newline at end of file
const app = getApp()
Page({
data: {
listData: [
{
icon: '../../images/icons/icon(23).png',
title: '低电量',
url: '../deviceList/index?type=lower_electric_device'
},
{
icon: '../../images/icons/icon(13).png',
title: '未成交',
url: '../deviceList/index?type=one_month_no_orders_device'
},
{
icon: '../../images/icons/icon(10).png',
title: '未补货',
url: '../deviceList/index?type=three_day_no_rep_device'
},
{
icon: '../../images/icons/icon(24).png',
title: '未扫码',
url: '../deviceList/index?type=one_week_no_scan_device'
},
{
icon: '../../images/icons/icon(60).png',
title: '蓝牙告警',
url: '../bluetoothWarning/index'
}
]
},
//**页面跳转 */
navigateTo: function (e) {
var _url = e.currentTarget.dataset.url;
wx.navigateTo({
url: _url
})
},
})
\ No newline at end of file
{
"usingComponents": {}
}
\ No newline at end of file
<view id="top_banner">
<image class="banner_img" src="../../images/top_banner/top_banner(6).png"></image>
</view>
<view id="block_item_box">
<view class="block_item" wx:for="{{listData}}" wx:key="k" bindtap="navigateTo" data-url="{{item.url}}">
<image class="block_item_img" src="{{item.icon}}"></image>
<view class="block_item_title">{{item.title}}</view>
</view>
</view>
\ No newline at end of file
/* pages/devicewarning/index.wxss */
\ No newline at end of file
// pages/editPlan/index.js
const app = getApp();
Page({
/**
* 页面的初始数据
*/
data: {
userInfo:[]
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
var PageThis = this;
PageThis.setData({
userInfo:wx.getStorageSync('userInfo')
})
},
/**
* 生命周期函数--监听页面初次渲染完成
*/
onReady: function () {
},
/**
* 生命周期函数--监听页面显示
*/
onShow: function () {
},
/**
* 生命周期函数--监听页面隐藏
*/
onHide: function () {
},
/**
* 生命周期函数--监听页面卸载
*/
onUnload: function () {
},
/**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh: function () {
},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom: function () {
},
/**
* 用户点击右上角分享
*/
onShareAppMessage: function () {
}
})
\ No newline at end of file
{
"usingComponents": {}
}
\ No newline at end of file
<view id="search_box">
<view id="search_content_box">
<image src="../../images/icons/icon(51).png"></image>
<input placeholder="请输入联系人名称或用户名"></input>
</view>
<view id="search_btn">搜索</view>
</view>
<view id="list_box">
<view class="list_item">
<view class="list_title_box">
<view class="list_title">商品001<span class="red_color">*0.01</span></view>
<image class="list_item_icon" src="../../images/icons/icon(46).png"></image>
</view>
<view class="cb"></view>
</view>
<view class="list_item">
<view class="list_title_box">
<view class="list_title">商品001<span class="red_color">*0.01</span></view>
<image class="list_item_icon" src="../../images/icons/icon(42).png"></image>
</view>
<view class="cb"></view>
</view>
</view>
<view class="main_btn">确定</view>
<view class="sec_btn">返回</view>
\ No newline at end of file
.list_title_box{
border: none;
width: 95%;
padding-left: 5%;
}
.list_item{
border-bottom: 1px solid rgb(245, 245, 245);
}
\ No newline at end of file
// pages/getWechat/index.js
const app = getApp()
Page({
/**
* 页面的初始数据
*/
data: {
userInfo: wx.getStorageSync('userInfo'),
canIUse: wx.canIUse('button.open-type.getUserInfo')
},
setBindWechat:function(){
var PageThis = this;
PageThis.getWxSession();
},
getWechatInfo:function(){
var PageThis = this;
PageThis.getWxSession();
},
bindGetUserInfoGo(e) {
var PageThis = this;
console.log(e);
console.log(PageThis.data.session);
wx.setStorage({
key: 'iv',
data: e.detail.iv
})
wx.setStorage({
key: 'encryptedData',
data: e.detail.encryptedData
})
wx.request({
url: app.globalData.serverInfo.gateWayUrl,
data: {
api_name: "sure_bind_wx",
target: app.globalData.ThisWechatTarget,
type: app.globalData.ThisWechatType,
iv: e.detail.iv,
encryptedData: e.detail.encryptedData,
session_key: PageThis.data.session,
login_manager_id: PageThis.data.userInfo.manager_id
},
method: 'POST',
header: { 'content-type': 'application/json' },
success: function (res) {
wx.showToast({
title: res.data.msg,
icon:'none',
duration: 2000
})
}
})
},
getAuthSetting:function(){
// 查看是否授权
wx.getSetting({
success(res) {
if (res.authSetting['scope.userInfo']) {
// 已经授权,可以直接调用 getUserInfo 获取头像昵称
wx.getUserInfo({
success: function (res) {
console.log(res);
wx.setStorage({
key: 'VerificationData',
data: res
})
}
})
}
}
})
},
getWxSession:function(){
var PageThis = this;
wx.login({
success(res) {
if (res.code) {
// 发起网络请求
wx.request({
url: 'https://m.dalvv.com/managerApi',
data: {
code: res.code,
api_name: "get_wx_session",
target: app.globalData.ThisWechatTarget,
type: app.globalData.ThisWechatType,
login_manager_id: PageThis.data.userInfo.manager_id
},
method: 'POST',
header: { 'content-type': 'application/json' },
success: function (res) {
PageThis.setData({
session:res.data.data.session_key
})
}
})
} else {
console.log('登录失败!' + res.errMsg)
}
}
})
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
this.getAuthSetting();
this.setBindWechat();
this.setData({
userInfo:wx.getStorageSync('userInfo')
})
},
/**
* 生命周期函数--监听页面初次渲染完成
*/
onReady: function () {
},
/**
* 生命周期函数--监听页面显示
*/
onShow: function () {
},
/**
* 生命周期函数--监听页面隐藏
*/
onHide: function () {
},
/**
* 生命周期函数--监听页面卸载
*/
onUnload: function () {
},
/**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh: function () {
},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom: function () {
},
/**
* 用户点击右上角分享
*/
onShareAppMessage: function () {
}
})
\ No newline at end of file
{
"usingComponents": {}
}
\ No newline at end of file
<view class="getWechatTitle">绑定须知</view>
<view class="getWechatTip">1.绑定微信之后,可以申请提现到微信零钱.</view>
<view class="getWechatTip">2.如果您不愿意让系统获取您的微信头像昵称等信息,可以不用绑定.</view>
<view class="getWechatTip">3.不绑定微信仍然可以通过银行卡转账的方式进行提现.</view>
<view class="getWechatTip">4.您可以随时解除微信账号绑定.</view>
<view class="getWechatTip">5.您的账号如果是酒店管理员,合伙人,运营人员以外的账户类型,此处不绑定微信,不受任何影响.</view>
<view class="getWechatTip">6.请确认您已经完全知晓上述条款,并选择操作.</view>
<button wx:if="{{canIUse}}" open-type="getUserInfo" bindgetuserinfo="bindGetUserInfoGo" class="btnClass">我已知晓,确认绑定</button>
\ No newline at end of file
/* pages/getWechat/index.wxss */
.getWechatTitle{
font-size: 18px;
font-weight: 600;
padding: 5px 10px;
text-align: center;
margin: 10px auto 5px;
}
.getWechatTip{
font-size: 16px;
padding: 5px 10px;
}
.btnClass{
width: 90%;
height: 45px;
line-height: 45px;
background-color: #07C160;
color: #ffffff;
border-radius: 5px;
margin: 10px auto 0;
}
\ No newline at end of file
// pages/goodsDetail/index.js
const app = getApp();
Page({
data: {
userInfo: wx.getStorageSync('userInfo'),
goodsDetail:{},
goodsId:0
},
onLoad: function (options) {
var id = options.id;
var PageThis = this;
PageThis.setData({
userInfo:wx.getStorageSync('userInfo')
})
this.setData({
"goodsId":id
})
},
onShow:function(){
this.getGoodsDetail();
},
//**页面跳转 */
goodsCopy: function (e) {
var PageThis = this;
var _url = "../updateGoodsDetail/index";
var _id = e.currentTarget.dataset.id;
wx.showModal({
title: '温馨提示',
content: '是否复制该商品',
success (res) {
if (res.confirm) {
wx.request({
url: app.globalData.serverInfo.gateWayUrl,
header: {
'content-type': 'application/json'
},
method: 'POST',
data:{
api_name: "goods_copy",
goods_id: _id,
login_manager_id: PageThis.data.userInfo.manager_id
},
success:function(res){
wx.showToast({
title: res.data.msg,
icon: 'success',
duration: 1500,
})
setTimeout(function(){
wx.navigateTo({
url: _url + "?id=" + res.data.data,
})
},1500);
}
})
} else if (res.cancel) {
console.log('用户点击取消')
}
}
})
},
//**页面跳转 */
navigateTo: function (e) {
var _url = e.currentTarget.dataset.url;
var _id = e.currentTarget.dataset.id;
wx.navigateTo({
url: _url + "?id=" + _id,
})
},
getGoodsDetail:function(){
var PageThis = this;
var id = PageThis.data.goodsId;
wx.request({
url: app.globalData.serverInfo.gateWayUrl,
header: {
'content-type': 'application/json'
},
method: 'POST',
data:{
api_name: "goods_detail",
goods_id: id,
login_manager_id: PageThis.data.userInfo.manager_id
},
success:function(res){
var data = res.data.data;
data['g_pic'] = JSON.parse(data['g_pic']);
if(Number(data['g_money_type']) === 1){
data['g_money_type'] = '营业额分成';
}else{
data['g_money_type'] = '利润分成';
}
PageThis.setData({
"goodsDetail": data
})
}
})
}
})
\ No newline at end of file
{
"usingComponents": {}
}
\ No newline at end of file
<view class="info_item">
<view class="info_title">商品名称</view>
<view class="info_content">{{goodsDetail.g_title}}</view>
</view>
<view class="info_item">
<view class="info_title">商品编号</view>
<view class="info_content">{{goodsDetail.g_no}}</view>
</view>
<view class="info_item">
<view class="info_title">分成方式</view>
<view class="info_content">{{goodsDetail.g_money_type}}</view>
</view>
<view class="info_item">
<view class="info_title">进货价格</view>
<view class="info_content">{{goodsDetail.g_cost_price}}</view>
</view>
<view class="info_item">
<view class="info_title">下级进货价</view>
<view class="info_content">{{goodsDetail.g_son_cost_price}}</view>
</view>
<view class="info_item">
<view class="info_title">销售价格</view>
<view class="info_content">{{goodsDetail.g_sale_price}}</view>
</view>
<view class="info_item info_image_item">
<view class="info_title">商品主图</view>
<view class="cb"></view>
<view class="img_content">
<view class="image_item">
<image src="{{goodsDetail.g_cover}}"></image>
</view>
</view>
<view class="cb"></view>
</view>
<view class="info_item">
<view class="info_title">商品分类</view>
<view class="info_content">{{goodsDetail.c_title}}</view>
</view>
<view class="info_item">
<view class="info_title">商品描述</view>
<view class="info_content">{{goodsDetail.g_introduce}}</view>
</view>
<view class="info_item info_image_item">
<view class="info_title">商品详情</view>
<view class="cb"></view>
<view class="img_content">
<view class="image_item" wx:for="{{goodsDetail.g_pic}}" wx:key="k">
<image src="{{item}}"></image>
</view>
</view>
<view class="cb"></view>
</view>
<view class="main_btn" bindtap="navigateTo" data-id="{{goodsDetail.g_id}}" data-url="../updateGoodsDetail/index">编辑商品</view>
<view class="main_btn sec_btn" data-id="{{goodsDetail.g_id}}" bindtap="goodsCopy" style="margin-bottom: 10vh;" >复制商品</view>
\ No newline at end of file
// pages/goodsList/index.js
const app = getApp();
Page({
data: {
userInfo: wx.getStorageSync('userInfo'),
searchTitle:"",
goodsList:[]
},
onLoad: function (options) {
var PageThis = this;
PageThis.setData({
userInfo:wx.getStorageSync('userInfo')
})
this.getGoodsList();
},
//**页面跳转 */
navigateTo: function (e) {
var _url = e.currentTarget.dataset.url;
var _id = e.currentTarget.dataset.id;
wx.navigateTo({
url: _url + "?id=" + _id,
})
},
/**获取商品列表 */
getGoodsList:function(){
var PageThis = this;
wx.request({
url: app.globalData.serverInfo.gateWayUrl,
header: {
'content-type': 'application/json'
},
method: 'POST',
data:{
api_name: "goods_list",
search_title: PageThis.data.searchTitle,
login_manager_id: PageThis.data.userInfo.manager_id
},
success:function(res){
var data = res.data.data;
console.log(data);
PageThis.setData({
"goodsList": data
});
}
})
},
/**搜索监听 */
changeSearch:function(e){
var PageThis = this;
var title = e.detail.value;
PageThis.setData({
"searchTitle": title
});
}
})
\ No newline at end of file
{
"usingComponents": {}
}
\ No newline at end of file
<view id="search_box">
<view id="search_content_box">
<image src="../../images/icons/icon(51).png"></image>
<input placeholder="请输入商品名称" bindinput="changeSearch"></input>
</view>
<view id="search_btn" bindtap="getGoodsList">搜索</view>
</view>
<view id="list">
<view class="img_list_item" wx:for="{{goodsList}}" wx:key="k" bindtap="navigateTo" data-id="{{item.g_id}}" data-url="../goodsDetail/index">
<image src="{{item.g_cover}}"></image>
<view class="item_text_box">
<view class="item_text" style="font-size:4.5vw">{{item.g_title}}</view>
<view class="item_text" style="color:rgb(138,138,138)">商品编号:{{item.g_no}}</view>
<view class="item_text" style="color:red">¥{{item.g_sale_price}}</view>
</view>
</view>
</view>
<image class="add_btn" src="../../images/icons/icon(33).png" bindtap="navigateTo" data-url="../createGoods/index"></image>
/* pages/goodsList/index.wxss */
\ No newline at end of file
// pages/goodsPlan/index.js
const app = getApp();
Page({
data: {
userInfo: wx.getStorageSync('userInfo'),
planList:[],
search_value: "",
},
onLoad: function (options) {
var PageThis = this;
PageThis.setData({
userInfo:wx.getStorageSync('userInfo')
})
this.getPlanList();
},
//**页面跳转 */
navigateTo: function (e) {
var _url = e.currentTarget.dataset.url;
var _id = e.currentTarget.dataset.id;
wx.navigateTo({
url: _url + "?id=" + _id,
})
},
upDevPlay:function(e){
var PageThis = this;
var _id = e.currentTarget.dataset.id;
wx.request({
url: app.globalData.serverInfo.gateWayUrl,
header: {
'content-type': 'application/json'
},
method: 'POST',
data: {
api_name: "docking_goods_plan",
gp_id: _id,
login_manager_id: PageThis.data.userInfo.manager_id
},
success:function(ret){
wx.showToast({
title: ret.data.msg,
icon: 'none',
duration: 2000
})
}
})
},
getPlanList:function(){
var PageThis = this;
wx.request({
url: app.globalData.serverInfo.gateWayUrl,
header: {
'content-type': 'application/json'
},
method: 'POST',
data: {
api_name: "goods_plan",
search_value: PageThis.data.search_value,
login_manager_id: PageThis.data.userInfo.manager_id
},
success:function(ret){
var data = ret.data.data;
PageThis.setData({
"planList": data
})
}
})
},
searchValueChange: function (e) {
var PageThis = this;
PageThis.setData({
"search_value": e.detail.value
})
},
})
\ No newline at end of file
{
"usingComponents": {}
}
\ No newline at end of file
<view id="search_box">
<view id="search_content_box">
<image src="../../images/icons/icon(51).png"></image>
<input placeholder="请输入方案名称" bindinput="searchValueChange"></input>
</view>
<view id="search_btn" bindtap="getPlanList">搜索</view>
</view>
<view id="list_box">
<view class="list_item" wx:for="{{planList}}" wx:key="k" bindtap="navigateTo" data-url="../goodsPlanDetail/index" data-id="{{item.gp_id}}">
<view class="list_title_box">
<view class="list_title">{{item.gp_title}} <span class="blue_color">({{item.lt_title}})</span></view>
<view class="upDevPlay" data-id="{{item.gp_id}}" catchtap="upDevPlay">同步方案</view>
<image class="list_item_icon" src="../../images/icons/icon(55).png"></image>
</view>
<view class="cb"></view>
</view>
</view>
<image class="add_btn" src="../../images/icons/icon(33).png" bindtap="navigateTo" data-url="../createGoodsPlan/index"></image>
\ No newline at end of file
.list_title_box {
border: none;
width: 95%;
padding-left: 5%;
}
.list_item {
border-bottom: 1px solid rgb(245, 245, 245);
}
.upDevPlay {
background-color: #387EE8;
position: absolute;
top: 0;
right: 10vw;
color: #fff;
padding: 0 2vw;
}
\ No newline at end of file
// pages/goodsPlanDetail/index.js
const app = getApp();
Page({
data: {
userInfo: wx.getStorageSync('userInfo'),
planDetail:{},
planId: 0
},
onLoad: function (options) {
var id = options.id;
var PageThis = this;
PageThis.setData({
userInfo:wx.getStorageSync('userInfo')
})
this.setData({
"planId": id
})
},
onShow: function () {
this.getGoodsPlanDetail();
},
//**页面跳转 */
navigateTo: function (e) {
var _url = e.currentTarget.dataset.url;
var _id = e.currentTarget.dataset.id;
wx.navigateTo({
url: _url + "?id=" + _id,
})
},
getGoodsPlanDetail:function(){
var PageThis = this;
var id = PageThis.data.planId;
wx.request({
url: app.globalData.serverInfo.gateWayUrl,
header: {
'content-type': 'application/json'
},
method: 'POST',
data: {
api_name: "goods_plan_detail",
gp_id: id,
login_manager_id: PageThis.data.userInfo.manager_id
},
success:function(res){
console.log(res);
var data = res.data.data
console.log(data);
PageThis.setData({
"planDetail":data
})
}
})
}
})
\ No newline at end of file
{
"usingComponents": {}
}
\ No newline at end of file
<view class="info_item">
<view class="info_title">方案名称</view>
<view class="info_content">{{planDetail.gp_title}}</view>
</view>
<view class="info_item">
<view class="info_title">格子机型</view>
<view class="info_content">{{planDetail.lt_title}}</view>
</view>
<view class="top_line"></view>
<view class="info_item" wx:for="{{planDetail.gp_content}}" wx:key="k" wx:for-index="index">
<view class="info_title">{{index+1}}号格子</view>
<view class="info_plan">{{item.plan_goods_title}}</view>
<view class="info_price">{{item.plan_goods_price}}元</view>
</view>
<view class="main_btn" bindtap="navigateTo" data-id="{{planDetail.gp_id}}" data-url="../updateGoodsPlan/index">编辑方案</view>
<!-- <view class="main_btn sec_btn">复制方案</view>
<view class="main_btn thi_btn">分配方案</view>
<view class="main_btn four_btn">同步方案</view> -->
\ No newline at end of file
/* pages/goodsPlanDetail/index.wxss */
.info_price {
float: right;
text-align: right;
}
.info_title {
width: calc(92vw / 3);
overflow:hidden; /*内容超出宽度时隐藏超出部分的内容 */
text-overflow:ellipsis;/* 当对象内文本溢出时显示省略标记(...) ;需与overflow:hidden;一起使用。*/
white-space:nowrap; /*不换行 */
}
.info_plan {
width: calc(92vw / 3);
overflow:hidden; /*内容超出宽度时隐藏超出部分的内容 */
text-overflow:ellipsis;/* 当对象内文本溢出时显示省略标记(...) ;需与overflow:hidden;一起使用。*/
white-space:nowrap; /*不换行 */
}
.info_price {
width: calc(92vw / 3);
overflow:hidden; /*内容超出宽度时隐藏超出部分的内容 */
text-overflow:ellipsis;/* 当对象内文本溢出时显示省略标记(...) ;需与overflow:hidden;一起使用。*/
white-space:nowrap; /*不换行 */
}
.info_content{
width: calc(92vw - (92vw / 3));
overflow:hidden; /*内容超出宽度时隐藏超出部分的内容 */
text-overflow:ellipsis;/* 当对象内文本溢出时显示省略标记(...) ;需与overflow:hidden;一起使用。*/
white-space:nowrap; /*不换行 */
}
\ No newline at end of file
// pages/goodsSalesStatistics/index.js
const app = getApp();
Page({
data: {
userInfo: wx.getStorageSync('userInfo'),
start_time:"请选择开始时间",
end_time: "请选择结束时间",
total_orders_goods: 0,
total_orders_money: 0,
goodsList:[],
hotelValue: [], //酒店列表数组
hotelIndex:0, //酒店列表数组picker选中【键值】
hotelId: 0,//存储的酒店ID
radioList:[
{
"name":"否",
"value":1,
"checked":true
},
{
"name":"是",
"value":2,
"checked":false
}
]
},
getHotelList: function () {
var PageThis = this;
wx.request({
url: app.globalData.serverInfo.gateWayUrl,
header: {
'content-type': 'application/json'
},
method: 'POST',
data: {
api_name: "hotel_list_value",
login_manager_id: PageThis.data.userInfo.manager_id
},
success: function (res) {
var data = res.data.data;
PageThis.setData({
"hotelValue": data
})
}
})
},
onLoad: function (options) {
var PageThis = this;
PageThis.setData({
userInfo:wx.getStorageSync('userInfo')
})
this.getData();
this.getHotelList();
},
getData:function(){
var PageThis = this;
wx.request({
url: app.globalData.serverInfo.gateWayUrl,
header: {
'content-type': 'application/json'
},
method: 'POST',
data: {
api_name: "goods_data_count",
start_time: PageThis.data.start_time == "请选择开始时间" ? "" : PageThis.data.start_time,
end_time: PageThis.data.end_time == "请选择结束时间" ? "" : PageThis.data.end_time,
login_manager_id: PageThis.data.userInfo.manager_id,
hotel_id: PageThis.data.hotelId
},
success:function(res){
var res = res.data;
if(res.state == 1){
PageThis.setData({
"total_orders_money": res.data.total_orders_money,
"total_orders_goods": res.data.total_orders_goods,
"goodsList": res.data.goods_list
})
}else{
PageThis.setData({
"total_orders_money": 0,
"total_orders_goods": 0,
"goodsList": []
})
}
}
})
},
pickerChange: function (e) {
var PageThis = this;
var val = e.detail.value;
var name = e.target.dataset.name;
switch (name) {
case "start_time":
PageThis.setData({
start_time: val
})
break;
case "end_time":
PageThis.setData({
end_time: val
})
break;
case "hotel":
//hotelIndex存储picker选中【键值】
//hotelId存储picker选中【h_id】
PageThis.setData({
hotelIndex: e.detail.value,
hotelId: this.data.hotelValue[e.detail.value].h_id
})
break;
}
},
radioChange(e){
var PageThis = this;
var goodsInfo = PageThis.data.goodsInfo;
goodsInfo['g_money_type'] = e.detail.value;
PageThis.setData({
"goodsInfo":goodsInfo
})
}
})
\ No newline at end of file
{
"usingComponents": {}
}
\ No newline at end of file
<view class="input_box_item">
<picker mode="date" fields="day" data-name="start_time" bindchange="pickerChange">
<span>{{start_time}}</span>
</picker>
<view class="link_icon">~</view>
<picker mode="date" fields="day" data-name="end_time" bindchange="pickerChange">
<span>{{end_time}}</span>
</picker>
<view class="input_box_btn" bindtap="getData">搜索</view>
</view>
<view class="input_box_item">
<picker range="{{hotelValue}}" value="{{hotelIndex}}" range-key="h_title" data-name="hotel" style="margin-top:8px !important;width:98%;" bindchange="pickerChange">
<span>{{hotelValue[hotelIndex].h_title}}</span>
</picker>
</view>
<view class="data_box">
<view class="data_item">
<view>{{total_orders_money}}</view>
<view>总成交额(元)</view>
</view>
<view class="data_item">
<view>{{total_orders_goods}}</view>
<view>总成交量(件)</view>
</view>
</view>
<view id="list">
<view class="img_list_item" wx:for="{{goodsList}}" wx:key="k">
<image src="{{item.goods_cover}}"></image>
<view class="item_text_box">
<view class="item_text" style="font-size:4.5vw;color:#000000;">{{item.goods_title}}</view>
<view class="item_text">数量:<span class="blue_color">{{item.goods_num}}</span></view>
<view class="item_box">
<view class="item_text">单价:<span class="blue_color">¥{{item.goods_price}}</span></view>
<view class="item_text">总价:<span class="blue_color">¥{{item.goods_money}}</span></view>
</view>
</view>
</view>
</view>
\ No newline at end of file
.input_box_item{
width: 90%;
border-bottom: none;
height: 10vw;
line-height: 10vw;
margin: 0 auto;
}
picker{
float: left;
width: 31vw;
height: 8vw;
background-color: rgb(248,248,248);
color: #999999;
border-radius: 5px;
margin-top: 2vw !important;
margin-left: 0;
line-height: 8vw;
padding-left: 2vw;
font-size: 3.5vw;
}
.link_icon{
height: 10vw;
line-height: 10vw;
float: left;
padding: 0 2vw;
}
.input_box_btn{
width: 12vw;
height: 8vw;
line-height: 8vw;
background-color: rgb(55,126,232);
color: #FFFFFF;
text-align: center;
font-size: 4vw;
border-radius: 5px;
float: right;
margin-top: 2vw;
}
.data_box{
width: calc(90vw + 1px);
height: 30vw;
border-radius: 15px;
background-image: linear-gradient(90deg, #77adff 0%, #387ee8 100%);
color: #FFFFFF;
margin: 8vw auto;
}
.data_item{
width: 45vw;
text-align: center;
float: left;
margin-top: 8vw;
}
.data_item:nth-child(1){
border-right: 1px solid rgb(106,160,245);
}
.data_item view:nth-child(1){
font-size: 6vw;
height: 8vw;
line-height: 8vw;
}
.data_item view:nth-child(2){
font-size: 3.2vw;
height: 6vw;
line-height: 6vw;
}
.item_text_box{
color: #999999;
}
.item_box{
width: 100%;
}
.item_box view:nth-child(1){
float: left;
}
.item_box view:nth-child(2){
float: right;
text-align: right;
margin-right: 8vw;
}
\ No newline at end of file
// pages/handleMessage/index.js
const app = getApp()
Page({
data: {
userInfo:{},
tabList:[],
tab_swiper_index:0,
list:[]
},
onLoad: function (options) {
var item = ["用户反馈","银行卡审核","提现审核","退款审核"];
var list = [];
for(var i in item){
var obj = {
"tabName":item[i],
"tabClass":"",
"tabIndex":i,
"tabContent":[]
}
list.push(obj);
}
list[0]['tabClass'] = "tab_item_active";
this.setData({
userInfo:wx.getStorageSync('userInfo'),
tabList:list
});
},
onShow(){
this.getToDoList();
},
onTabItem(e){
var PageThis = this;
var index = e.currentTarget.dataset.page;
var tabList = PageThis.data.tabList;
for(var i in tabList){
if(Number(tabList[i].tabIndex) === Number(index)){
tabList[i].tabClass = "tab_item_active";
}else{
tabList[i].tabClass = "";
}
}
PageThis.setData({
tab_swiper_index:index,
tabList:tabList
})
},
tabSwiperChange(e){
var PageThis = this;
var index = e.detail.current;
var tabList = PageThis.data.tabList;
for(var i in tabList){
if(Number(tabList[i].tabIndex) === Number(index)){
tabList[i].tabClass = "tab_item_active";
}else{
tabList[i].tabClass = "";
}
}
PageThis.setData({
tab_swiper_index:index,
tabList:tabList
})
},
getToDoList(){
var PageThis = this;
wx.request({
url: app.globalData.serverInfo.gateWayUrl,
header: {
'content-type': 'application/json'
},
method: 'POST',
data: {
api_name: "get_to_do_list",
login_manager_id: PageThis.data.userInfo.manager_id
},
success:function(res){
var data = res.data.data;
app.globalData.handleNum = data.total_number;
PageThis.setData({
list:data
})
}
})
},
handleMessage(e){
var PageThis = this;
var name = e.currentTarget.dataset.name;
var type = e.currentTarget.dataset.type;
var id = e.currentTarget.dataset.id;
var str = "";
var obj = {};
obj.api_name = name;
obj.login_manager_id = PageThis.data.userInfo.manager_id;
if(name == "reply_user_feedback"){
str = "确认已处理该反馈?";
obj.feedback_id = id;
}else if(name == "auth_bank_card"){
if(Number(type) == 2){
str = "确认通过该银行卡申请?";
}else if(Number(type) == 3){
str = "确认驳回该银行卡申请?";
}
obj.card_id = id;
obj.state = type;
}else if(name == "auth_apply_withdraw"){
if(Number(type) == 2){
str = "确认通过该提现申请?";
}else if(Number(type) == 4){
str = "确认驳回该提现申请?";
}
obj.w_id = id;
obj.state = type;
obj.target = app.globalData.ThisWechatTarget;
obj.type = app.globalData.ThisWechatType;
}else if(name == "auth_refund_orders"){
if(Number(type) == 1){
str = "确认通过该退款申请?";
}else if(Number(type) == 2){
str = "确认驳回该退款申请?";
}
obj.pay_id = id;
obj.result = type;
}else{
wx.showToast({
title: '未知类型',
icon: "none"
})
return;
}
wx.showModal({
title: '温馨提示',
content: str,
success(r){
if(r.confirm){
wx.request({
url: app.globalData.serverInfo.gateWayUrl,
header: {
'content-type': 'application/json'
},
method: 'POST',
data: obj,
success(res){
var ret = res.data;
if(Number(ret.state) === 1){
wx.showToast({
title: ret.msg,
})
PageThis.getToDoList();
}else{
wx.showToast({
title: ret.msg,
icon: 'none'
})
}
}
})
}
}
})
}
})
\ No newline at end of file
{
"usingComponents": {}
}
\ No newline at end of file
<view class="tab_box">
<view wx:for="{{tabList}}" wx:key="k" class="tab_item {{item.tabClass}}" bindtap="onTabItem" data-page="{{item.tabIndex}}">{{item.tabName}}</view>
</view>
<swiper class="tab_swiper" bindchange="tabSwiperChange" current="{{tab_swiper_index}}">
<swiper-item class="tab_swiper_item feedback_list">
<view class="message_box" wx:for="{{list.feedback_list}}" wx:key="k">
<view class="message_top">
<view>{{item.feedback_time}}</view>
<view>待处理</view>
<view class="cb"></view>
</view>
<view class="message_content">
<image src="../../images/icons/wechat.png"></image>
<view class="message_content_text">
<view>设备号:</view>
<view>{{item.feedback_dev_no}}</view>
<view>酒店:{{item.hotel_title}}</view>
<view>反馈信息:{{item.feedback_content}}</view>
</view>
<view class="message_content_right">{{item.feedback_mobile}}</view>
<view class="cb"></view>
</view>
<view class="message_bottom">
<view class="message_btn btn_main" bindtap="handleMessage" data-name="reply_user_feedback" data-id="{{item.feedback_id}}">处理</view>
</view>
</view>
</swiper-item>
<swiper-item class="tab_swiper_item card_list">
<view class="message_box" wx:for="{{list.card_list}}" wx:key="k">
<view class="message_top">
<view>{{item.card_create}}</view>
<view>待审核</view>
<view class="cb"></view>
</view>
<view class="message_content">
<image src="../../images/icons/wechat.png"></image>
<view class="message_content_text">
<view>银行卡号:</view>
<view>{{item.card_no}}</view>
<view>银行名称:{{item.card_bank}}{{item.card_open_bank}}</view>
<view>持卡人:{{item.card_name}}</view>
</view>
<view class="message_content_right">{{item.manager_nickname}}</view>
<view class="cb"></view>
</view>
<view class="message_bottom">
<view class="message_btn" bindtap="handleMessage" data-name="auth_bank_card" data-id="{{item.card_id}}" data-type="3">驳回</view>
<view class="message_btn btn_main" bindtap="handleMessage" data-name="auth_bank_card" data-id="{{item.card_id}}" data-type="2">通过</view>
</view>
</view>
</swiper-item>
<swiper-item class="tab_swiper_item withdraw_list">
<view class="message_box" wx:for="{{list.withdraw_list}}" wx:key="k">
<view class="message_top">
<view class="message_title">
<view>{{item.w_no}}</view>
<view>{{item.w_create}}</view>
</view>
<view>待审核</view>
<view class="cb"></view>
</view>
<view class="message_content">
<image src="../../images/icons/wechat.png"></image>
<view class="message_content_text">
<view>提现ID:</view>
<view>{{item.w_no}}</view>
<view>手机号:{{item.w_mobile}}</view>
<view>提现商户:{{item.manager_nickname}}</view>
</view>
<view class="message_content_right">¥{{item.w_money}}</view>
<view class="cb"></view>
</view>
<view class="message_bottom">
<view class="message_btn" bindtap="handleMessage" data-name="auth_apply_withdraw" data-type="4" data-id="{{item.w_id}}">驳回</view>
<view class="message_btn btn_main" bindtap="handleMessage" data-name="auth_apply_withdraw" data-type="2" data-id="{{item.w_id}}">通过</view>
</view>
</view>
</swiper-item>
<swiper-item class="tab_swiper_item refund_list">
<view class="message_box" wx:for="{{list.refund_list}}" wx:key="k">
<view class="message_top">
<view class="message_title">
<view>{{item.hotel_title}}</view>
<view>{{item.pay_time}}</view>
</view>
<view>待审核</view>
<view class="cb"></view>
</view>
<view class="message_content">
<image src="{{item.goods_cover}}"></image>
<view class="message_content_text">
<view>{{item.detail_goods_title}}</view>
<view>订单号:{{item.pay_no}}</view>
<view>设备号:{{item.dev_no}}</view>
</view>
<view class="message_content_right">¥{{item.pay_real_money}}</view>
<view class="cb"></view>
</view>
<view class="message_bottom">
<view class="message_btn" bindtap="handleMessage" data-name="auth_refund_orders" data-type="2" data-id="{{item.pay_id}}">驳回</view>
<view class="message_btn btn_main" bindtap="handleMessage" data-name="auth_refund_orders" data-type="1" data-id="{{item.pay_id}}">通过</view>
</view>
</view>
</swiper-item>
</swiper>
\ No newline at end of file
.cb{
clear: both;
height: 0;
width: 100%;
}
.btn_main{
background-color: #387ee8 !important;
color: #FFFFFF !important;
}
\ No newline at end of file
// pages/hotelDetail/index.js
const app = getApp();
Page({
data: {
userInfo: wx.getStorageSync('userInfo'),
hotelDetail:{},
hotelId: 0
},
onLoad: function (options) {
var id = options.id;
var PageThis = this;
PageThis.setData({
userInfo:wx.getStorageSync('userInfo')
})
this.setData({
"hotelId": id
})
},
onShow: function () {
this.getHotelDetail();
},
//**页面跳转 */
navigateTo: function (e) {
var _url = e.currentTarget.dataset.url;
var _id = e.currentTarget.dataset.id;
wx.navigateTo({
url: _url + "?id=" + _id,
})
},
getHotelDetail:function(){
var PageThis = this;
var id = PageThis.data.hotelId;
wx.request({
url: app.globalData.serverInfo.gateWayUrl,
header: {
'content-type': 'application/json'
},
method: 'POST',
data: {
api_name: "hotel_detail",
hotel_id: id,
login_manager_id: PageThis.data.userInfo.manager_id
},
success:function(res){
console.log(res);
var data = res.data.data;
PageThis.setData({
"hotelDetail": data
})
}
})
}
})
\ No newline at end of file
{
"usingComponents": {}
}
\ No newline at end of file
<view class="info_item">
<view class="info_title">酒店名称</view>
<view class="info_content">{{hotelDetail.h_title}}</view>
</view>
<view class="info_item">
<view class="info_title">酒店负责人</view>
<view class="info_content">{{hotelDetail.h_lead}}</view>
</view>
<view class="info_item">
<view class="info_title">酒店类型</view>
<view class="info_content">经济型酒店</view>
</view>
<view class="info_item">
<view class="info_title">介绍人</view>
<view class="info_content">{{hotelDetail.introduce_nickname}}</view>
</view>
<view class="info_item">
<view class="info_title">酒店管理员</view>
<view class="info_content">{{hotelDetail.hotel_manager_nickname}}</view>
</view>
<view class="info_item">
<view class="info_title">补货员</view>
<view class="info_content">{{hotelDetail.rep_nickname}}</view>
</view>
<view class="info_item">
<view class="info_title">负责人电话</view>
<view class="info_content">{{hotelDetail.h_mobile}}</view>
</view>
<view class="info_item">
<view class="info_title">酒店电话</view>
<view class="info_content">{{hotelDetail.h_phone}}</view>
</view>
<view class="info_item">
<view class="info_title">位置地段</view>
<view class="info_content">{{hotelDetail.lot_title}}</view>
</view>
<view class="info_item">
<view class="info_title">酒店地址</view>
<view class="info_content">
<span>{{hotelDetail.h_address}}</span>
<image class="info_content_img" src="../../images/icons/icon(50).png"></image>
</view>
</view>
<view class="info_item">
<view class="info_title">房间数量</view>
<view class="info_content">{{hotelDetail.h_room_num}}</view>
</view>
<view class="info_item">
<view class="info_title">默认方案</view>
<view class="info_content">{{hotelDetail.gp_title}}</view>
</view>
<view class="info_item">
<view class="info_title">创建时间</view>
<view class="info_content">{{hotelDetail.h_create}}</view>
</view>
<view class="main_btn" bindtap="navigateTo" data-id="{{hotelDetail.h_id}}" data-url="../updateHotelDetail/index">编辑酒店</view>
<view class="main_btn four_btn" bindtap="navigateTo" data-url="../bindDevice/index" data-id="{{hotelDetail.h_id}}">绑定设备</view>
\ No newline at end of file
/* pages/hotelDetail/index.wxss */
\ No newline at end of file
// pages/hotelInventory/index.js
const app = getApp();
Page({
data: {
userInfo: wx.getStorageSync('userInfo'),
search_value: "",
hotelList: []
},
onLoad(){
var PageThis = this;
PageThis.setData({
userInfo:wx.getStorageSync('userInfo')
})
},
onShow: function () {
this.getHotelList();
},
getHotelList: function () {
var PageThis = this;
wx.request({
url: app.globalData.serverInfo.gateWayUrl,
header: {
'content-type': 'application/json'
},
method: 'POST',
data: {
api_name: "hotel_list",
search_value: PageThis.data.search_value,
login_manager_id: PageThis.data.userInfo.manager_id
},
success: function (res) {
var data = res.data.data;
PageThis.setData({
"hotelList": data
})
}
})
},
/**搜索监听 */
changeSearch: function (e) {
var PageThis = this;
var title = e.detail.value;
PageThis.setData({
"search_value": title
});
},
//**页面跳转 */
navigateTo: function (e) {
var _url = e.currentTarget.dataset.url;
var _id = e.currentTarget.dataset.id;
wx.navigateTo({
url: _url + "?id=" + _id,
})
},
})
\ No newline at end of file
{
"usingComponents": {}
}
\ No newline at end of file
<view id="search_box">
<view id="search_content_box">
<image src="../../images/icons/icon(51).png"></image>
<input placeholder="请输入酒店名称" bindinput="changeSearch"></input>
</view>
<view id="search_btn" bindtap="getHotelList">搜索</view>
</view>
<view id="list_box">
<view class="list_item" wx:for="{{hotelList}}" wx:key="k" bindtap="navigateTo" data-id="h_id" data-url="../hotelInventoryDetail/index">
<view class="list_title_box">
<view class="list_title">{{item.h_title}}的仓库</view>
<image class="list_item_icon" src="../../images/icons/icon(55).png"></image>
</view>
<view class="cb"></view>
</view>
</view>
\ No newline at end of file
.list_title_box{
border: none;
width: 95%;
padding-left: 5%;
}
.list_item{
border-bottom: 1px solid rgb(245, 245, 245);
}
\ No newline at end of file
// pages/hotelInventoryDetail/index.js
const app = getApp();
Page({
/**
* 页面的初始数据
*/
data: {
userInfo:[]
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
var PageThis = this;
PageThis.setData({
userInfo:wx.getStorageSync('userInfo')
})
},
/**
* 生命周期函数--监听页面初次渲染完成
*/
onReady: function () {
},
/**
* 生命周期函数--监听页面显示
*/
onShow: function () {
},
/**
* 生命周期函数--监听页面隐藏
*/
onHide: function () {
},
/**
* 生命周期函数--监听页面卸载
*/
onUnload: function () {
},
/**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh: function () {
},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom: function () {
},
/**
* 用户点击右上角分享
*/
onShareAppMessage: function () {
}
})
\ No newline at end of file
{
"usingComponents": {}
}
\ No newline at end of file
<view id="search_box">
<view id="search_content_box">
<image src="../../images/icons/icon(51).png"></image>
<input placeholder="请输入商品名称"></input>
</view>
<view id="search_btn">搜索</view>
</view>
<view id="list">
<view class="img_list_item">
<image src="../../images/icons/logo.png"></image>
<view class="item_text_box">
<view class="item_text" style="font-size:4.5vw">欧乐B电动牙刷</view>
<view class="item_text" style="color:red">库存:200000</view>
<view class="item_text" style="color:rgb(138,138,138)">进货价:¥1.00</view>
</view>
</view>
<view class="img_list_item">
<image src="../../images/icons/logo.png"></image>
<view class="item_text_box">
<view class="item_text" style="font-size:4.5vw">欧乐B电动牙刷</view>
<view class="item_text" style="color:red">库存:200000</view>
<view class="item_text" style="color:rgb(138,138,138)">进货价:¥1.00</view>
</view>
</view>
</view>
\ No newline at end of file
/* pages/hotelInventoryDetail/index.wxss */
\ No newline at end of file
// pages/hotelList/index.js
const app = getApp();
Page({
data: {
userInfo: wx.getStorageSync('userInfo'),
hotelList:[],
search_value: "",
},
onLoad: function (options) {
var PageThis = this;
PageThis.setData({
userInfo:wx.getStorageSync('userInfo')
})
this.getHotelList();
},
//**页面跳转 */
navigateTo: function (e) {
var _url = e.currentTarget.dataset.url;
var _id = e.currentTarget.dataset.id;
wx.navigateTo({
url: _url + "?id=" + _id,
})
},
getHotelList:function(){
var PageThis = this;
wx.request({
url: app.globalData.serverInfo.gateWayUrl,
header: {
'content-type': 'application/json'
},
method: 'POST',
data: {
api_name: "hotel_list",
search_value: PageThis.data.search_value,
login_manager_id: PageThis.data.userInfo.manager_id
},
success:function(res){
var data = res.data.data;
PageThis.setData({
"hotelList": data
})
}
})
},
/**搜索监听 */
changeSearch: function (e) {
var PageThis = this;
var title = e.detail.value;
PageThis.setData({
"search_value": title
});
}
})
\ No newline at end of file
{
"usingComponents": {}
}
\ No newline at end of file
<view id="search_box">
<view id="search_content_box">
<image src="../../images/icons/icon(51).png"></image>
<input placeholder="请输入酒店名称" bindinput="changeSearch"></input>
</view>
<view id="search_btn" bindtap="getHotelList">搜索</view>
</view>
<view id="list_box">
<view class="list_item" wx:for="{{hotelList}}" wx:key="k" bindtap="navigateTo" data-id="{{item.h_id}}" data-url="../hotelDetail/index">
<view class="list_title_box">
<view class="list_title">{{item.h_title}}</view>
<image class="list_item_icon" src="../../images/icons/icon(55).png"></image>
</view>
<view class="cb"></view>
</view>
</view>
<image class="add_btn" src="../../images/icons/icon(33).png" bindtap="navigateTo" data-url="../createHotel/index"></image>
\ No newline at end of file
.list_title_box{
border: none;
width: 95%;
padding-left: 5%;
}
.list_item{
border-bottom: 1px solid rgb(245, 245, 245);
}
\ No newline at end of file
// pages/salesStatistics/index.js
const app = getApp();
Page({
data: {
userInfo: wx.getStorageSync('userInfo'),
start_time: "请选择开始时间",
end_time: "请选择结束时间",
hotelValue: [], //酒店列表数组
hotelIndex:0, //酒店列表数组picker选中【键值】
hotelId: 0,//存储的酒店ID
hotel_list: [],
total_orders_money:0,
total_orders_goods:0,
total_hotel:0,
user_name:""
},
onLoad: function (options) {
var PageThis = this;
PageThis.setData({
userInfo:wx.getStorageSync('userInfo')
})
this.getData();
this.getHotelList();
},
getData: function () {
var PageThis = this;
wx.request({
url: app.globalData.serverInfo.gateWayUrl,
header: {
'content-type': 'application/json'
},
method: 'POST',
data: {
api_name: "hotel_data_count",
hotel_id: PageThis.data.hotelId,
start_time: PageThis.data.start_time == "请选择开始时间" ? "" : PageThis.data.start_time,
end_time: PageThis.data.end_time == "请选择结束时间" ? "" : PageThis.data.end_time,
login_manager_id: PageThis.data.userInfo.manager_id,
username:PageThis.data.user_name
},
success: function (res) {
console.log(res);
var res = res.data;
if (res.state == 1) {
PageThis.setData({
"total_orders_money": res.data.total_orders_money,
"total_orders_goods": res.data.total_orders_goods,
"hotel_list": res.data.hotel_list,
"total_hotel": res.data.total_hotel
})
}
}
})
},
getHotelList: function () {
var PageThis = this;
wx.request({
url: app.globalData.serverInfo.gateWayUrl,
header: {
'content-type': 'application/json'
},
method: 'POST',
data: {
api_name: "hotel_list_value",
login_manager_id: PageThis.data.userInfo.manager_id
},
success: function (res) {
var data = res.data.data;
PageThis.setData({
"hotelValue": data
})
}
})
},
inputChange:function(e){
var PageThis = this;
PageThis.setData({
"user_name":e.detail.value
})
},
pickerChange: function (e) {
var PageThis = this;
var val = e.detail.value;
var name = e.target.dataset.name;
switch (name) {
case "start_time":
PageThis.setData({
start_time: val
})
break;
case "end_time":
PageThis.setData({
end_time: val
})
break;
case "hotel":
//hotelIndex存储picker选中【键值】
//hotelId存储picker选中【h_id】
PageThis.setData({
hotelIndex: e.detail.value,
hotelId: this.data.hotelValue[e.detail.value].h_id
})
break;
}
},
reset:function(){
var PageThis = this;
PageThis.setData({
start_time: "请选择开始时间",
end_time: "请选择结束时间",
hotelName: "请选择酒店",
hotelId: 0,
})
}
})
\ No newline at end of file
{
"usingComponents": {}
}
\ No newline at end of file
<view class="input_box_item">
<view class="input_title">酒店</view>
<picker range="{{hotelValue}}" value="{{hotelIndex}}" range-key="h_title" data-name="hotel" style="background-color:rgba(0,0,0,0);padding-left:0;margin-top:0 !important;" bindchange="pickerChange">
<input placeholder="{{hotelValue[hotelIndex].h_title}}" disabled="true"></input>
</picker>
</view>
<view class="input_box_item">
<view class="input_title">交易时间</view>
<picker mode="date" fields="day" data-name="start_time" bindchange="pickerChange">
<span>{{start_time}}</span>
</picker>
<view class="link_icon">~</view>
<picker mode="date" fields="day" data-name="end_time" bindchange="pickerChange">
<span>{{end_time}}</span>
</picker>
</view>
<view class="serach_form_btn_box">
<view class="serach_form_btn active" bindtap="getData">搜索</view>
<view class="serach_form_btn" bindtap="reset">重置</view>
</view>
<view class="data_box">
<view class="data_item">
<view>{{total_orders_money}}</view>
<view>总成交额(元)</view>
</view>
<view class="data_item">
<view>{{total_orders_goods}}</view>
<view>总成交量(元)</view>
</view>
</view>
<view class="statistics_list_box">
<view class="statistics_list_title">
<view>酒店名称</view>
<view>销售额(元)</view>
<view>销售量(件)</view>
</view>
<view class="statistics_list_item" wx:for="{{hotel_list}}" wx:key="k">
<view>{{item.h_title}}</view>
<view>{{item.total_orders_money}}</view>
<view>{{item.total_orders_num}}</view>
</view>
</view>
\ No newline at end of file
picker{
float: left;
width: 31vw;
height: 8vw;
background-color: rgb(248,248,248);
color: #999999;
border-radius: 5px;
margin-top: 2vw !important;
margin-left: 0;
line-height: 8vw;
padding-left: 2vw;
font-size: 3.5vw;
}
input{
background-color: rgb(248,248,248);
padding-left: 2vw;
width: 69.5vw;
height: 8vw !important;
line-height: 8vw !important;
border-radius: 5px;
margin-top: 1vw !important;
}
.input_box_item{
width: 100%;
border-bottom: none;
height: 10vw;
line-height: 10vw;
}
.input_title{
width: 20vw;
margin-left: 2vw;
height: 100%;
line-height: 10vw;
}
.link_icon{
height: 10vw;
line-height: 10vw;
float: left;
padding: 0 2vw;
}
.data_box{
width: calc(90vw + 1px);
height: 30vw;
border-radius: 15px;
background-image: linear-gradient(90deg, #77adff 0%, #387ee8 100%);
color: #FFFFFF;
margin: 8vw auto;
}
.data_item{
width: 45vw;
text-align: center;
float: left;
margin-top: 8vw;
}
.data_item:nth-child(1){
border-right: 1px solid rgb(106,160,245);
}
.data_item view:nth-child(1){
font-size: 6vw;
height: 8vw;
line-height: 8vw;
}
.data_item view:nth-child(2){
font-size: 3.2vw;
height: 6vw;
line-height: 6vw;
}
.statistics_list_box{
width: 93vw;
margin: 0 auto;
border-top: 3vw solid rgb(248,248,248);
padding: 0 3.5vw;
}
.statistics_list_title,.statistics_list_item{
width: 90vw;
height: 12vw;
line-height: 12vw;
padding: 0 1.5vw;
border-bottom: 1px solid rgb(248,248,248);
font-size: 3.8vw;
}
.statistics_list_title view,.statistics_list_item view{
width: 30vw;
color: rgb(150,150,150);
height: 100%;
float: left;
}
.statistics_list_title view:nth-child(2){
/* text-align: center; */
}
.statistics_list_title view:nth-child(3){
text-align: right;
}
.statistics_list_item view{
color: #000000;
}
.statistics_list_item view:nth-child(2){
color: rgb(106,160,245);
/* text-align: center; */
}
.statistics_list_item view:nth-child(3){
text-align: center;
color: rgb(106,160,245);
}
\ No newline at end of file
//index.js
//获取应用实例
const app = getApp()
Page({
data: {
userInfo: wx.getStorageSync('userInfo'),
bottomNavList: app.globalData.bottomNavList,
indexIcon: app.globalData.indexIcon,
dateIndex:2,
bootomNavIndex:1,
dateActive1: '',
dateActive2: 'date_active',
dateActive3: '',
handleNum:0,
topData:{
topData1:0,
topData2: 0,
topData3: 0,
},
dataBox:{
no_stock_device:0,
total_device:0,
no_stock_p:0
},
ordersDataCount:{},
notice:"您好!欢迎使用",
time:0,
px:0
},
onLoad: function () {
var PageThis = this;
PageThis.setData({
userInfo:wx.getStorageSync('userInfo')
});
PageThis.getNotice();
PageThis.getToDoList();
PageThis.getPageInfo();
},
onShow: function () {
this.setData({
"handleNum":app.globalData.handleNum
})
},
//**页面跳转 */
navigateTo: function (e) {
var _url = e.currentTarget.dataset.url;
wx.navigateTo({
url: _url,
})
},
/**tap切换 */
switchNav:function(e){
var PageThis = this;
var id = e.target.dataset.id;
PageThis.setOrderData(id);
},
setOrderData:function(id){
var PageThis = this;
PageThis.setData({
dateActive1: '',
dateActive2: '',
dateActive3: ''
})
switch(id){
case "1":
var data = {
topData1: PageThis.data.ordersDataCount.separate_yesterday_money,
topData2: PageThis.data.ordersDataCount.orders_yesterday_num,
topData3: PageThis.data.ordersDataCount.sales_yesterday_money,
}
PageThis.setData({
dateActive1: 'date_active',
topData: data
})
break;
case "2":
var data = {
topData1: PageThis.data.ordersDataCount.separate_today_money,
topData2: PageThis.data.ordersDataCount.orders_today_num,
topData3: PageThis.data.ordersDataCount.sales_today_money,
}
PageThis.setData({
dateActive2: 'date_active',
topData: data
})
break;
case "3":
var data = {
topData1: PageThis.data.ordersDataCount.separate_month_money,
topData2: PageThis.data.ordersDataCount.orders_month_num,
topData3: PageThis.data.ordersDataCount.sales_month_money,
}
PageThis.setData({
dateActive3: 'date_active',
topData: data
})
break;
}
},
/**获取页面数据信息 */
getPageInfo:function(){
var PageThis = this;
wx.request({
url: app.globalData.serverInfo.gateWayUrl,
header: {
'content-type': 'application/json'
},
method: 'POST',
data:{
api_name: "device_count",
login_manager_id: PageThis.data.userInfo.manager_id
},
success:function(res){
var data = res.data.data;
if (Number(data['total_device']) > 0){
data['no_stock_p'] = (data['no_stock_device'] / data['total_device'] * 100).toFixed(2);
}else{
data['no_stock_p'] = 0;
}
PageThis.setData({
dataBox: data
})
}
})
wx.request({
url: app.globalData.serverInfo.gateWayUrl,
header: {
'content-type': 'application/json'
},
method: 'POST',
data: {
api_name: "orders_count",
login_manager_id: PageThis.data.userInfo.manager_id
},
success:function(res){
var data = res.data.data;
PageThis.setData ({
ordersDataCount: data
},() => {
PageThis.setOrderData('2');
});
}
})
},
getNotice(){
var PageThis = this;
wx.request({
url: app.globalData.serverInfo.gateWayUrl,
header: {
'content-type': 'application/json'
},
method: 'POST',
data: {
api_name: "",
login_manager_id: PageThis.data.userInfo.manager_id
},
success:function(res){
PageThis.setData({
notice:res.data.data.mini_index_notice
})
var box_width = 0;
var content_width = 0;
var query = wx.createSelectorQuery();
query.select('.sound_bar_box').boundingClientRect(function(rect){
box_width = rect.width;
});
query.select('.sound_bar_content').boundingClientRect(function(rect){
content_width = rect.width;
}).exec();
setTimeout(function(){
if(Number(content_width) > Number(box_width)){
var time = Math.ceil(content_width/30);
PageThis.setData({
time:Math.floor(content_width/30),
px:content_width*(-1)
})
setInterval(function(){
PageThis.setData({
time:0,
px:box_width
},Math.floor(content_width/30) * 1000)
setTimeout(function(){
PageThis.setData({
time:Math.floor(content_width/30),
px:content_width*(-1)
})
})
},time * 1000)
}
},1000)
}
})
},
getToDoList(){
var PageThis = this;
wx.request({
url: app.globalData.serverInfo.gateWayUrl,
header: {
'content-type': 'application/json'
},
method: 'POST',
data: {
api_name: "get_to_do_list",
login_manager_id: PageThis.data.userInfo.manager_id
},
success:function(res){
var data = res.data.data;
app.globalData.handleNum = data.total_number;
PageThis.setData({
"handleNum":data.total_number
})
}
})
},
})
{
"usingComponents": {}
}
\ No newline at end of file
<view id="top_banner">
<view id="message_box" bindtap="navigateTo" data-url="../handleMessage/index">
<view id="message_tips">{{handleNum}}</view>
<image src="../../images/icons/message.png"></image>
</view>
<view id="date_box">
<view class="date_box_item {{dateActive1}}" bindtap="switchNav" data-id="1">昨日</view>
<view class="date_box_item {{dateActive2}}" bindtap="switchNav" data-id="2">今日</view>
<view class="date_box_item {{dateActive3}}" bindtap="switchNav" data-id="3">本月</view>
<view class="cb"></view>
</view>
<view id="money_box">
<view class="money_num">{{topData.topData1}}</view>
<view class="money_title">分成金额(元)</view>
</view>
<view id="detail_box">
<view class="detail_left">
<view class="detail_box_title">订单数量(笔)</view>
<view class="detail_box_num">{{topData.topData2}}</view>
</view>
<view class="detail_right">
<view class="detail_box_title">销售额(元)</view>
<view class="detail_box_num">{{topData.topData3}}</view>
</view>
</view>
</view>
<view class="sound_bar">
<image src="../../images/icons/sound.png"></image>
<view class="sound_bar_box">
<view class="sound_bar_content" style="left:{{px}}px;transition:left {{time}}s linear">{{notice}}</view>
</view>
</view>
<view id="data_box">
<view class="data_item">
<view class="data_item_title">设备总数</view>
<view class="data_item_num">{{dataBox.total_device}}</view>
<view class="data_item_tips"></view>
</view>
<view class="data_item">
<view class="data_item_title">在线设备</view>
<view class="data_item_num">{{dataBox.online_device}}</view>
<view class="data_item_tips">在线率:{{dataBox.online_rat}}%</view>
</view>
<view class="data_item">
<view class="data_item_title">缺货设备</view>
<view class="data_item_num">{{dataBox.no_stock_device}}</view>
<view class="data_item_tips">缺货率:{{dataBox.no_stock_rat}}%</view>
</view>
</view>
<view id="index_icon_box">
<view wx:for="{{indexIcon}}" wx:key="k" class="index_item" bindtap="navigateTo" data-url="{{item.url}}" wx:if="{{userInfo.manager_type!=7}}">
<view class="index_item_icon_box">
<image class="index_item_icon" src="{{item.icon}}"></image>
</view>
<view class="index_item_title">{{item.title}}</view>
</view>
<view wx:for="{{indexIcon}}" wx:key="k" class="index_item" bindtap="navigateTo" data-url="{{item.url}}" wx:if="{{userInfo.manager_type==7&&item.index==0}}">
<view class="index_item_icon_box">
<image class="index_item_icon" src="{{item.icon}}"></image>
</view>
<view class="index_item_title">{{item.title}}</view>
</view>
</view>
\ No newline at end of file
#date_box{
color: #FFFFFF;
width: 60vw;
padding: 3vw 20vw 4vw 20vw;
}
.date_box_item{
float: left;
width: 10vw;
text-align: center;
font-size: 3.8vw;
padding: 2vw 0;
margin: 0 5vw;
}
.date_active{
font-size: 4.5vw;
border-bottom: 2px solid #FFFFFF;
line-height: 3.8vw;
}
#money_box{
width: 100%;
text-align: center;
color: #FFFFFF;
}
.money_num{
font-size: 10vw;
}
.money_title{
font-size: 3.2vw;
}
#detail_box{
width: 84vw;
color: #FFFFFF;
padding: 5vw 8vw;
}
.detail_left{
float: left;
width: 25vw;
text-align: center;
}
.detail_right{
float: right;
width: 20vw;
text-align: center;
}
.detail_box_title{
font-size: 3vw;
}
.detail_box_num{
font-size: 4.2vw;
margin-top: 0.5vw;
}
#data_box{
width: 90vw;
height: 25vw;
margin: 3vw 5vw;
border-radius: 5px;
-moz-box-shadow:2px 4px 10px 2px #DEE4E6;
-webkit-box-shadow:2px 4px 10px 2px #DEE4E6;
box-shadow:2px 4px 10px 2px #DEE4E6;
}
.data_item{
width: 30vw;
text-align: center;
float: left;
}
.data_item_title{
font-weight: bold;
color: rgb(53,72,97);
height: 6vw;
line-height: 6vw;
font-size: 3.8vw;
margin-top: 2vw;
}
.data_item_num{
font-size: 4.5vw;
height: 10vw;
line-height: 10vw;
color: rgb(56,125,232);
font-weight: bold;
}
.data_item_tips{
font-size: 3vw;
color: rgb(175,189,214);
}
#index_icon_box{
width: 90vw;
margin-top: 8vw;
padding: 0 5vw;
}
.index_item{
float: left;
text-align: center;
color: rgb(53,72,97);
width: 30vw;
height: 25vw;
font-size: 3.2vw;
font-weight: bold;
}
.index_item_icon_box{
width: 6vw;
height: 6vw;
position: relative;
margin: 2vw 12vw;
}
.index_item_icon{
width: 100%;
height: 100%;
background-size: 100% 100%;
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
margin: auto;
}
#message_box{
width: 7vw;
height: 7vw;
position: absolute;
top: 2vw;
left: 5vw;
}
#message_box image{
width: 6vw;
height: 7vw;
background-size: 100% 100%;
}
#message_tips{
position: absolute;
right: 0;
top: -0.5vw;
border-radius: 50%;
width: 3.5vw;
height: 3.5vw;
text-align: center;
line-height: 3.5vw;
font-size: 3vw;
background-color: #FF4141;
border: 1px soldi #FFFFFF;
color: #FFFFFF;
}
.sound_bar{
width: 90vw;
height: 5vw;
line-height: 5vw;
margin: 3vw auto 0 auto;
}
.sound_bar image{
width: 4vw;
height: 4vw;
margin: 0.5vw 0;
background-size: 100% 100%;
float: left;
}
.sound_bar_box{
float: left;
width: 83vw;
overflow: hidden;
height: 5vw;
line-height: 5vw;
position: relative;
margin-left: 2vw;
font-size: 3.5vw;
color: #999999;
}
.sound_bar_content{
position: absolute;
white-space: nowrap;
}
\ No newline at end of file
// pages/login/index.js
const app = getApp();
Page({
data: {
login_name:"",
login_password:"",
switchChecked: true,
},
onLoad(){
var PageThis = this;
PageThis.setData({
userInfo:wx.getStorageSync('userInfo')
})
if(wx.getStorageSync('username')!=''){
PageThis.setData({
login_name:wx.getStorageSync('username')
})
};
if(wx.getStorageSync('password')!=''){
PageThis.setData({
login_password:wx.getStorageSync('password')
})
};
},
clickRegister:function(){
wx.navigateTo({
url: '../register/index',
})
},
switchChange:function(e){
this.setData({
switchChecked:e.detail.value
});
},
formSubmit:function(e){
var PageThis = this;
wx.showLoading({
title: '登录中...',
});
wx.request({
url: app.globalData.serverInfo.gateWayUrl,
header: {
'content-type': 'application/json'
},
method: 'POST',
data: {
api_name: "login",
username: e.detail.value.login_name,
password: e.detail.value.login_password,
},
success: function (res) {
wx.hideLoading();
if(res.data.state == 1){
wx.showToast({
title: '登录成功',
icon: 'success',
duration: 500,
success:function(){
wx.setStorage({
key: 'userInfo',
data: res.data.data
})
wx.setStorage({
key: 'username',
data: e.detail.value.login_name
})
wx.setStorage({
key: 'password',
data: e.detail.value.login_password
})
wx.switchTab({
url: '../index/index',
})
}
})
}else{
wx.showToast({
title: res.data.msg,
icon: 'none',
duration: 500
})
}
},fail:function(err){
wx.showToast({
title: "网络异常",
icon: 'none',
duration: 500
})
}
})
}
})
\ No newline at end of file
{
"usingComponents": {}
}
\ No newline at end of file
<image class="login_top_img" src="../../images/top_banner/top_banner(1).png"></image>
<view class="login_type_box">
<view class="login_type login_type_active">账号密码登录</view>
<view class="login_type">手机验证码登录</view>
</view>
<view class="cb"></view>
<form catchsubmit="formSubmit">
<view class="login_box">
<view class="login_item">
<image src="../../images/icons/icon(31).png"></image>
<input id="name" name="login_name" value="{{login_name}}" placeholder="请输入您的账号"></input>
</view>
<view class="cb"></view>
<view class="login_item">
<image src="../../images/icons/icon(32).png"></image>
<input id="password" name="login_password" value="{{login_password}}" placeholder="请输入您的密码" password></input>
</view>
<view class="cb"></view>
</view>
<view class="rememberPasswordWrap">
<switch type="checkbox" checked="{{switchChecked}}" bindchange="switchChange" color="rgb(55,126,232)"/>
记住密码
</view>
<button class="login_btn" type="primary" formType="submit">登录</button>
<view class="register_wrap" bindtap="clickRegister">我要注册</view>
</form>
<view class="login_tips">
<view>温馨提示:</view>
<view>1.本系统为管理员端管理系统,并非面对所有用户</view>
<view>2.请输入账号和密码登陆方可管理自己的设备</view>
<view>3.不输入正确的账号和密码不能进入系统进行设备管理</view>
<view>4.请注意保管自己的账号和密码信息,防止信息泄露</view>
</view>
<!-- <image id="wx_logo" src="../../images/icons/wx_logo.jpg"></image> -->
\ No newline at end of file
.login_top_img{
width: 100%;
background-size: 100% 100%;
}
.login_type_box{
width: 70vw;
margin: 0 15vw;
margin-top: 8vw;
}
.login_type{
font-size: 4vw;
color: rgb(67,82,106);
padding: 2vw 0;
}
.login_type:nth-child(1){
float: left;
text-align: left;
}
.login_type:nth-child(2){
float: right;
text-align: right;
}
.login_type_active{
color: rgb(77,139,233);
border-bottom: 1vw solid rgb(56,125,232);
}
.login_box{
margin-top: 8vw;
}
.login_item{
border-bottom: 1px solid rgb(248,248,248);
height: 15vw;
width: 80vw;
margin: 0 10vw;
}
.login_item image{
float: left;
width: 5vw;
height: 5vw;
background-size: 100% 100%;
margin-top: 6vw;
}
.login_item input{
float: left;
padding-left: 3vw;
font-size: 4vw;
height: 5vw;
line-height: 5vw;
margin: 5vw 0;
}
.login_btn{
width: 80vw !important;
height: 12vw !important;
line-height: 12vw !important;
color: #FFFFFF !important;
border-radius: 6vw !important;
text-align: center !important;
font-size: 5vw !important;
background-color: rgb(55,126,232) !important;
margin-top: 10vw !important;
padding: 0 !important;
}
#wx_logo{
width: 12vw;
height: 12vw;
border-radius: 50%;
background-size: 100% 100%;
/* border: 2vw solid rgb(0,153,63); */
margin: 10vw 44vw;
}
.register_wrap{
width: 100%;
text-align: center;
font-size: 4vw;
margin-top: 5vw;
color: #666666;
}
.login_tips{
font-size: 2.8vw;
color: #afafaf;
width: 80%;
margin: 5vw auto;
line-height: 4vw;
}
.rememberPasswordWrap{
width: 80%;
margin: 2vw auto;
font-size: 4vw;
}
\ No newline at end of file
//logs.js
const util = require('../../utils/util.js')
Page({
data: {
logs: []
},
onLoad: function () {
this.setData({
logs: (wx.getStorageSync('logs') || []).map(log => {
return util.formatTime(new Date(log))
})
})
}
})
{
"navigationBarTitleText": "查看启动日志",
"usingComponents": {}
}
\ No newline at end of file
<!--logs.wxml-->
<view class="container log-list">
<block wx:for="{{logs}}" wx:for-item="log">
<text class="log-item">{{index + 1}}. {{log}}</text>
</block>
</view>
.log-list {
display: flex;
flex-direction: column;
padding: 40rpx;
}
.log-item {
margin: 10rpx;
}
const app = getApp();
Page({
data: {
userInfo: wx.getStorageSync('userInfo'),
deviceList: [],
search_type: 0,
search_value: "",
bind_value: -1,
state_value: -1,
searchArray: ['酒店', '合伙人', '设备号']
},
onShow: function (options) {
var PageThis = this;
PageThis.setData({
userInfo:wx.getStorageSync('userInfo')
})
this.getDeviceList();
},
//**页面跳转 */
navigateTo: function (e) {
var _url = e.currentTarget.dataset.url;
var _id = e.currentTarget.dataset.id;
wx.navigateTo({
url: _url + "?id=" + _id,
})
},
/**获取设备列表 */
getDeviceList: function () {
var PageThis = this;
wx.showLoading({
title: '信息加载中',
})
wx.request({
url: app.globalData.serverInfo.gateWayUrl,
header: {
'content-type': 'application/json'
},
method: 'POST',
data: {
api_name: "no_stock_device",
search_type: Number(PageThis.data.search_type) + 1,
search_value: PageThis.data.search_value,
bind_value: PageThis.data.bind_value,
state_value: PageThis.data.state_value,
login_manager_id: PageThis.data.userInfo.manager_id
},
success: function (res) {
var data = res.data.data;
for (var i in data) {
data[i]['show_list'] = "false";
data[i]['hotel_img'] = "../../images/icons/arrow_down.png";
for(var k in data[i].dev_list){
var device_title = "未分配酒店设备";
var rep_nickname = "未分配补货员";
var lattice_arr = [];
for(var x in data[i].dev_list[k].dev_no_stock_lattice){
lattice_arr.push(Number(data[i].dev_list[k].dev_no_stock_lattice[x].lat_title))
}
if (Number(data[i].dev_list[k].dev_hotel_id) > 0 && data[i].dev_list[k].dev_hotel_room != "") {
device_title = data[i].dev_list[k].hotel_title + data[i].dev_list[k].dev_hotel_room;
} else if (data[i].dev_list[k].dev_room_address != "") {
device_title = data[i].dev_list[k].dev_room_address;
}else if(Number(data[i].dev_list[k].dev_hotel_id) > 0){
device_title = "未分配房间设备";
}
if (data[i].dev_list[k].rep_nickname != "" && data[i].dev_list[k].rep_nickname != null) {
rep_nickname = data[i].dev_list[k].rep_nickname;
}
var obj = {
"dev_id": data[i].dev_list[k].dev_id,
"dev_no": data[i].dev_list[k].dev_no,
"dev_no_stock_lattice": lattice_arr,
"dev_state": data[i].dev_list[k].dev_state,
"device_title": device_title,
"rep_nickname": rep_nickname
}
data[i].dev_list[k] = obj;
}
}
PageThis.setData({
"deviceList": data
})
wx.hideLoading({
success: (res) => {},
})
}
})
},
changeSearchType: function (e) {
var PageThis = this;
var id = e.detail.value;
PageThis.setData({
"search_type": id
})
},
searchValueChange: function (e) {
var PageThis = this;
PageThis.setData({
"search_value": e.detail.value
})
},
hotel_click(e){
var PageThis = this;
var deviceList = PageThis.data.deviceList
var id = e.currentTarget.dataset.id;
var type = e.currentTarget.dataset.type;
for(var i in deviceList){
if(Number(deviceList[i]['hotel_id']) == Number(id)){
if(type == "true"){
deviceList[i]['show_list'] = "false";
deviceList[i]['hotel_img'] = "../../images/icons/arrow_down.png";
}else{
deviceList[i]['show_list'] = "true";
deviceList[i]['hotel_img'] = "../../images/icons/arrow_up.png";
}
}else{
deviceList[i]['show_list'] = "false";
deviceList[i]['hotel_img'] = "../../images/icons/arrow_down.png";
}
}
PageThis.setData({
deviceList:deviceList
})
},
quickScan(){
var PageThis = this;
wx.scanCode({
scanType:"qrCode",
success (res) {
var scan_url = res.result;
var thisDevNo = scan_url.replace(app.globalData.serverInfo.qrReplaceUrl, '');
if(thisDevNo != "" ){
wx.request({
url: app.globalData.serverInfo.gateWayUrl,
header: {
'content-type': 'application/json'
},
method: 'POST',
data: {
api_name: "find_device",
dev_no: thisDevNo
},
success:function(ret){
var data = ret.data;
if(Number(data.state) === 1){
var _url = "../replenishmentDetail/index";
var _id = data.data.dev_id;
wx.navigateTo({
url: _url + "?id=" + _id,
})
}else{
wx.showToast({
title: data.msg,
})
}
}
})
}else{
wx.showToast({
title: '无效二维码',
icon:"none"
})
}
}
})
}
})
\ No newline at end of file
{
"usingComponents": {}
}
\ No newline at end of file
<view id="search_box">
<view id="search_content_box">
<view class="select_item">
<picker id="searchPicker" bindchange="changeSearchType" range="{{searchArray}}">
<image src="../../images/icons/icon(58).png"></image>
<span>{{searchArray[search_type]}}</span>
</picker>
</view>
<image src="../../images/icons/icon(51).png"></image>
<input placeholder="请输入需要搜索的字段" bindinput="searchValueChange"></input>
</view>
<view id="search_btn" bindtap="getDeviceList">搜索</view>
</view>
<view class="hotel_box" wx:for="{{deviceList}}" wx:key="k">
<view class="hotel_name_item" bindtap="hotel_click" data-id="{{item.hotel_id}}" data-type="{{item.show_list}}">
<image src="../../images/icons/hotel.png"></image>
<view class="hotel_name_text">{{item.hotel_title}}</view>
<image class="hotel_name_arrow" src="{{item.hotel_img}}"></image>
<view class="no_stock_icon">缺货</view>
<view class="cb"></view>
</view>
<block wx:if="{{item.show_list == 'true'}}">
<view class="hotel_item" wx:for="{{item.dev_list}}" wx:key="k" bindtap="navigateTo" data-id="{{item.dev_id}}" data-url="../replenishmentDetail/index" >
<view>
<view class="hotel_name">{{item.device_title}} </view>
<image src="../../images/icons/icon(45).png"></image>
<view class="cb"></view>
</view>
<view class="hotel_content_item">
<view>缺货格子:</view>
<view class="ball_item" wx:for="{{item.dev_no_stock_lattice}}" wx:key="k1">{{item}}</view>
<view class="cb"></view>
</view>
<view class="hotel_content_item">
<view>设备号:{{item.dev_no}}</view>
<view>{{item.rep_nickname}}</view>
<view class="cb"></view>
</view>
</view>
</block>
</view>
<image id="quickScan" bindtap="quickScan" src="../../images/icons/qrScan.png"></image>
\ No newline at end of file
#search_content_box{
border-radius: 5px;
}
.select_item{
float: left;
width: 18vw;
border-right: 1px solid rgb(248,248,248);
height: 6vw;
margin: 1.5vw 0;
position: relative;
}
#searchPicker{
width: 100%;
height: 100%;
position: absolute;
left: 0;
top: 0;
z-index: 10;
}
.select_item span{
float: right;
font-size: 3.5vw;
height: 100%;
line-height: 6vw;
color: #999999;
margin-left: 2vw;
text-align: right;
}
.select_item image{
float: right !important;
width: 2vw !important;
height: 2vw !important;
background-size: 100% 100%;
margin-top: 2vw !important;
margin-left: 1vw !important;
}
.select_box{
width: 100%;
border-bottom: 1px solid rgb(248,248,248);
height: 12vw;
}
.select_box .select_item{
width: calc(100vw/3);
border: none;
color: #999999;
font-size: 3.5vw;
}
.select_box .select_item span{
margin-top: 1.5vw !important;
margin-left: 12vw !important;
float: left !important;
}
.select_box .select_item image{
margin-top: 3.5vw !important;
float: left !important;
}
.no_stock_icon{
color:#FFFFFF;
background-color: #FF3F00;
border-radius: 3px;
font-size: 3.2vw;
text-align: center;
height: 5vw;
line-height: 5vw;
float:right;
width: 8vw;
margin: 4vw 0 0 0;
}
#quickScan{
position: fixed;
bottom: 10vw;
right: 5vw;
width: 6vw;
height: 6vw;
background-color: #387ee8;
border-radius: 50%;
padding: 4vw;
}
\ No newline at end of file
// pages/ordersList/index.js
const app = getApp();
Page({
data: {
userInfo: wx.getStorageSync('userInfo'),
pay_no:"",
hotelValue: [], //酒店列表数组
hotelIndex:0, //酒店列表数组picker选中【键值】
hotelId: 0,//存储的酒店ID
managerValue: [], //合伙人列表数组
managerIndex:0, //合伙人列表数组picker选中【键值】
managerId: 0,//存储的合伙人ID
partnerList: [],
partnerValue: [],
partnerName: "请选择合伙人",
partner_id:"",
start_time:"请选择开始时间",
end_time:"请选择结束时间",
ordersList:[]
},
//**页面跳转 */
navigateTo: function (e) {
var _url = e.currentTarget.dataset.url;
var _id = e.currentTarget.dataset.id;
wx.navigateTo({
url: _url + "?id=" + _id,
})
},
onLoad(){
var PageThis = this;
PageThis.setData({
userInfo:wx.getStorageSync('userInfo')
})
},
onShow: function () {
this.getOrdersList();
this.getHotelList();
this.getPartnerList();
},
getOrdersList: function () {
var PageThis = this;
wx.request({
url: app.globalData.serverInfo.gateWayUrl,
header: {
'content-type': 'application/json'
},
method: 'POST',
data: {
api_name: "get_orders_list",
pay_no: PageThis.data.pay_no,
hotel_id: PageThis.data.hotelId,
partner_id: PageThis.data.managerId,
start_time: PageThis.data.start_time == "请选择开始时间" ? "" : PageThis.data.start_time,
end_time: PageThis.data.end_time == "请选择结束时间" ? "" : PageThis.data.end_time,
login_manager_id: PageThis.data.userInfo.manager_id
},
success:function(res){
var data = res.data.data;
PageThis.setData({
"ordersList": data
})
}
})
},
getHotelList: function () {
var PageThis = this;
wx.request({
url: app.globalData.serverInfo.gateWayUrl,
header: {
'content-type': 'application/json'
},
method: 'POST',
data: {
api_name: "hotel_list_value",
login_manager_id: PageThis.data.userInfo.manager_id
},
success: function (res) {
var data = res.data.data;
PageThis.setData({
"hotelValue": data
})
}
})
},
getPartnerList:function(){
var PageThis = this;
wx.request({
url: app.globalData.serverInfo.gateWayUrl,
header: {
'content-type': 'application/json'
},
method: 'POST',
data: {
api_name: "manager_list_value",
login_manager_id: PageThis.data.userInfo.manager_id
},
success: function (res) {
var data = res.data.data;
PageThis.setData({
"managerValue": data,
})
}
})
},
pickerChange:function(e){
var PageThis = this;
var name = e.currentTarget.dataset.name;
var val = e.detail.value;
switch(name){
case "hotel":
//hotelIndex存储picker选中【键值】
//hotelId存储picker选中【h_id】
PageThis.setData({
hotelIndex: e.detail.value,
hotelId: this.data.hotelValue[e.detail.value].h_id
})
break;
case "partner":
PageThis.setData({
managerIndex: e.detail.value,
managerId: this.data.managerValue[e.detail.value].manager_id
})
break;
case "start_time":
PageThis.setData({
start_time: val
})
break;
case "end_time":
PageThis.setData({
end_time: val
})
break;
}
},
inputChange:function(e){
var PageThis = this;
PageThis.setData({
"pay_no": e.detail.value
})
},
reset:function(){
var PageThis = this;
PageThis.setData({
pay_no: "",
hotelName: "请选择酒店",
hotel_id: 0,
partnerName: "请选择合伙人",
partner_id: 0,
start_time: "请选择开始时间",
end_time: "请选择结束时间",
})
}
})
\ No newline at end of file
{
"usingComponents": {}
}
\ No newline at end of file
<view class="input_box_item">
<view class="input_title">订单号</view>
<input placeholder="请输入搜索的字段" data-name="pay_no" value="{{pay_no}}" bindinput="inputChange"></input>
</view>
<view class="input_box_item">
<view class="input_title">酒店</view>
<picker range="{{hotelValue}}" value="{{hotelIndex}}" range-key="h_title" data-name="hotel" style="background-color:rgba(0,0,0,0);padding-left:0;margin-top:0 !important;" bindchange="pickerChange">
<input placeholder="{{hotelValue[hotelIndex].h_title}}" disabled="true"></input>
</picker>
</view>
<view class="input_box_item">
<view class="input_title">合伙人</view>
<picker range="{{managerValue}}" value="{{managerIndex}}" range-key="manager_username" data-name="partner" style="background-color:rgba(0,0,0,0);padding-left:0;margin-top:0 !important;" bindchange="pickerChange">
<input placeholder="{{managerValue[managerIndex].manager_username}}" disabled="true"></input>
</picker>
</view>
<view class="input_box_item">
<view class="input_title">付款时间</view>
<picker mode="date" fields="day" data-name="start_time" bindchange="pickerChange">
<span>{{start_time}}</span>
</picker>
<view class="link_icon">~</view>
<picker mode="date" fields="day" data-name="end_time" bindchange="pickerChange">
<span>{{end_time}}</span>
</picker>
</view>
<view class="serach_form_btn_box">
<view class="serach_form_btn active" bindtap="getOrdersList">搜索</view>
<view class="serach_form_btn" bindtap="reset">重置</view>
</view>
<view class="list_box">
<view class="orders_item" wx:for="{{ordersList}}" wx:key="k">
<view class="order_item_top">
<view class="order_item_hotel_name">
{{item.hotel_title}}
<span style='font-size:12px;font-weight: 500;'>
房间号:
<span style='color:red;'>
{{item.dev_hotel_room!=''?item.dev_hotel_room:"-"}}
</span>
</span>
</view>
<view class="orders_item_state" wx:if="{{item.pay_state == 10}}">未支付</view>
<view class="orders_item_state" wx:if="{{item.pay_state == 20}}">已支付</view>
<view class="orders_item_state" wx:if="{{item.pay_state == 21}}">申请退款</view>
<view class="orders_item_state" wx:if="{{item.pay_state == 22}}">退款中</view>
<view class="orders_item_state" wx:if="{{item.pay_state == 30}}">已退款</view>
<view class="orders_item_state" wx:if="{{item.pay_state == 31}}">部分退款</view>
<view class="orders_item_state" wx:if="{{item.pay_state == 40}}">已完成</view>
</view>
<view class="orders_goods" wx:for="{{item.detail_list}}" wx:for-item="goods" wx:key="k2">
<image src="{{goods.goods_cover}}"></image>
<view class="orders_goods_content">
<view>
<view class="orders_content_item orders_goods_name">{{goods.detail_goods_title}}</view>
<view class="orders_content_item red_color">¥{{goods.detail_goods_price}}</view>
</view>
<view>
<view class="orders_content_item">
<span>设备格子:</span>
<view class="ball_item">{{goods.detail_lat_title*1}}</view>
</view>
<view class="orders_content_item">设备号:{{item.pay_dev_no}}</view>
</view>
</view>
</view>
<view class="order_item_bottom">
<view class="order_item_info_box">
<view>订单号:{{item.pay_no}}</view>
<view>{{item.pay_create}} </view>
</view>
<view class="order_item_detail_box">
<view class="blue_color" bindtap="navigateTo" data-url="../separateDetail/index" data-id="{{item.pay_id}}">查看分成明细</view>
<view>实付金额:<span class="red_color">¥{{item.pay_real_money}}</span></view>
</view>
</view>
</view>
</view>
\ No newline at end of file
picker{
float: left;
width: 31vw;
height: 8vw;
background-color: rgb(248,248,248);
color: gray;
border-radius: 5px;
margin-top: 2vw !important;
margin-left: 0;
line-height: 8vw;
padding-left: 2vw;
font-size: 3.5vw;
}
input{
background-color: rgb(248,248,248);
padding-left: 2vw;
width: 69.5vw;
height: 8vw !important;
line-height: 8vw !important;
border-radius: 5px;
margin-top: 1vw !important;
}
.input_box_item{
width: 100%;
border-bottom: none;
height: 10vw;
line-height: 10vw;
overflow-x: hidden;
}
.input_title{
width: 20vw;
margin-left: 2vw;
height: 100%;
line-height: 10vw;
}
.link_icon{
height: 10vw;
line-height: 10vw;
float: left;
padding: 0 2vw;
}
.list_box{
width: 100%;
overflow-x: hidden;
}
.orders_item{
width: 100%;
background-color: #FFFFFF;
border-top: 3vw solid rgb(248,248,248);
border-bottom: 2px solid rgb(248,248,248);
}
.order_item_top{
width: 92%;
height: 14vw;
margin: 0 auto;
}
.order_item_hotel_name{
float: left;
font-size: 4.5vw;
height: 100%;
line-height: 14vw;
font-weight: bold;
}
.orders_item_state{
float: right;
background-color: rgb(118,173,255);
color: #FFFFFF;
border-radius: 4vw;
height: 7vw;
line-height: 7vw;
font-size: 3.5vw;
text-align: center;
width: 16vw;
margin: 3.5vw 0;
}
.orders_goods{
width: 100%;
background-color: rgb(248,248,248);
height: 24vw;
}
.orders_goods image{
width: 16vw;
height: 16vw;
background-size: 100% 100%;
margin: 4vw;
float: left;
}
.orders_goods_content{
float: left;
width: 72vw;
height: 22vw;
margin-top: 2vw;
}
.orders_content_item{
width: 55%;
float: left;
text-align: right;
font-size: 3.2vw;
color: #999999;
height: 4vw;
line-height: 4vw;
margin-top: 4vw;
font-weight: bold
}
.orders_content_item span{
float: left;
}
.orders_content_item:nth-child(odd){
width: 45% !important;
text-align: left !important;
}
.orders_goods_name{
font-size: 4vw;
color: #000000;
}
.ball_item{
float: left !important;
margin: 0 0.5vw 0 0!important;
width: 4vw !important;
height: 4vw !important;
line-height: 4vw !important;
text-align: center !important;
color: #FFFFFF !important;
background-color: rgb(55,126,232) !important;
border-radius: 50% !important;
font-size: 3.2vw !important;
}
.order_item_bottom{
height: 20vw;
width: 92vw;
margin: 0 auto;
}
.order_item_info_box{
color: #999999;
font-size: 3.2vw;
width: 100%;
padding-top: 4vw;
}
.order_item_info_box view:nth-child(1){
width: 65%;
float: left;
}
.order_item_info_box view:nth-child(2){
float: right;
}
.order_item_detail_box{
width: 100%;
font-size: 3.8vw;
padding-top: 7vw;
}
.order_item_detail_box view:nth-child(1){
float: left;
}
.order_item_detail_box view:nth-child(2){
color: #000000;
float: right;
}
\ No newline at end of file
// pages/ordersSalesStatistics/index.js
const app = getApp();
Page({
data: {
userInfo: {},
start_time:"请选择开始时间",
end_time:"请选择结束时间",
timeType:"day",
userName:"",
pageData:{
total_device_num:0,
total_hotel_num:0,
total_orders_num:0,
total_sep_money:0,
date_list:[]
}
},
onLoad: function (options) {
var item = ["按日","按月"];
var list = [];
for(var i in item){
var obj = {
"tabName":item[i],
"tabClass":"",
"tabIndex":i,
"tabContent":[]
}
list.push(obj);
}
list[0]['tabClass'] = "tab_item_active";
this.setData({
userInfo:wx.getStorageSync('userInfo'),
tabList:list
});
},
onShow: function () {
this.getData();
},
onTabItem(e){
var PageThis = this;
var index = e.currentTarget.dataset.page;
var tabList = PageThis.data.tabList;
for(var i in tabList){
if(Number(tabList[i].tabIndex) === Number(index)){
tabList[i].tabClass = "tab_item_active";
}else{
tabList[i].tabClass = "";
}
}
var timeType;
if(Number(index) == 0){
timeType = "day";
}else{
timeType = "month";
}
PageThis.setData({
tab_swiper_index:index,
tabList:tabList,
timeType:timeType
})
PageThis.reset();
PageThis.getData();
},
pickerChange: function (e) {
var PageThis = this;
var val = e.detail.value;
var name = e.target.dataset.name;
switch (name) {
case "start_time":
PageThis.setData({
start_time: val,
})
break;
case "end_time":
PageThis.setData({
end_time: val,
})
break;
}
},
inputChange:function(e){
var PageThis = this;
PageThis.setData({
"userName": e.detail.value
})
},
getData(){
var PageThis = this;
wx.request({
url:app.globalData.serverInfo.gateWayUrl,
header: {
'content-type': 'application/json'
},
method: 'POST',
data: {
api_name: "get_date_orders_count",
login_manager_id: PageThis.data.userInfo.manager_id,
username:PageThis.data.userName,
start_time: PageThis.data.start_time == "请选择开始时间" ? "" : PageThis.data.start_time,
end_time: PageThis.data.end_time == "请选择结束时间" ? "" : PageThis.data.end_time,
count_type:PageThis.data.timeType == "day" ? 1 : 2
},
success:function(res){
var data = res.data.data;
console.log(data.date_list)
PageThis.setData({
pageData:data
})
}
})
},
reset:function(){
var PageThis = this;
PageThis.setData({
userName: "",
start_time: "请选择开始时间",
end_time: "请选择结束时间",
})
}
})
\ No newline at end of file
{
"usingComponents": {}
}
\ No newline at end of file
<view class="tab_box">
<view wx:for="{{tabList}}" wx:key="k" class="tab_item {{item.tabClass}}" bindtap="onTabItem" data-page="{{item.tabIndex}}">{{item.tabName}}</view>
</view>
<view class="input_box_item" style="margin-top:1vw;border-top: 1px solid #eeeeee;padding-top:2vw">
<view class="input_title">用户名</view>
<input placeholder="请输入用户名" data-name="user_name" value="{{userName}}" bindinput="inputChange"></input>
</view>
<view class="input_box_item">
<view class="input_title">付款时间</view>
<picker mode="date" fields="{{timeType}}" data-name="start_time" bindchange="pickerChange">
<span>{{start_time}}</span>
</picker>
<view class="link_icon">~</view>
<picker mode="date" fields="{{timeType}}" data-name="end_time" bindchange="pickerChange">
<span>{{end_time}}</span>
</picker>
</view>
<view class="serach_form_btn_box">
<view class="serach_form_btn active" bindtap="getData">搜索</view>
<view class="serach_form_btn" bindtap="reset">重置</view>
</view>
<view class="data_box">
<view class="data_item">
<view>{{pageData.total_device_num}}</view>
<view>运营设备数</view>
</view>
<view class="data_item">
<view>{{pageData.total_hotel_num}}</view>
<view>酒店数</view>
</view>
<view class="data_item">
<view>{{pageData.total_orders_num}}</view>
<view>总成交量</view>
</view>
<view class="data_item">
<view>{{pageData.total_sep_money}}</view>
<view>总成交分成</view>
</view>
</view>
<view class="device_statistics_list">
<view class="device_statistics_item" wx:for="{{pageData.date_list}}" wx:key="k">
<view>{{item.date}}</view>
<view>共{{item.total_orders_num}}单</view>
<view>订单金额(元):<span class="blue_color">{{item.total_money}}</span></view>
<view>订单分成(元):<span class="blue_color">{{item.total_sep}}</span></view>
<view>扫码总数(次):<span class="blue_color">{{item.total_scan}}</span></view>
<view>扫码有效数(次):<span class="blue_color">{{item.total_valid_scan}}</span></view>
<view>蓝牙连接总数:<span class="blue_color">{{item.total_blue_tooth}}</span></view>
<view>蓝牙连接有效数:<span class="blue_color">{{item.total_valid_blue_tooth}}</span></view>
<view class="cb"></view>
</view>
</view>
\ No newline at end of file
.tab_item{
width: calc(100% / 2 - 40%);
margin: 0 20%;
}
picker{
float: left;
width: 31vw;
height: 8vw;
background-color: rgb(248,248,248);
color: gray;
border-radius: 5px;
margin-top: 2vw !important;
margin-left: 0;
line-height: 8vw;
padding-left: 2vw;
font-size: 3.5vw;
}
input{
background-color: rgb(248,248,248);
padding-left: 2vw;
width: 69.5vw;
height: 8vw !important;
line-height: 8vw !important;
border-radius: 5px;
margin-top: 1vw !important;
}
.input_box_item{
width: 100%;
border-bottom: none;
height: 10vw;
line-height: 10vw;
overflow-x: hidden;
}
.input_title{
width: 20vw;
margin-left: 2vw;
height: 100%;
line-height: 10vw;
}
.link_icon{
height: 10vw;
line-height: 10vw;
float: left;
padding: 0 2vw;
}
.data_box{
width: calc(90vw + 3px);
height: 24vw;
border-radius: 15px;
background-image: linear-gradient(90deg, #77adff 0%, #387ee8 100%);
color: #FFFFFF;
margin: 8vw auto;
}
.data_item{
width: calc(90vw / 4);
text-align: center;
float: left;
margin-top: 5vw;
}
.data_item:nth-child(2){
border-left: 1px solid rgb(128, 174, 248);
border-right: 1px solid rgb(106,160,245);
}
.data_item:nth-child(3){
border-right: 1px solid rgb(106,160,245);
}
.data_item view:nth-child(1){
font-size: 5vw;
height: 8vw;
line-height: 8vw;
}
.data_item view:nth-child(2){
font-size: 3vw;
height: 6vw;
line-height: 6vw;
}
.device_statistics_list{
width: 100%;
border-top: 3vw solid rgb(248,248,248);
}
.device_statistics_item{
color: #999999;
font-size: 3.5vw;
width: 94vw;
padding: 3vw;
border-bottom: 1px solid rgb(248,248,248);
}
.device_statistics_item view{
width: 50%;
float: left;
height: 8vw;
line-height: 8vw;
}
.device_statistics_item view:nth-child(1){
font-size: 4vw;
color: #000000;
}
.device_statistics_item view:nth-child(2){
color: #000000;
}
.device_statistics_item view:nth-child(2n){
text-align: right;
}
.blue_color{
color: rgb(55,126,232) !important;
}
\ No newline at end of file
// pages/refundList/index.js
const app = getApp();
Page({
data: {
userInfo: wx.getStorageSync('userInfo'),
payNo:"",
hotelName:"",
start_time:"请选择开始时间",
end_time:"请选择结束时间",
list:[]
},
onLoad: function (options) {
this.setData({
userInfo:wx.getStorageSync('userInfo')
})
},
onShow: function () {
this.getList();
},
pickerChange:function(e){
var PageThis = this;
var name = e.currentTarget.dataset.name;
var val = e.detail.value;
switch(name){
case "start_time":
PageThis.setData({
start_time: val
})
break;
case "end_time":
PageThis.setData({
end_time: val
})
break;
}
},
inputChange:function(e){
var PageThis = this;
var name = e.currentTarget.dataset.name;
switch(name){
case "pay_no":
PageThis.setData({
"payNo": e.detail.value
})
break;
case "hotel_name":
PageThis.setData({
"hotelName": e.detail.value
})
break;
}
},
reset:function(){
var PageThis = this;
PageThis.setData({
payNo: "",
hotelName: "",
start_time: "请选择开始时间",
end_time: "请选择结束时间",
})
},
getList(){
var PageThis = this;
wx.request({
url: app.globalData.serverInfo.gateWayUrl,
header: {
'content-type': 'application/json'
},
method: 'POST',
data: {
api_name: "get_refund_list",
orders_no: PageThis.data.payNo,
hotel_title: PageThis.data.hotelName,
login_manager_id: PageThis.data.userInfo.manager_id,
start_time: PageThis.data.start_time == "请选择开始时间" ? "" : PageThis.data.start_time,
end_time: PageThis.data.end_time == "请选择结束时间" ? "" : PageThis.data.end_time,
},
success: function (res) {
var data = res.data.data;
PageThis.setData({
list:data
})
}
})
},
handleMessage(e){
var PageThis = this;
var name = e.currentTarget.dataset.name;
var type = e.currentTarget.dataset.type;
var id = e.currentTarget.dataset.id;
var str = "";
var obj = {};
obj.api_name = name;
obj.login_manager_id = PageThis.data.userInfo.manager_id;
if(name == "auth_refund_orders"){
if(Number(type) == 1){
str = "确认通过该退款申请?";
}else if(Number(type) == 2){
str = "确认驳回该退款申请?";
}
obj.pay_id = id;
obj.result = type;
}else{
wx.showToast({
title: '未知类型',
icon: "none"
})
return;
}
wx.showModal({
title: '温馨提示',
content: str,
success(r){
if(r.confirm){
wx.request({
url: app.globalData.serverInfo.gateWayUrl,
header: {
'content-type': 'application/json'
},
method: 'POST',
data: obj,
success(res){
var ret = res.data;
if(Number(ret.state) === 1){
wx.showToast({
title: ret.msg,
})
PageThis.getList();
}else{
wx.showToast({
title: ret.msg,
icon: 'none'
})
}
}
})
}
}
})
}
})
\ No newline at end of file
{
"usingComponents": {}
}
\ No newline at end of file
<view class="input_box_item">
<view class="input_title">订单号</view>
<input placeholder="请输入订单号" data-name="pay_no" value="{{payNo}}" bindinput="inputChange"></input>
</view>
<view class="input_box_item">
<view class="input_title">酒店名称</view>
<input placeholder="请输入酒店名称" data-name="hotel_name" value="{{hotelName}}" bindinput="inputChange"></input>
</view>
<view class="input_box_item">
<view class="input_title">付款时间</view>
<picker mode="date" fields="day" data-name="start_time" bindchange="pickerChange">
<span>{{start_time}}</span>
</picker>
<view class="link_icon">~</view>
<picker mode="date" fields="day" data-name="end_time" bindchange="pickerChange">
<span>{{end_time}}</span>
</picker>
</view>
<view class="serach_form_btn_box">
<view class="serach_form_btn active" bindtap="getList">搜索</view>
<view class="serach_form_btn" bindtap="reset">重置</view>
</view>
<view class="message_box" wx:for="{{list}}" wx:key="k">
<view class="message_top">
<view class="message_title">
<view>{{item.hotel_title}}</view>
<view>{{item.pay_time}}</view>
</view>
<view wx:if="{{item.pay_state == 21}}">待审核</view>
<view wx:if="{{item.pay_state == 22}}">退款中</view>
<view wx:if="{{item.pay_state == 30}}">已退款</view>
<view wx:if="{{item.pay_state == 31}}">部分退款</view>
<view wx:if="{{item.pay_state == 32}}">拒绝退款</view>
<view class="cb"></view>
</view>
<view class="message_content">
<image src="{{item.goods_cover}}"></image>
<view class="message_content_text">
<view>{{item.detail_goods_title}}</view>
<view>订单号:{{item.pay_no}}</view>
<view>设备号:{{item.dev_no}}</view>
</view>
<view class="message_content_right">¥{{item.pay_real_money}}</view>
<view class="cb"></view>
</view>
<view class="message_bottom" wx:if="{{item.pay_state == 21}}">
<view class="message_btn" bindtap="handleMessage" data-name="auth_refund_orders" data-type="2" data-id="{{item.pay_id}}">驳回</view>
<view class="message_btn btn_main" bindtap="handleMessage" data-name="auth_refund_orders" data-type="1" data-id="{{item.pay_id}}">通过</view>
</view>
</view>
\ No newline at end of file
picker{
float: left;
width: 31vw;
height: 8vw;
background-color: rgb(248,248,248);
color: gray;
border-radius: 5px;
margin-top: 2vw !important;
margin-left: 0;
line-height: 8vw;
padding-left: 2vw;
font-size: 3.5vw;
}
input{
background-color: rgb(248,248,248);
padding-left: 2vw;
width: 69.5vw;
height: 8vw !important;
line-height: 8vw !important;
border-radius: 5px;
margin-top: 1vw !important;
}
.input_box_item{
width: 100%;
border-bottom: none;
height: 10vw;
line-height: 10vw;
overflow-x: hidden;
}
.input_title{
width: 20vw;
margin-left: 2vw;
height: 100%;
line-height: 10vw;
}
.link_icon{
height: 10vw;
line-height: 10vw;
float: left;
padding: 0 2vw;
}
\ No newline at end of file
// pages/register/index.js
const app = getApp();
Page({
/**
* 页面的初始数据
*/
data: {
account:'',
password:'',
name:'',
number:'',
},
formName:function(e){
this.setData({
name:e.detail.value
})
},
formAccount:function(e){
this.setData({
account:e.detail.value
})
},
formPassword:function(e){
this.setData({
password:e.detail.value
})
},
formNumber:function(e){
this.setData({
number:e.detail.value
})
},
registerGetBtn:function(){
if(this.data.account=="" || this.data.account.length !=6){
wx.showToast({
title: '请输入不少于6位字符的账号',
icon: 'none',
duration: 2000
})
return false;
}
if(this.data.password=="" || this.data.password.length !=6){
wx.showToast({
title: '请输入不少于6位字符的密码',
icon: 'none',
duration: 2000
})
return false;
}
if(this.data.number=="" || this.data.number.length !=11){
wx.showToast({
title: '请输入11位数字的手机号',
icon: 'none',
duration: 2000
})
return false;
}
if(this.data.name=="" || this.data.name.length<2){
wx.showToast({
title: '请输入正确的名字',
icon: 'none',
duration: 2000
})
return false;
}
console.log(this.data.account);
console.log(this.data.password);
console.log(this.data.name);
console.log(this.data.number);
wx.showToast({
title: '信息提交成功72小时内会有人工主动联系认证信息,认证通过开通相应账号的权限!',
icon: 'none',
duration: 5000
})
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
},
/**
* 生命周期函数--监听页面初次渲染完成
*/
onReady: function () {
},
/**
* 生命周期函数--监听页面显示
*/
onShow: function () {
},
/**
* 生命周期函数--监听页面隐藏
*/
onHide: function () {
},
/**
* 生命周期函数--监听页面卸载
*/
onUnload: function () {
},
/**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh: function () {
},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom: function () {
},
/**
* 用户点击右上角分享
*/
onShareAppMessage: function () {
}
})
\ No newline at end of file
{
"usingComponents": {}
}
\ No newline at end of file
<view class="registerWrap">
<view class="registerMain">
<view class="registerTip">请输入需要注册的账号</view>
<view class="registerBody">
<input value="" bindinput='formAccount' placeholder="请填写账号"></input>
</view>
</view>
<view class="registerMain">
<view class="registerTip">请输入账号的密码</view>
<view class="registerBody">
<input value="" bindinput='formPassword' placeholder="请填写密码"></input>
</view>
</view>
<view class="registerMain">
<view class="registerTip">请输入手机号码</view>
<view class="registerBody">
<input value="" bindinput='formNumber' placeholder="请输入手机号码"></input>
</view>
</view>
<view class="registerMain">
<view class="registerTip">请输入姓名</view>
<view class="registerBody">
<input value="" bindinput='formName' placeholder="请输入姓名"></input>
</view>
</view>
</view>
<view class="tipWrap">信息提交成功后72小时内会有人工主动联系认证信息,认证通过开通相应账号的权限!</view>
<view class="registerGetInfoWrap">
<view class="registerGetBtn" bindtap="registerGetBtn">提交信息</view>
</view>
\ No newline at end of file
/* pages/register/index.wxss */
page{
background-color: #F7F7F7;
}
.registerWrap{
width: 100%;
background-color: white;
padding-bottom: 10px;
}
.registerMain{
width: 90%;
margin: 10px auto 0;
padding: 10px 0 0;
}
.registerTip{
font-size: 14px;
}
.registerBody{
margin-top: 5px;
}
.registerBody>input{
border-bottom: 1px solid #F7F7F7;
height: 45px;
}
.tipWrap{
font-size: 14px;
text-align: center;
padding: 15px;
color: red;
}
.registerGetInfoWrap{
width: 100%;
position: fixed;
left: 0;
bottom: 10px;
}
.registerGetBtn{
width: 90%;
margin: 0 auto;
height: 45px;
line-height: 45px;
border-radius: 5px;
text-align: center;
background-color: #00BB11;
color: white;
}
\ No newline at end of file
const app = getApp()
Page({
data: {
listData: [
{
icon: '../../images/icons/icon(19).png',
title: '智能补货',
url: '../noStockDevice/index'
},
{
icon: '../../images/icons/icon(20).png',
title: '补货记录',
url: '../replenishmentRecord/index'
},
{
icon: '../../images/icons/icon(21).png',
title: '重置设备',
url: '../resetDevice/index'
},
]
},
//**页面跳转 */
navigateTo: function (e) {
var _url = e.currentTarget.dataset.url;
wx.navigateTo({
url: _url
})
},
})
\ No newline at end of file
{
"usingComponents": {}
}
\ No newline at end of file
<view id="top_banner">
<image class="banner_img" src="../../images/top_banner/top_banner(5).png"></image>
</view>
<view id="block_item_box">
<view class="block_item" wx:for="{{listData}}" wx:key="k" bindtap="navigateTo" data-url="{{item.url}}">
<image class="block_item_img" src="{{item.icon}}"></image>
<view class="block_item_title">{{item.title}}</view>
</view>
</view>
\ No newline at end of file
const app = getApp();
Page({
data: {
userInfo: wx.getStorageSync('userInfo'),
deviceId:0,
devInfo:{},
_deviceId:"",
_mac:"",
deviceId:"",
serviceId:"F000AA50-0451-4000-B000-000000000000",
writeCharacteristic:"F000AA51-0451-4000-B000-000000000000",
readCharacteristic:"F000AA52-0451-4000-B000-000000000000",
countCharacteristic:"F000AA53-0451-4000-B000-000000000000",
mac:"",
count:"",
power:"",
code:"",
move:"",
D600:null
},
onLoad: function (options) {
var id = options.id;
var PageThis = this;
PageThis.setData({
userInfo:wx.getStorageSync('userInfo')
})
this.setData({
deviceId: id
})
this.getDeviceDetail();
},
onUnload(){
this.closeBluetoothAdapter();
this.closeBLEConnection();
var D600 = that.data.D600;
if(D600 != null){
D600.closeBluetoothAdapter();
D600.closeBLEConnection();
}
},
/**获取设备 */
getDeviceDetail: function () {
var PageThis = this;
var id = PageThis.data.deviceId;
wx.request({
url: app.globalData.serverInfo.gateWayUrl,
header: {
'content-type': 'application/json'
},
method: 'POST',
data: {
api_name: "device_detail",
device_id: id,
login_manager_id: PageThis.data.userInfo.manager_id
},
success: function (res) {
PageThis.setData({
"devInfo": res.data.data,
"_mac": res.data.data.dev_mac
})
PageThis.openBluetoothAdapter();
}
})
},
/**
* 打开格子
*/
openLat(e){
var that = this;
var dev_info = that.data.devInfo;
var name = e.currentTarget.dataset.name;
if(Number(dev_info['dev_version']) === 4){
var D600 = that.data.D600;
if(D600 != null){
D600.openLat(name);
}
}
},
/**
* 打开所有格子
*/
openAllLat(){
var that = this;
var dev_info = that.data.devInfo;
if(Number(dev_info['dev_version']) === 4){
var D600 = that.data.D600;
if(D600 != null){
D600.openNoStockLat();
}
}
},
// 初始化蓝牙适配器
openBluetoothAdapter() {
var that = this;
that.closeBluetoothAdapter();
that.closeBLEConnection();
wx.openBluetoothAdapter({
success: function (res) {
console.log("初始化蓝牙适配器成功");
that.startBluetoothDevicesDiscovery();
},
fail: function (err) {
wx.showModal({
title: '温馨提示',
content: '请先打开手机蓝牙,然后点击确认连接设备',
success (res) {
if (res.confirm) {
that.openBluetoothAdapter();
} else if (res.cancel) {
console.log('用户点击取消')
}
}
})
console.log(err, "初始化蓝牙适配器失败");
}
})
},
// 开始搜索蓝牙设备
startBluetoothDevicesDiscovery() {
var that = this;
wx.startBluetoothDevicesDiscovery({
powerLevel:"low",
success: function (res) {
console.log("蓝牙搜索中...");
wx.showLoading({
title: '设备搜索中',
})
var times = 0;
var timer = setInterval(() => {
that.getBluetoothDevices();
times++;
if(times >= 5){
wx.hideLoading();
clearInterval(timer);
that.stopBluetoothDevicesDiscovery();
wx.showModal({
title: "温馨提示",
content: "请按设备任意按钮激活蓝牙,再点击确定重新连接",
success (res) {
if (res.confirm) {
that.startBluetoothDevicesDiscovery();
} else if (res.cancel) {
console.log('用户点击取消')
}
}
})
}
},2000);
that.setData({
timer:timer
})
}
})
},
//获取已发现的蓝牙设备列表
getBluetoothDevices() {
var that = this;
wx.getBluetoothDevices({
success: function (res) {
var devInfo = that.data.devInfo;
res.devices.forEach(item => {
if(Number(devInfo['dev_version']) === 4 && item.localName == devInfo['dev_no'] && item.advertisServiceUUIDs[0] == "6E400001-B5A3-F393-E0A9-E50E24DCCA9E"){
var file = require("../../utils/D600.js");
clearInterval(that.data.timer);
that.stopBluetoothDevicesDiscovery();
var D600 = new file(devInfo['dev_no'],item.deviceId);
D600.createBLEConnection().then(function(ret){
console.log(ret);
var isConnect = ret;
if(isConnect){
D600.readPower();
setTimeout(() => {
var power = D600.getPower();
power = (Number(power)/4)*100;
if(power > 100){
power = 100;
}else{
power = power.toFixed(2);
}
that.reportElectric(power);
}, 2000);
}
});
that.setData({
D600:D600
})
}else if (item.localName == "OrgboxMini" || item.name == "TI BLE Sensor Tag") {
var mac = that.buf2hex(item.advertisData);
mac = mac.toUpperCase();
var new_mac = "";
for(var i in mac){
new_mac += mac[i];
if(i%2 != 0 && i != 11){
new_mac += ":";
}
}
if(new_mac == that.data._mac){
clearInterval(that.data.timer);
that.stopBluetoothDevicesDiscovery();
that.createBLEConnection(item.deviceId);
that.setData({
deviceId:item.deviceId,
mac:new_mac
})
}
}
});
}
})
},
//停止搜索设备
stopBluetoothDevicesDiscovery() {
wx.stopBluetoothDevicesDiscovery({
success: function (res) {
console.log("停止搜索设备" + JSON.stringify(res.errMsg))
}
})
},
//创建蓝牙连接
createBLEConnection(deviceId) {
var that = this;
wx.showLoading({
title: '设备连接中',
duration: 99999,
mask: true
})
wx.createBLEConnection({
deviceId: deviceId,
success: function (res) {
wx.getBLEDeviceServices({
deviceId: deviceId,
success: function (res) {
that.getBLEDeviceCharacteristics()
},
fail: function (err) {
console.log(err, "蓝牙连接失败getBLEDeviceServices")
}
})
},
fail: function (err) {
console.log(err, "蓝牙连接失败createBLEConnection")
}
})
},
// 获取该服务的特征值
getBLEDeviceCharacteristics() {
var that = this;
wx.getBLEDeviceCharacteristics({
deviceId: that.data.deviceId,
serviceId: that.data.serviceId,
success: function (res) {
that.notifyBLECharacteristicValueChange(that.data.deviceId, that.data.serviceId, that.data.readCharacteristic);
},
fail: function (err) {
console.log(err, "获取该服务失败getBLEDeviceCharacteristics")
}
})
},
// 监听蓝牙返回值
notifyBLECharacteristicValueChange(deviceId, serviceId, characteristicId) {
var that = this;
wx.notifyBLECharacteristicValueChange({
deviceId: deviceId,
serviceId: serviceId,
characteristicId: characteristicId,
state: true,
success: function (res) {
console.log('使能成功', res);
wx.showToast({
title: '连接成功',
duration: 3000,
icon: 'success'
})
that.onBLECharacteristicValueChange();
wx.readBLECharacteristicValue({
characteristicId: that.data.countCharacteristic,
deviceId: that.data.deviceId,
serviceId: that.data.serviceId,
success:function(ret){
console.log(ret);
},fail:function(err){
console.log(err);
console.log(that.data.deviceId);
console.log(that.data.serviceId);
console.log(that.data.countCharacteristic);
}
})
},
fail: function (err) {
wx.hideLoading({
complete: (res) => {
},
})
wx.showToast({
title: '蓝牙连接失败,errCode:'+err.errCode,
icon:"none"
})
console.log("监听失败", err, deviceId, serviceId, characteristicId)
}
})
},
// 获取返回值
onBLECharacteristicValueChange() {
var that = this;
wx.onBLECharacteristicValueChange(function (res) {
var turn_back = that.hex2str(that.buf2hex(res.value));
turn_back = turn_back.replace(/\ +/g,"");
turn_back = turn_back.replace(/[ ]/g,"");
turn_back = turn_back.replace(/[\r\n]/g,"");
console.log("最终转回来的值",turn_back);
}, function (err) {
console.log(err)
})
},
// 发送指令API
writeBLECharacteristicValue(hex,characteristic){
var that = this;
var buffer = new ArrayBuffer(hex.length);
console.log(hex);
if(hex){
console.log(hex);
for(var i in hex){
new DataView(buffer).setInt8(i,Number(hex.charCodeAt(i)));
}
}else{
console.log("未输入指令");
return;
}
console.log(buffer);
wx.writeBLECharacteristicValue({
deviceId: that.data.deviceId,
serviceId: that.data.serviceId,
characteristicId: characteristic,
value: buffer,
success: function (res) {
console.log("发送指令成功")
},
fail: function (err) {
console.log("指令发送失败", err)
}
})
},
closeBluetoothAdapter() {
wx.closeBluetoothAdapter({
success(res) {
console.log("断开蓝牙模块", res);
}
})
},
closeBLEConnection() {
var that = this;
wx.closeBLEConnection({
deviceId: that.data.deviceId,
success(res) {
console.log("断开蓝牙连接", res);
that.setData({
mac:"",
count:"",
power:"",
})
wx.showToast({
title: '已断开连接',
icon:"none"
})
}
})
},
buf2hex: function (buffer) { // buffer is an ArrayBuffer
return Array.prototype.map.call(new Uint8Array(buffer), x => ('00' + x.toString(16)).slice(-2)).join('');
},
// 16进制转字符串
hex2str(hex) {
var rawStr = hex.substr(0, 2).toLowerCase() === "0x" ? hex.substr(2) : hex;
var len = rawStr.length;
if (len % 2 !== 0) {
alert("Illegal Format ASCII Code!");
return "";
}
var curCharCode;
var resultStr = [];
for (var i = 0; i < len; i = i + 2) {
curCharCode = parseInt(rawStr.substr(i, 2), 16);
resultStr.push(String.fromCharCode(curCharCode));
}
return resultStr.join("");
},
// 字符串转16进制
str2hex(str) {
if (str === "") {
return "";
}
var arr = [];
// arr.push("0x");
for (var i = 0; i < str.length; i++) {
arr.push(str.charCodeAt(i).toString(16));
}
return arr.join('');
},
/**
* 确认补货完成
*/
sureRep:function(){
var PageThis = this;
wx.showModal({
title: '提示',
content: '确认已完成补货?',
success(res) {
if (res.confirm) {
PageThis.uploadData();
} else if (res.cancel) {
}
}
})
},
/**
* 上报信息
*/
uploadData:function(){
var PageThis = this;
var latList = PageThis.data.devInfo.lat_list;
var uploadList = [];
for(var i in latList){
if (latList[i].lat_op_state > 0 && latList[i].noStockState != 1){
uploadList.push({
lat_id:latList[i].lat_id,
rep_goods_id:latList[i].lat_goods_id
});
}
}
wx.request({
url: app.globalData.serverInfo.gateWayUrl,
header: {
'content-type': 'application/json'
},
method: 'POST',
data: {
api_name: "rep_lat_goods",
device_id: PageThis.data.devInfo.dev_id,
login_manager_id: PageThis.data.userInfo.manager_id,
rep_list: uploadList,
count:PageThis.data.count
},
success:function(res){
var data = res.data;
console.log(res);
if (Number(data.state) == 1){
wx.showToast({
title: '补货成功',
icon: 'success',
duration: 2000,
});
PageThis.closeBluetoothAdapter();
PageThis.closeBLEConnection();
setTimeout(function(){
wx.navigateBack();
},1500)
}else{
wx.showToast({
title: data.msg,
icon: 'none',
duration: 2000,
});
}
}
})
},
/**
* 上报缺货
*/
reportNoStock:function(e){
var PageThis = this;
var devInfo = PageThis.data.devInfo;
var id = e.currentTarget.dataset.id;
for (var i in devInfo.lat_list){
if (devInfo.lat_list[i].lat_id == id){
devInfo.lat_list[i].noStockState = 1;
}
}
PageThis.setData({
devInfo: devInfo
});
wx.showToast({
title: '设置成功',
icon: 'success',
duration: 1000,
});
},
/**
* 上报电量
*/
reportElectric:function(num){
var PageThis = this;
var devInfo = PageThis.data.devInfo;
devInfo['dev_electric_quantity'] = num;
PageThis.setData({
devInfo:devInfo,
})
wx.request({
url: app.globalData.serverInfo.gateWayUrl,
header: {
'content-type': 'application/json'
},
method: 'POST',
data: {
api_name: "report_device_electric",
dev_id: PageThis.data.devInfo.dev_id,
device_electric: num,
login_manager_id: PageThis.data.userInfo.manager_id
},
success:function(res){
console.log(res)
}
})
}
})
\ No newline at end of file
{
"usingComponents": {}
}
\ No newline at end of file
<view class="rep_top">
<view class="img_list_item">
<image src="../../images/icons/logo.png"></image>
<view class="item_text_box">
<view class="item_text">设备编号:{{devInfo.dev_no}}</view>
<view class="item_text">设备地址:{{devInfo.dev_room_address}}</view>
<view class="item_text">设备电量:{{devInfo.dev_electric_quantity}}%</view>
</view>
</view>
<view class="radian_btn" bindtap="openAllLat">一键补货</view>
<view class="radian_btn shadow_btn"></view>
</view>
<view id="goods_list_box">
<view class="goods_item" wx:for="{{devInfo.lat_list}}" wx:key="k">
<view class="goods_img_box">
<image class="goods_img" src="{{item.g_cover}}"></image>
<view wx:if="{{item.lat_op_state == 1}}" class="sold_out_cover">待补货</view>
<view wx:elif="{{item.lat_op_state == 2}}" class="sold_out_cover">待换货</view>
<view wx:elif="{{item.lat_op_state == 3}}" class="sold_out_cover">待上货</view>
<view wx:elif="{{item.lat_op_state == 4}}" class="sold_out_cover">待清空</view>
</view>
<view>
<view class="goods_title"><span class="blue_color">NO.{{item.lat_title}}</span> {{item.g_title}}</view>
</view>
<view class="cb"></view>
<view>
<view class="goods_btn" data-name="{{item.lat_title}}" bindtap="openLat">补货开锁</view>
<view wx:if="{{item.noStockState != 1}}" class="goods_btn2" data-id="{{item.lat_id}}" bindtap="reportNoStock">商品缺货</view>
<view wx:if="{{item.noStockState == 1}}" class="goods_btn2" data-id="{{item.lat_id}}" style="background-color:gray !important">商品缺货</view>
</view>
</view>
<view class="cb"></view>
</view>
<view class="radian_main_btn" bindtap="sureRep" style="margin-bottom:5vw;">补货完成</view>
\ No newline at end of file
.rep_top{
width: 100%;
height: 40vw;
background-color: #77adff;
background-image: linear-gradient(90deg, #77adff 0%, #387ee8 100%);
position: absolute;
top: 0;
left: 0;
}
.img_list_item{
background-color: rgba(0,0,0,0) !important;
border-bottom: none;
color:#FFFFFF;
padding-top: 2vw !important;
}
.item_text{
font-size: 3.8vw !important;
}
.item_text:nth-child(1){
font-size: 4.5vw !important;
}
.radian_btn,.shadow_btn{
position: absolute;
top: 34vw;
left: 5vw;
}
.shadow_btn{
z-index: -1;
-moz-box-shadow:2px 4px 5px 2px #f2f3f3;
-webkit-box-shadow:2px 4px 5px 2px #f2f3f3;
box-shadow:2px 4px 5px 2px #f2f3f3;
}
#goods_list_box{
width: 100vw;
background-color:rgb(248,248,248);
margin-top: 50vw;
}
.goods_item{
width: 47vw;
margin-left: 2vw;
border-radius: 5px;
background-color: #FFFFFF;
height: 67vw;
overflow: hidden;
float: left;
margin-bottom: 2vw;
-moz-box-shadow:2px 4px 5px 2px #f2f3f3;
-webkit-box-shadow:2px 4px 5px 2px #f2f3f3;
box-shadow:2px 4px 5px 2px #f2f3f3;
}
.goods_img_box{
width: 100%;
height: 47vw;
position: relative;
}
.goods_img{
width: 100%;
height: 100%;
background-size: 100%;
position: absolute;
left: 0;
top: 0;
}
.sold_out_cover{
width: 100%;
height: 100%;
background-image: linear-gradient(45deg,rgba(0,0,0,0.5) 25%,rgba(75,75,75,0.5) 0,rgba(75,75,75,0.5) 50%,rgba(0,0,0,0.5) 0,rgba(0,0,0,0.5) 75%,rgba(75,75,75,0.5) 0);
background-size: 10px 10px;
line-height: 47vw;
text-align: center;
font-size: 5vw;
color: #FFFFFF;
z-index: 5;
position: absolute;
top: 0;
left: 0;
}
.goods_title{
float: left;
font-size: 4vw;
margin-left: 3vw;
margin-top: 1vw;
width: 40vw;
overflow: hidden;
text-overflow:ellipsis;
white-space: nowrap;
}
.goods_btn,.goods_btn2{
width: 20vw;
text-align: center;
color: #FFFFFF;
height: 6.5vw;
line-height: 6.5vw;
font-size: 3.5vw;
float: left;
background-color: rgb(55,126,232);
border-radius: 6vw;
margin-left: 2vw;
margin-top: 4.2vw;
}
.goods_btn2{
background-color: rgb(97,216,236) !important;
float: right !important;
margin-left: 0 !important;
margin-right: 2vw !important;
}
\ No newline at end of file
const app = getApp();
Page({
data: {
userInfo: wx.getStorageSync('userInfo'),
dev_no: "",
hotelList: [],
hotelValue: [],
hotelName: "请选择酒店",
hotel_id: "",
partnerList: [],
partnerValue: [],
partnerName: "请选择补货员",
partner_id: "",
start_time: "请选择开始时间",
end_time: "请选择结束时间",
recordList: []
},
onLoad: function (options) {
var PageThis = this;
PageThis.setData({
userInfo:wx.getStorageSync('userInfo')
})
},
onShow: function(){
this.getRepList();
this.getHotelList();
this.getPartnerList();
},
getRepList:function(){
var PageThis = this;
wx.request({
url: app.globalData.serverInfo.gateWayUrl,
header: {
'content-type': 'application/json'
},
method: 'POST',
data: {
api_name: "get_rep_list",
dev_no: PageThis.data.dev_no,
hotel_id: PageThis.data.hotel_id,
rep_manager_id: PageThis.data.partner_id,
start_time: PageThis.data.start_time == "请选择开始时间" ? "" : PageThis.data.start_time,
end_time: PageThis.data.end_time == "请选择结束时间" ? "" : PageThis.data.end_time,
login_manager_id: PageThis.data.userInfo.manager_id
},
success:function(res){
var data = res.data.data;
PageThis.setData({
"recordList": data
})
}
})
},
getHotelList: function () {
var PageThis = this;
wx.request({
url: app.globalData.serverInfo.gateWayUrl,
header: {
'content-type': 'application/json'
},
method: 'POST',
data: {
api_name: "hotel_list",
login_manager_id: PageThis.data.userInfo.manager_id
},
success: function (res) {
var data = res.data.data;
var hotelList = [];
for (var i in data) {
hotelList.push(data[i].h_title)
}
hotelList.push("全部");
PageThis.setData({
"hotelList": hotelList,
"hotelValue": data
})
}
})
},
getPartnerList: function () {
var PageThis = this;
wx.request({
url: app.globalData.serverInfo.gateWayUrl,
header: {
'content-type': 'application/json'
},
method: 'POST',
data: {
api_name: "manager_list",
login_manager_id: PageThis.data.userInfo.manager_id
},
success: function (res) {
var data = res.data.data;
var managerList = [];
var managerValue = [];
for (var i in data) {
if (data[i].manager_type == 7) {
managerList.push(data[i]['manager_username']);
managerValue.push(data[i])
}
}
managerList.push("全部");
PageThis.setData({
"partnerList": managerList,
"partnerValue": managerValue
})
}
})
},
pickerChange: function (e) {
var PageThis = this;
var name = e.currentTarget.dataset.name;
var val = e.detail.value;
switch (name) {
case "hotel":
var hotelList = PageThis.data.hotelList;
var hotelValue = PageThis.data.hotelValue;
if (hotelValue == hotelList.length) {
PageThis.setData({
"hotelName": "请选择酒店",
"hotelId": 0
})
} else {
PageThis.setData({
"hotelName": hotelList[val],
"hotelId": hotelValue[val]['h_id']
})
}
break;
case "partner":
var partnerList = PageThis.data.partnerList;
var partnerValue = PageThis.data.partnerValue;
if (partnerValue == partnerList.length) {
PageThis.setData({
"partnerName": "请选择补货员",
"partnerId": 0
})
} else {
PageThis.setData({
"partnerName": partnerList[val],
"partnerId": partnerValue[val]['h_id']
})
}
break;
case "start_time":
PageThis.setData({
start_time: val
})
break;
case "end_time":
PageThis.setData({
end_time: val
})
break;
}
},
inputChange: function (e) {
var PageThis = this;
PageThis.setData({
"dev_no": e.detail.value
})
},
reset: function () {
var PageThis = this;
PageThis.setData({
dev_no: "",
hotelName: "请选择酒店",
hotel_id: 0,
partnerName: "请选择补货员",
partner_id: 0,
start_time: "请选择开始时间",
end_time: "请选择结束时间",
})
}
})
\ No newline at end of file
{
"usingComponents": {}
}
\ No newline at end of file
<view class="input_box_item">
<view class="input_title">设备号</view>
<input placeholder="请输入设备号" data-name="dev_no" value="{{dev_no}}"></input>
</view>
<view class="input_box_item">
<view class="input_title">酒店</view>
<picker range="{{hotelList}}" data-name="hotel" style="background-color:rgba(0,0,0,0);padding-left:0;margin-top:0 !important;" bindchange="pickerChange">
<input placeholder="{{hotelName}}" disabled="true"></input>
</picker>
</view>
<view class="input_box_item">
<view class="input_title">补货员</view>
<picker range="{{partnerList}}" data-name="partner" style="background-color:rgba(0,0,0,0);padding-left:0;margin-top:0 !important;" bindchange="pickerChange">
<input placeholder="{{partnerName}}" disabled="true"></input>
</picker>
</view>
<view class="input_box_item">
<view class="input_title">补货时间</view>
<picker mode="date" fields="day" data-name="start_time" bindchange="pickerChange">
<span>{{start_time}}</span>
</picker>
<view class="link_icon">~</view>
<picker mode="date" fields="day" data-name="end_time" bindchange="pickerChange">
<span>{{end_time}}</span>
</picker>
</view>
<view class="serach_form_btn_box">
<view class="serach_form_btn active" bindtap="getRepList">搜索</view>
<view class="serach_form_btn" bindtap="reset">重置</view>
</view>
<view class="list_box">
<view class="item" wx:for="{{recordList}}">
<view class="item_top">
<image src="../../images/icons/icon(48).png"></image>
<view>{{item.hotel_title}}</view>
</view>
<view class="item_content_box">
<view class="item_content">
<view>补货格子:</view>
<view class="ball_item" wx:for="{{item.lattice_list}}" wx:key="k2" wx:for-item="lat">{{lat.lat_title*1}}</view>
</view>
<view class="item_content">{{item.manager_nickname}}</view>
<view class="item_content">设备号:{{item.dev_no}}</view>
<view class="item_content">{{item.rep_time}}</view>
<view class="cb"></view>
</view>
</view>
</view>
\ No newline at end of file
picker{
float: left;
width: 31vw;
height: 8vw;
background-color: rgb(248,248,248);
color: gray;
border-radius: 5px;
margin-top: 2vw !important;
margin-left: 0;
line-height: 8vw;
padding-left: 2vw;
font-size: 3.5vw;
}
input{
background-color: rgb(248,248,248);
padding-left: 2vw;
width: 69.5vw;
height: 8vw !important;
line-height: 8vw !important;
border-radius: 5px;
margin-top: 1vw !important;
}
.input_box_item{
width: 100%;
border-bottom: none;
height: 10vw;
line-height: 10vw;
}
.input_title{
width: 20vw;
margin-left: 2vw;
height: 100%;
line-height: 10vw;
}
.link_icon{
height: 10vw;
line-height: 10vw;
float: left;
padding: 0 2vw;
}
.ball_item{
float: left !important;
margin: 2vw 0.5vw 0 0!important;
width: 4vw !important;
height: 4vw !important;
line-height: 4vw !important;
text-align: center !important;
color: #FFFFFF !important;
background-color: rgb(55,126,232) !important;
border-radius: 50% !important;
font-size: 3.2vw !important;
}
.list_box{
border-top: 3vw solid rgb(248,248,248);
}
.item{
width: 92vw;
padding: 4vw;
background-color: #FFFFFF;
border-bottom: 1px solid rgb(248,248,248)
}
.item_top{
width: 100%;
height: 8vw;
}
.item_top image{
width: 5vw;
height: 5vw;
background-size: 100% 100%;
float: left;
margin-top: 0.5vw;
}
.item_top view{
float: left;
font-size: 4.2vw;
padding-left: 2vw;
}
.item_content_box view{
float: left;
color: #999999;
}
.item_content{
width: 50%;
text-align: right;
font-size: 3.5vw;
height: 8vw;
line-height: 8vw;
}
.item_content:nth-child(odd){
text-align: left !important;
}
\ No newline at end of file
// pages/resetDevice/index.js
const app = getApp();
Page({
data: {
userInfo: wx.getStorageSync('userInfo'),
},
onLoad: function (options) {
var PageThis = this;
PageThis.setData({
userInfo:wx.getStorageSync('userInfo')
})
},
scanQrCode:function(){
wx.scanCode({
success: (res) => {
var url = res.result;
var devCode = url.replace(app.globalData.serverInfo.qrReplaceUrl,"");
wx.request({
url: app.globalData.serverInfo.gateWayUrl,
header: {
'content-type': 'application/json'
},
method: 'POST',
data: {
api_name: "reset_device_info",
dev_no: devCode,
login_manager_id: PageThis.data.userInfo.manager_id
},
success:function(res){
var res = res.data;
if(res.state == 1){
wx.showToast({
title: '重置成功',
icon: "success",
duration: 2000
})
}else{
wx.showToast({
title: res.msg,
icon: "none",
duration: 2000
})
}
}
})
},
fail: (res) => {
console.log(res);
}
})
}
})
\ No newline at end of file
{
"usingComponents": {}
}
\ No newline at end of file
<image id="resetDevice_img" src="../../images/icons/resetDevice.png" bindtap="scanQrCode"></image>
<view id="resetDevice_tips" bindtap="scanQrCode">点击扫码</view>
\ No newline at end of file
#resetDevice_img{
width: 60vw;
height: 60vw;
background-size: 100% 100%;
margin: 40vw 20vw 0 20vw;
}
#resetDevice_tips{
font-size: 4.5vw;
color: rgb(172,188,212);
width: 100%;
text-align: center;
margin-top: 5vw;
}
\ No newline at end of file
// pages/roomHelper/index.js
const app = getApp();
Page({
/**
* 页面的初始数据
*/
data: {
new_room:"",
},
getInputValueRoom(e){
this.setData({
new_room: e.detail.value,
})
},
snoScan:function(){
var PageThis = this;
wx.scanCode({
success (res) {
var scan_url = res.result;
var thisDevNo = scan_url.replace(app.globalData.serverInfo.qrReplaceUrl, '');
if(thisDevNo.length!=10){
wx.showToast({
title: '无效二维码:'+thisDevNo,
icon: 'none',
duration:3000
})
return false;
}
PageThis.getDeviceData(thisDevNo);
}
})
},
getDeviceData:function(self){
var PageThis = this;
wx.request({
url: app.globalData.serverInfo.gateWayUrl,
header: {
'content-type': 'application/json'
},
method: 'POST',
data: {
api_name: "post_no_device_detail",
login_manager_id: PageThis.data.userInfo.manager_id,
device_no: self
},
success:function(ret){
var thisData = ret.data.data;
PageThis.setData({
"deviceData": thisData
})
wx.showToast({
title: ret.data.msg,
icon: 'none',
duration:3000
})
}
})
},
updateDeviceRoom:function(){
var PageThis = this;
wx.request({
url: app.globalData.serverInfo.gateWayUrl,
header: {
'content-type': 'application/json'
},
method: 'POST',
data: {
api_name: "update_device_room",
login_manager_id: PageThis.data.userInfo.manager_id,
device_id: PageThis.data.deviceData.dev_id,
device_room: PageThis.data.new_room,
},
success:function(ret){
wx.showToast({
title: ret.data.msg,
icon: 'none',
duration:3000
})
}
})
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
var PageThis = this;
PageThis.setData({
userInfo:wx.getStorageSync('userInfo')
})
},
/**
* 生命周期函数--监听页面初次渲染完成
*/
onReady: function () {
},
/**
* 生命周期函数--监听页面显示
*/
onShow: function () {
},
/**
* 生命周期函数--监听页面隐藏
*/
onHide: function () {
},
/**
* 生命周期函数--监听页面卸载
*/
onUnload: function () {
},
/**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh: function () {
},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom: function () {
},
/**
* 用户点击右上角分享
*/
onShareAppMessage: function () {
}
})
\ No newline at end of file
{
"usingComponents": {}
}
\ No newline at end of file
<view class="listWrap">
<view class="listMain">
<view class="listLeft">设备编号</view>
<view class="listRight">
<input catchtap="snoScan" placeholder='请点击右侧扫描设备二维码按钮' value="{{deviceData.dev_no}}" type='number' disabled ></input>
<image src="/images/scan.png" mode="aspectFill" catchtap="snoScan"></image>
</view>
</view>
<view class="listMain">
<view class="listLeft">原房间号</view>
<view class="listRight">
<input placeholder='原房间号' value="{{deviceData.dev_hotel_room}}" type='number'></input>
</view>
</view>
<view class="listMain">
<view class="listLeft">新房间号</view>
<view class="listRight">
<input bindinput="getInputValueRoom" placeholder='请输入新房间号' value="{{new_room}}" type='number'></input>
</view>
</view>
</view>
<view class="main_btn" bindtap="updateDeviceRoom">保存</view>
\ No newline at end of file
/* pages/tool/plan.wxss */
page{
background-color: #f8f8f8;
}
.listWrap{
width: 100%;
margin-top: 10px;
}
.listMain{
height: 45px;
line-height: 45px;
background-color: white;
width: 100%;
border-bottom: 1px solid #f8f8f8;
}
.listLeft{
width: 25%;
float: left;
text-align: center;
}
.listRight{
width: 75%;
float: left;
position: relative;
}
.listRight input{
height: 45px;
}
.listRight image{
position: absolute;
top: 10px;
right: 20px;
height: 25px;
width: 25px;
}
\ No newline at end of file
// pages/separateDetail/index.js
const app = getApp();
Page({
data: {
userInfo: wx.getStorageSync('userInfo'),
payId: 0,
info:{},
list:[]
},
onLoad: function (option) {
var id = option.id;
var PageThis = this;
PageThis.setData({
userInfo:wx.getStorageSync('userInfo')
})
this.setData({
"payId":id
})
},
onShow: function () {
this.getDetail();
},
getDetail:function(){
var PageThis = this;
wx.request({
url: app.globalData.serverInfo.gateWayUrl,
header: {
'content-type': 'application/json'
},
method: 'POST',
data: {
api_name: "get_orders_separate",
pay_id: PageThis.data.payId,
login_manager_id: PageThis.data.userInfo.manager_id
},
success:function(res){
console.log(res.data.data);
PageThis.setData({
"info": res.data.data[0],
"list": res.data.data
})
}
})
},
refundOrders:function(){
var PageThis = this;
wx.request({
url: app.globalData.serverInfo.gateWayUrl,
header: {
'content-type': 'application/json'
},
method: 'POST',
data: {
api_name: "auth_refund_orders",
result: 1,
pay_id: PageThis.data.payId,
login_manager_id: PageThis.data.userInfo.manager_id
},
success:function(res){
wx.showToast({
title: res.data.msg,
icon:'none'
})
setTimeout(function () {
wx.switchTab({
url: '../index/index',
})
}, 1500);
}
})
}
})
\ No newline at end of file
{
"usingComponents": {}
}
\ No newline at end of file
<view class="orders_item">
<view class="order_item_bottom">
<view class="order_item_info_box">
<view>订单号:{{info.sep_out}}</view>
<view>{{info.pay_create}} </view>
</view>
<view class="order_item_detail_box">
<view>订单金额:
<span class="red_color">¥{{info.sep_total_money}}</span>
</view>
</view>
</view>
</view>
<view class="statistics_list_box">
<view class="statistics_list_title">
<view>分成人名称</view>
<view>分成比例</view>
<view>分成金额</view>
</view>
<view class="statistics_list_item" wx:for="{{list}}" wx:key="k">
<view>{{item.manager_nickname}}</view>
<view>{{item.sep_percent*1}}%</view>
<view>{{item.sep_money}}</view>
</view>
</view>
<view class="refundOrdersWrap" wx:if="{{userInfo.manager_level == 1 || userInfo.manager_type == 1}}">
<view class="refundOrders" bindtap="refundOrders">立即退款</view>
</view>
\ No newline at end of file
.input_box_item{
width: 100%;
border-bottom: none;
height: 10vw;
line-height: 10vw;
}
.input_title{
width: 20vw;
margin-left: 2vw;
height: 100%;
line-height: 10vw;
}
.link_icon{
height: 10vw;
line-height: 10vw;
float: left;
padding: 0 2vw;
}
.list_box{
width: 100%;
}
.orders_item{
width: 100%;
background-color: #FFFFFF;
border-bottom: 2px solid rgb(248,248,248);
}
.order_item_top{
width: 92%;
height: 14vw;
margin: 0 auto;
}
.order_item_hotel_name{
float: left;
font-size: 4.5vw;
height: 100%;
line-height: 14vw;
font-weight: bold;
}
.orders_item_state{
float: right;
background-color: rgb(118,173,255);
color: #FFFFFF;
border-radius: 4vw;
height: 7vw;
line-height: 7vw;
font-size: 3.5vw;
text-align: center;
width: 16vw;
margin: 3.5vw 0;
}
.order_item_bottom{
height: 20vw;
width: 92vw;
margin: 0 auto;
}
.order_item_info_box{
color: #999999;
font-size: 3.2vw;
width: 100%;
padding-top: 4vw;
}
.order_item_info_box view:nth-child(1){
width: 60%;
float: left;
}
.order_item_info_box view:nth-child(2){
float: right;
}
.order_item_detail_box{
width: 100%;
font-size: 3.8vw;
padding-top: 7vw;
}
.order_item_detail_box view:nth-child(1){
float: left;
}
.order_item_detail_box view:nth-child(2){
color: #000000;
float: right;
}
.statistics_list_box{
width: 93vw;
margin: 0 auto;
border-top: 3vw solid rgb(248,248,248);
padding: 0 3.5vw;
}
.statistics_list_title,.statistics_list_item{
width: 90vw;
height: 12vw;
line-height: 12vw;
padding: 0 1.5vw;
border-bottom: 1px solid rgb(248,248,248);
font-size: 3.8vw;
}
.statistics_list_title view,.statistics_list_item view{
width: 30vw;
color: rgb(150,150,150);
height: 100%;
float: left;
}
.statistics_list_title view:nth-child(2){
text-align: center;
}
.statistics_list_title view:nth-child(3){
text-align: center;
}
.statistics_list_item view{
color: #000000;
}
.statistics_list_item view:nth-child(2){
color: rgb(106,160,245);
text-align: center;
}
.statistics_list_item view:nth-child(3){
text-align: center;
color: rgb(106,160,245);
}
.refundOrdersWrap{
width: 100vw;
position: fixed;
left: 0;
bottom: 5vh;
}
.refundOrders{
width: 92vw;
margin: 0 auto;
height: 45px;
line-height: 45px;
background-color: #DD5145;
color: #FFFFFF;
border-radius: 5px;
text-align: center;
}
\ No newline at end of file
// pages/shortageList/index.js
const app = getApp();
Page({
/**
* 页面的初始数据
*/
data: {
userInfo:[]
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
var PageThis = this;
PageThis.setData({
userInfo:wx.getStorageSync('userInfo')
})
},
/**
* 生命周期函数--监听页面初次渲染完成
*/
onReady: function () {
},
/**
* 生命周期函数--监听页面显示
*/
onShow: function () {
},
/**
* 生命周期函数--监听页面隐藏
*/
onHide: function () {
},
/**
* 生命周期函数--监听页面卸载
*/
onUnload: function () {
},
/**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh: function () {
},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom: function () {
},
/**
* 用户点击右上角分享
*/
onShareAppMessage: function () {
}
})
\ No newline at end of file
{
"usingComponents": {}
}
\ No newline at end of file
<view class="shortage_item">
<view class="shortage_top">
<image class="shortage_hotel_icon" src="../../images/icons/icon(47).png"></image>
<view class="shortage_hotel_name">希尔顿酒店</view>
<image class="shortage_more_icon" src="../../images/icons/icon(56).png"></image>
</view>
<view class="shortage_content">
<view class="shortage_content_nav"></view>
<view class="shortage_content_top">
<view class="shortage_content_top_item">
<view>类型</view>
<image src="../../images/icons/icon(37).png"></image>
</view>
<view class="shortage_content_top_item">
<view>房间</view>
<view>8603</view>
</view>
<view class="shortage_content_top_item">
<view>设备号</view>
<view>C1904005628</view>
</view>
<view class="shortage_content_top_item">
<view>缺货格子</view>
<view>
<view class="ball_item">1</view>
<view class="ball_item">3</view>
<view class="ball_item">6</view>
</view>
</view>
<view class="cb"></view>
</view>
<view class="shortage_content_bottom">
<view class="shortage_goods_label">缺货商品明细</view>
<view class="shortage_goods_title">
<view>商品图片</view>
<view>商品名称</view>
<view>缺货柜子</view>
<view>缺货数量</view>
<view class="cb"></view>
</view>
<view class="shortage_goods_item">
<view class="shortage_goods_item_cell">
<image src="../../images/icons/logo.png"></image>
</view>
<view class="shortage_goods_item_cell">电动牙刷</view>
<view class="shortage_goods_item_cell">
<view class="ball_item">1</view>
</view>
<view class="blue_color shortage_goods_item_cell">
x1
</view>
</view>
<view class="cb"></view>
<view class="shortage_goods_item">
<view class="shortage_goods_item_cell">
<image src="../../images/icons/logo.png"></image>
</view>
<view class="shortage_goods_item_cell">毛巾</view>
<view class="shortage_goods_item_cell">
<view class="ball_item">3</view>
<view class="ball_item">6</view>
</view>
<view class="blue_color shortage_goods_item_cell">
x2
</view>
</view>
<view class="cb"></view>
</view>
</view>
</view>
<image class="add_btn" src="../../images/icons/icon(34).png"></image>
\ No newline at end of file
.shortage_item{
width: 92vw;
margin: 4vw auto 0 auto;
border-radius: 10px;
overflow: hidden;
-moz-box-shadow:2px 4px 5px 2px #f2f3f3;
-webkit-box-shadow:2px 4px 5px 2px #f2f3f3;
box-shadow:2px 4px 5px 2px #f2f3f3;
padding-bottom: 2vw;
}
.shortage_top{
width: 100%;
height: 15vw;
line-height: 15vw;
color: #FFFFFF;
background-color: rgb(55,126,232);
font-size: 4vw;
border-radius: 10px;
}
.shortage_hotel_icon{
float: left;
width: 5vw;
height: 5vw;
margin: 5vw 5vw;
}
.shortage_hotel_name{
float: left;
}
.shortage_more_icon{
float: right;
width: 3.4vw;
height: 3.4vw;
margin: 5.8vw 5vw;
}
.shortage_content{
margin-top: -10px;
}
.shortage_content_nav{
width: 100%;
height: 10px;
background-color: rgb(55,126,232);
}
.shortage_content_top{
border-bottom: 1px solid rgb(248,248,248);
padding: 2vw 0;
}
.shortage_content_top_item{
float: left;
font-size: 3.4vw;
}
.shortage_content_top_item view{
height: 4vw;
line-height:4vw;
margin: 4vw;
}
.shortage_content_top_item view:nth-child(1){
color: #999999;
width: 100%;
}
.shortage_content_top_item image{
width: 7vw;
height: 7vw;
background-size: 100% 100%;
margin-left: 4vw;
margin-top: -1.5vw;
}
.shortage_content_top_item:nth-child(-n+2){
width: 15vw;
}
.shortage_content_top_item:nth-child(3){
width: 25vw;
}
.shortage_content_top_item:nth-child(4){
width: 35vw;
margin-left: 2vw;
}
.ball_item{
float: left !important;
margin: 0 0.5vw 0 0!important;
width: 4vw !important;
height: 4vw !important;
line-height: 4vw !important;
text-align: center !important;
color: #FFFFFF !important;
background-color: rgb(55,126,232) !important;
border-radius: 50% !important;
font-size: 3.2vw !important;
}
.shortage_goods_label{
color: rgb(148,170,201);
font-size: 3.5vw;
margin: 4vw;
}
.shortage_goods_title{
margin-bottom: 3.5vw;
}
.shortage_goods_title,.shortage_goods_item{
width: 92vw;
padding: 0 4vw;
color: #999999;
font-size: 3.5vw;
}
.shortage_goods_item{
height: 8vw;
line-height: 8vw;
}
.shortage_goods_item .ball_item{
margin-top: 2vw !important;
}
.shortage_goods_title view,.shortage_goods_item_cell{
float: left;
width: 20vw;
}
.shortage_goods_title view:nth-child(3),.shortage_goods_item_cell:nth-child(3){
width: 30vw;
text-align: left;
}
.shortage_goods_title view:nth-child(4),.shortage_goods_item_cell:nth-child(4){
width: 16vw;
text-align: center;
}
.shortage_goods_item_cell{
color: #000000;
font-size: 3.5vw;
}
.shortage_goods_item_cell image{
width: 8vw;
height: 8vw;
background-size: 100% 100%;
margin: 0 3vw;
}
const app = getApp()
Page({
data: {
bottomNavList: app.globalData.bottomNavList,
bootomNavIndex: 2,
listData: [
{
icon: '../../images/icons/icon(12).png',
title: '商品统计',
url: '../goodsSalesStatistics/index',
index:0
},
{
icon: '../../images/icons/icon(14).png',
title: '酒店统计',
url: '../hotelSalesStatistics/index',
index:0
},
{
icon: '../../images/icons/icon(15).png',
title: '设备统计',
url: '../deviceSalesStatistics/index',
index:0
},
{
icon: '../../images/icons/icon(20).png',
title: '订单统计',
url: '../ordersSalesStatistics/index',
index:0
},
{
icon: '../../images/icons/icon(17).png',
title: '用户统计',
url: '../userStatistics/index',
index:0
},
{
icon: '../../images/icons/icon(24).png',
title: '扫码记录',
url: '../deviceOrdersCount/index',
index:0
}
]
},
//**页面跳转 */
navigateTo: function (e) {
var _url = e.currentTarget.dataset.url;
wx.navigateTo({
url: _url,
})
},
onLoad: function () {
var PageThis = this;
PageThis.setData({
userInfo:wx.getStorageSync('userInfo')
});
},
})
\ No newline at end of file
{
"navigationBarTitleText": "统计",
"usingComponents": {}
}
\ No newline at end of file
<view id="top_banner">
<image class="banner_img" src="../../images/top_banner/top_banner(4).png"></image>
</view>
<view id="block_item_box">
<view class="block_item" wx:for="{{listData}}" wx:key="k" bindtap="navigateTo" data-url="{{item.url}}" wx:if="{{userInfo.manager_type!=7}}">
<image class="block_item_img" src="{{item.icon}}"></image>
<view class="block_item_title">{{item.title}}</view>
</view>
</view>
/* pages/statistics/index.wxss */
\ No newline at end of file
const app = getApp()
Page({
data: {
userInfo:[],
bottomNavList: app.globalData.bottomNavList,
bootomNavIndex: 3,
listData : [
{
icon : '../../images/icons/icon(11).png',
title : 'D600专用',
url : '../deployToolSec/index'
},
{
icon : '../../images/icons/icon(11).png',
title : '扫码绑定',
url : '../warehouse/index'
},
{
icon : '../../images/icons/icon(11).png',
title : '设置方案',
url : '../tool/plan'
},
{
icon : '../../images/icons/icon(11).png',
title : '房间助手',
url : '../roomHelper/index'
},
]
},
onLoad(options){
var PageThis = this;
PageThis.setData({
userInfo:wx.getStorageSync('userInfo')
})
},
//**页面跳转 */
navigateTo: function (e) {
var PageThis = this;
var _url = e.currentTarget.dataset.url;
if (_url == "../warehouse/index"){
wx.scanCode({
scanType:['qrCode'],
success (res) {
console.log(res)
var scan_url = res.result;
var code = scan_url.replace(app.globalData.serverInfo.qrReplaceUrl,'');
if(code != ""){
wx.showModal({
title: '绑定设备',
content: '确定绑定设备编号为:'+code+"的设备?",
success (res) {
if (res.confirm) {
wx.request({
url: app.globalData.serverInfo.gateWayUrl,
header: {
'content-type': 'application/json'
},
method: 'POST',
data: {
api_name: "scan_qr_bind_device",
device_no: code,
login_manager_id: PageThis.data.userInfo.manager_id
},
success:function(res){
var data = res.data;
if(Number(data.state) === 1){
wx.showToast({
title: '绑定成功',
})
}else{
wx.showToast({
title: data.msg,
icon:"none"
})
}
}
})
} else if (res.cancel) {
console.log('用户点击取消')
}
}
})
}
}
})
}else{
wx.navigateTo({
url: _url,
})
}
},
})
\ No newline at end of file
{
"usingComponents": {}
}
\ No newline at end of file
<view id="top_banner">
<image class="banner_img" src="../../images/top_banner/top_banner(3).png"></image>
</view>
<view id="block_item_box">
<view class="block_item" wx:for="{{listData}}" wx:key="k" bindtap="navigateTo" data-url="{{item.url}}" wx:if="{{userInfo.manager_type!=7}}">
<image class="block_item_img" src="{{item.icon}}"></image>
<view class="block_item_title">{{item.title}}</view>
</view>
</view>
/* pages/storehouse/index.wxss */
\ No newline at end of file
// pages/tool/plan.js
const app = getApp();
Page({
/**
* 页面的初始数据
*/
data: {
userInfo: wx.getStorageSync('userInfo'),
replenishment: ['否', '是'],
replenishmentIndex: 0,
planIndex: 0,
s_no: "",
e_no: "",
gp_id:0,
},
bindPickerChange: function(e) {
this.setData({
planIndex: e.detail.value,
gp_id: this.data.planList[e.detail.value].gp_id
})
console.log(this.data.gp_id)
},
replenishmentChange: function(e) {
this.setData({
replenishmentIndex: e.detail.value
})
},
getInputValueSno(e){
this.setData({
s_no: e.detail.value,
})
},
getInputValueEno(e){
this.setData({
e_no: e.detail.value,
})
},
snoScan:function(){
var PageThis = this;
wx.scanCode({
success (res) {
var scan_url = res.result;
var thisDevNo = scan_url.replace(app.globalData.serverInfo.qrReplaceUrl, '');
if(thisDevNo.length!=10){
wx.showToast({
title: '无效二维码:'+thisDevNo,
icon: 'none',
duration:3000
})
return false;
}
if(PageThis.data.e_no==0){
PageThis.setData({
"s_no": thisDevNo,
"e_no": thisDevNo
})
}else{
PageThis.setData({
"s_no": thisDevNo
})
}
}
})
},
enoScan:function(){
var PageThis = this;
wx.scanCode({
success (res) {
var scan_url = res.result;
var thisDevNo = scan_url.replace(app.globalData.serverInfo.qrReplaceUrl, '');
if(thisDevNo.length!=10){
wx.showToast({
title: '无效二维码:'+thisDevNo,
icon: 'none',
duration:3000
})
return false;
}
PageThis.setData({
"e_no": thisDevNo
})
}
})
},
getPlanList:function(){
var PageThis = this;
var thisPlan = [{ gp_id: 0, gp_title: "请选择" }]
wx.request({
url: app.globalData.serverInfo.gateWayUrl,
header: {
'content-type': 'application/json'
},
method: 'POST',
data: {
api_name: "goods_plan",
login_manager_id: PageThis.data.userInfo.manager_id
},
success:function(ret){
var thisData = ret.data.data;
for (var i = 0; i < thisData.length; i++) {
var thisFor = { gp_id: thisData[i]['gp_id'],gp_title: thisData[i]['gp_title'] }
thisPlan.push(thisFor);
}
PageThis.setData({
"planList": thisPlan
})
}
})
},
devicePlan:function(){
var PageThis = this;
if(PageThis.data.gp_id<=0){
wx.showToast({
title: '请选择商品方案',
icon: 'none',
})
return false;
}
if(PageThis.data.s_no<=0 ||PageThis.data.s_no.length!=10){
wx.showToast({
title: '请填写正确开始设备编号',
icon: 'none',
})
return false;
}
if(PageThis.data.e_no<=0 ||PageThis.data.e_no.length!=10){
wx.showToast({
title: '请填写正确结束设备编号',
icon: 'none',
})
return false;
}
wx.request({
url: app.globalData.serverInfo.gateWayUrl,
header: {
'content-type': 'application/json'
},
method: 'POST',
data: {
api_name: "bind_device_goods_plan",
gp_id: PageThis.data.gp_id,
fill_stock: PageThis.data.replenishmentIndex,
dev_id: 0,
dev_start: PageThis.data.s_no,
dev_end: PageThis.data.e_no,
login_manager_id: PageThis.data.userInfo.manager_id
},
success:function(ret){
console.log(ret);
wx.showToast({
title: ret.data.msg,
icon: 'none',
duration: 2000
});
}
})
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
var PageThis = this;
PageThis.setData({
userInfo:wx.getStorageSync('userInfo')
})
this.getPlanList();
},
/**
* 生命周期函数--监听页面初次渲染完成
*/
onReady: function () {
},
/**
* 生命周期函数--监听页面显示
*/
onShow: function () {
},
/**
* 生命周期函数--监听页面隐藏
*/
onHide: function () {
},
/**
* 生命周期函数--监听页面卸载
*/
onUnload: function () {
},
/**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh: function () {
},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom: function () {
},
/**
* 用户点击右上角分享
*/
onShareAppMessage: function () {
}
})
\ No newline at end of file
{
"usingComponents": {}
}
\ No newline at end of file
<view class="listWrap">
<view class="listMain">
<view class="listLeft">商品方案</view>
<view class="listRight">
<picker bindchange="bindPickerChange" value="{{planIndex}}" range="{{planList}}" range-key="gp_title">
<view class="picker">
{{planList[planIndex].gp_title}}
</view>
</picker>
</view>
</view>
<view class="listMain">
<view class="listLeft">是否补满</view>
<view class="listRight">
<picker bindchange="replenishmentChange" value="{{replenishmentIndex}}" range="{{replenishment}}">
<view class="picker">
{{replenishment[replenishmentIndex]}}
</view>
</picker>
</view>
</view>
<view class="listMain">
<view class="listLeft">开始设备</view>
<view class="listRight">
<input bindinput="getInputValueSno" placeholder='输入内容' value="{{s_no}}" type='number'></input>
<image src="/images/scan.png" mode="aspectFill" bindtap="snoScan"></image>
</view>
</view>
<view class="listMain">
<view class="listLeft">结束设备</view>
<view class="listRight">
<input bindinput="getInputValueEno" placeholder='输入内容' value="{{e_no}}" type='number'></input>
<image src="/images/scan.png" mode="aspectFill" bindtap="enoScan"></image>
</view>
</view>
</view>
<view class="main_btn" bindtap="devicePlan">保存</view>
\ No newline at end of file
/* pages/tool/plan.wxss */
page{
background-color: #f8f8f8;
}
.listWrap{
width: 100%;
margin-top: 10px;
}
.listMain{
height: 45px;
line-height: 45px;
background-color: white;
width: 100%;
border-bottom: 1px solid #f8f8f8;
}
.listLeft{
width: 25%;
float: left;
text-align: center;
}
.listRight{
width: 75%;
float: left;
position: relative;
}
.listRight input{
height: 45px;
}
.listRight image{
position: absolute;
top: 10px;
right: 20px;
height: 25px;
width: 25px;
}
\ No newline at end of file
// pages/trainInfo/index.js
const app = getApp();
Page({
data: {
userInfo:{},
tabList:[],
list:[],
tab_index:1
},
onLoad: function (options) {
var item = ["培训资料","培训视频"];
var list = [];
for(var i in item){
var obj = {
"tabName":item[i],
"tabClass":"",
"tabIndex":i,
"tabContent":[]
}
list.push(obj);
}
list[0]['tabClass'] = "tab_item_active";
this.setData({
userInfo:wx.getStorageSync('userInfo'),
tabList:list
});
},
onShow: function () {
this.getList();
},
onTabItem(e){
var PageThis = this;
var index = e.currentTarget.dataset.page;
var tabList = PageThis.data.tabList;
for(var i in tabList){
if(Number(tabList[i].tabIndex) === Number(index)){
tabList[i].tabClass = "tab_item_active";
}else{
tabList[i].tabClass = "";
}
}
PageThis.setData({
tab_index:Number(index)+1,
tabList:tabList
})
},
getList(){
var PageThis = this;
wx.request({
url: app.globalData.serverInfo.gateWayUrl,
header: {
'content-type': 'application/json'
},
method: 'POST',
data: {
api_name: "get_train_info",
login_manager_id: PageThis.data.userInfo.manager_id,
},
success:function(res){
var data = res.data.data;
PageThis.setData({
list:data
})
}
})
},
//**页面跳转 */
navigateTo: function (e) {
var _url = e.currentTarget.dataset.url;
var _id = e.currentTarget.dataset.id;
wx.navigateTo({
url: _url + "?id=" + _id,
})
}
})
\ No newline at end of file
{
"usingComponents": {}
}
\ No newline at end of file
<view class="tab_box">
<view wx:for="{{tabList}}" wx:key="k" class="tab_item {{item.tabClass}}" bindtap="onTabItem" data-page="{{item.tabIndex}}">{{item.tabName}}</view>
</view>
<view style="height:5vw"></view>
<view class="train_box" wx:for="{{list}}" wx:if="{{item.train_type == tab_index}}" wx:key="k">
<view class="train_title">{{item.train_title}}</view>
<view class="train_list">
<view class="train_item" data-id="{{item.train_id}}" bindtap="navigateTo" data-url="../trainInfoDetail/index">
<view>{{item.train_introduce}}</view>
<image src="../../images/icons/icon(55).png"></image>
<view class="cb"></view>
</view>
</view>
</view>
.tab_item{
width: calc(100% / 2 - 30%);
margin: 0 15%;
}
.train_box{
width: 95vw;
margin: 0 2.5vw;
line-height: 10vw;
font-size: 4vw;
border-bottom: 1px solid #eeeeee;
}
.train_title{
color: #42A5F5;
}
.train_item{
width: 95%;
margin-left: 5%;
border-top: 1px solid #efefef;
color: #F4834A;
}
.train_item view{
float: left;
}
.train_item image{
width: 4vw;
height: 4vw;
margin: 3vw;
background-size: 100% 100%;
float: right;
}
\ No newline at end of file
// pages/trainInfoDetail/index.js
const app = getApp();
Page({
data: {
id:0,
pageData:{}
},
onLoad: function (options) {
var id = options.id;
this.setData({
id: id,
userInfo:wx.getStorageSync('userInfo')
})
},
onShow: function () {
this.getData();
},
getData(){
var PageThis = this;
wx.request({
url: app.globalData.serverInfo.gateWayUrl,
header: {
'content-type': 'application/json'
},
method: 'POST',
data: {
api_name: "get_train_detail",
train_id: PageThis.data.id,
login_manager_id: PageThis.data.userInfo.manager_id
},
success: function (res) {
var data = res.data.data;
// data.train_content = JSON.parse(data.train_content);
PageThis.setData({
pageData:data
})
}
})
}
})
\ No newline at end of file
{
"usingComponents": {}
}
\ No newline at end of file
<rich-text nodes="{{pageData.train_content}}"></rich-text>
\ No newline at end of file
/* pages/trainInfoDetail/index.wxss */
\ No newline at end of file
// pages/updateCard/index.js
const app = getApp();
Page({
data: {
userInfo: wx.getStorageSync('userInfo'),
cardId: 0,
cardInfo: {}
},
onLoad:function(options){
var id = options.id;
var PageThis = this;
PageThis.setData({
userInfo:wx.getStorageSync('userInfo')
})
this.setData({
cardId: id
})
this.getCardDetail();
},
getCardDetail: function () {
var PageThis = this;
var id = PageThis.data.cardId;
wx.request({
url: app.globalData.serverInfo.gateWayUrl,
header: {
'content-type': 'application/json'
},
method: 'POST',
data: {
api_name: "get_bank_card_detail",
card_id: id,
login_manager_id: PageThis.data.userInfo.manager_id
},
success: function (res) {
var data = res.data.data;
PageThis.setData({
"cardInfo": data
})
}
})
},
createCard: function () {
var PageThis = this;
var cardInfo = PageThis.data.cardInfo;
cardInfo['api_name'] = "update_bank_card";
cardInfo['login_manager_id'] = PageThis.data.userInfo.manager_id
wx.request({
url: app.globalData.serverInfo.gateWayUrl,
header: {
'content-type': 'application/json'
},
method: 'POST',
data: cardInfo,
success: function (res) {
res = res.data;
if (res.state == 1) {
wx.showToast({
title: '保存成功',
icon: 'success',
duration: 1500,
})
setTimeout(function () {
wx.navigateBack()
}, 1500);
} else {
wx.showToast({
title: res.msg,
icon: 'none',
duration: 2000,
})
}
}
})
},
inputChange: function (e) {
var PageThis = this;
var name = e.currentTarget.dataset.name;
var data = PageThis.data.cardInfo;
data[name] = e.detail.value;
PageThis.setData({
"cardInfo": data
})
},
})
\ No newline at end of file
{
"usingComponents": {}
}
\ No newline at end of file
<view class="info_item">
<view class="info_title">银行卡号</view>
<input placeholder="请输入银行卡号" bindinput="inputChange" data-name="card_no" value="{{cardInfo.card_no}}"></input>
</view>
<view class="info_item">
<view class="info_title">银行名称</view>
<input placeholder="请输入银行名称" bindinput="inputChange" data-name="card_bank" value="{{cardInfo.card_bank}}"></input>
</view>
<view class="info_item">
<view class="info_title">开户行名称</view>
<input placeholder="请输入开户行名称" bindinput="inputChange" data-name="card_open_bank" value="{{cardInfo.card_open_bank}}"></input>
</view>
<view class="info_item">
<view class="info_title">持卡人姓名</view>
<input placeholder="请输入持卡人姓名" bindinput="inputChange" data-name="card_name" value="{{cardInfo.card_name}}"></input>
</view>
<view class="info_item">
<view class="info_title">预留手机号</view>
<input placeholder="请输入预留手机号" bindinput="inputChange" data-name="card_mobile" value="{{cardInfo.card_mobile}}"></input>
</view>
<view class="info_item">
<view class="info_title">身份证号</view>
<input placeholder="请输入身份证号" bindinput="inputChange" data-name="card_identify" type="idcard" value="{{cardInfo.card_identify}}"></input>
</view>
<view class="main_btn" bindtap="createCard">保存</view>
\ No newline at end of file
/* pages/updateCard/index.wxss */
\ No newline at end of file
// pages/createGoods/index.js
const app = getApp();
Page({
data: {
userInfo: wx.getStorageSync('userInfo'),
mainImg: {
filePath: "../../images/icons/add_img.png",
isUpload: 0,
uploadPath: "",
type: "main",
size: 0
},
cateTitle: "请选择商品分类",
detailImg: [],
detailImgCount: 0,
cateList: [],
cateValue: [],
goodsInfo: {},
radioList:[
{
"name":"营业额分成",
"value":1,
"checked":true
},
{
"name":"利润分成",
"value":2,
"checked":false
}
]
},
onLoad: function (options) {
var id = options.id;
var PageThis = this;
PageThis.setData({
userInfo:wx.getStorageSync('userInfo')
})
this.getGoodsInfo(id);
this.getGoodsCate();
},
getGoodsInfo:function(id){
var PageThis = this;
wx.request({
url: app.globalData.serverInfo.gateWayUrl,
header: {
'content-type': 'application/json'
},
method: 'POST',
data: {
api_name: "goods_detail",
goods_id: id,
login_manager_id: PageThis.data.userInfo.manager_id
},
success:function(ret){
var data = ret.data.data;
var imgList = data['g_pic']?JSON.parse(data['g_pic']):[];
var radioList = PageThis.data.radioList;
var detailImg = [];
for(var i in imgList){
var obj = {
filePath:imgList[i],
isUpload: 1,
uploadPath: imgList[i],
type: "detail",
}
detailImg.push(obj);
}
if(Number(data['g_money_type']) != 1){
radioList[1].checked = true;
radioList[0].checked = "";
}
PageThis.setData({
goodsInfo:data,
mainImg:{
filePath: data['g_cover'],
isUpload: 1,
uploadPath: data['g_cover'],
type: "main",
},
detailImg: detailImg,
detailImgCount: detailImg.length,
cateTitle: data['c_title'],
radioList:radioList
})
}
})
},
getGoodsCate: function () {
var PageThis = this;
wx.request({
url: app.globalData.serverInfo.gateWayUrl,
header: {
'content-type': 'application/json'
},
method: 'POST',
data: {
api_name: "goods_cate",
login_manager_id: PageThis.data.userInfo.manager_id
},
success: function (res) {
var data = res.data.data;
var cateList = [];
for (var i in data) {
cateList.push(data[i].c_title);
}
PageThis.setData({
"cateValue": data,
"cateList": cateList
})
}
})
},
chooseImage: function (e) {
var PageThis = this;
var count = 1;
var type = e.currentTarget.dataset.type;
if (type == "detail") {
count = 10 - PageThis.data.detailImg.length;
}
wx.chooseImage({
count: count,
sizeType: ['original'],
sourceType: ['album'],
success: function (res) {
if (type == "main") {
PageThis.setData({
"mainImg": {
"filePath": res.tempFiles[0].path,
"isUpload": 0,
"uploadPath": "",
"type": "main",
"size": res.tempFiles[0].size
}
})
} else {
var imgs = PageThis.data.detailImg;
for (var i in res.tempFilePaths) {
var obj = {
"filePath": res.tempFiles[i].path,
"isUpload": 0,
"uploadPath": "",
"type": "detail",
"size": res.tempFiles[i].size,
};
imgs.push(obj);
}
PageThis.setData({
"detailImg": imgs,
"detailImgCount": PageThis.data.detailImgCount + res.tempFilePaths.length
})
}
},
})
},
delImage: function (e) {
var PageThis = this;
var name = e.currentTarget.dataset.name;
var data = PageThis.data.detailImg;
var new_data = [];
var new_num = 0;
for (var i in data) {
if (data[i]['filePath'] != name) {
new_data.push(data[i])
new_num++;
}
}
PageThis.setData({
detailImg: new_data,
detailImgCount: new_num
})
},
inputChange: function (e) {
var PageThis = this;
var name = e.currentTarget.dataset.name;
var data = PageThis.data.goodsInfo;
data[name] = e.detail.value;
PageThis.setData({
"goodsInfo": data
})
},
radioChange(e){
var PageThis = this;
var goodsInfo = PageThis.data.goodsInfo;
goodsInfo['g_money_type'] = e.detail.value;
PageThis.setData({
"goodsInfo":goodsInfo
})
},
cateChange: function (e) {
var PageThis = this;
var id = e.detail.value;
var cateList = PageThis.data.cateList;
var cateValue = PageThis.data.cateValue;
var goodsInfo = PageThis.data.goodsInfo;
for (var i in cateValue) {
if (cateValue[i]['c_title'] == cateList[id]) {
goodsInfo['g_cate_id'] = cateValue[i]['c_id']
}
}
PageThis.setData({
"cateTitle": cateList[id],
"goodsInfo": goodsInfo
})
},
uploadImgs: function () {
var PageThis = this;
var data = [PageThis.data.mainImg];
var detailImg = PageThis.data.detailImg;
for (var i in detailImg) {
data.push(detailImg[i]);
}
wx.showToast({
title: '图片上传中',
icon: 'loading',
duration: 99999
})
var img_interval = setInterval(function () {//轮询图片是否上传完成
var flag = true;
for (var i in data) {
if (data[i].isUpload != 1) {
flag = false;
}
}
console.log(data);
if (flag) {//没有未上传的,直接处理数据
clearInterval(img_interval);
var detailImgs = [];
for (var i in data) {
if (data[i]['type'] == "main") {
PageThis.setData({
"mainImg": data[i]
})
} else {
detailImgs.push(data[i])
}
}
PageThis.setData({
"detailImg": detailImgs
})
console.log(detailImgs);
wx.hideLoading();
PageThis.createGood();
}
}, 500);
for (var i in data) {
if (data[i].isUpload != 1) {
wx.uploadFile({
url: app.globalData.serverInfo.uploadFileUrl,
filePath: data[i].filePath,
name: 'file',
success: function (res) {
res = JSON.parse(res.data);
if (res.state == 1) {
for (var j in data) {
if (data[j].size == res.data.file_size) {
data[j]['isUpload'] = 1;
data[j]['uploadPath'] = res.data.file_url;
}
}
} else {
clearInterval(img_interval);
wx.hideLoading();
wx.showToast({
title: '图片上传失败',
icon: 'none',
duration: 2000
})
}
}
})
}
}
},
createGood: function () {
var PageThis = this;
var goodsInfo = PageThis.data.goodsInfo;
goodsInfo['g_cover'] = PageThis.data.mainImg.uploadPath;
goodsInfo['g_pic'] = PageThis.data.detailImg;
goodsInfo['api_name'] = "update_goods";
goodsInfo['login_manager_id'] = PageThis.data.userInfo.manager_id
wx.hideLoading()
wx.request({
url: app.globalData.serverInfo.gateWayUrl,
header: {
'content-type': 'application/json'
},
method: 'POST',
data: goodsInfo,
success: function (res) {
res = res.data;
if (Number(res.state) == 1) {
wx.showToast({
title: '保存成功',
icon: 'success',
duration: 2000,
success: function () {
wx.navigateBack({})
}
})
} else {
wx.showToast({
title: res.msg,
icon: 'none',
duration: 2000
})
}
}
})
}
})
\ No newline at end of file
{
"usingComponents": {}
}
\ No newline at end of file
<view class="info_item">
<view class="info_title"><span class="red_color">*</span>商品名称</view>
<input placeholder="请输入商品名称" bindinput="inputChange" data-name="g_title" value="{{goodsInfo.g_title}}"></input>
</view>
<view class="info_item">
<view class="info_title">商品编号</view>
<input placeholder="请输入商品编号" bindinput="inputChange" data-name="g_no" value="{{goodsInfo.g_no}}"></input>
</view>
<view class="info_item">
<view class="info_title"><span class="red_color">*</span>分成方式</view>
<radio-group bindchange="radioChange">
<label class="radio" wx:for="{{radioList}}" wx:key="k">
<radio value="{{item.value}}" checked="{{item.checked}}" color="#387ee8"/>{{item.name}}
</label>
</radio-group>
</view>
<view class="info_item">
<view class="info_title"><span class="red_color">*</span>进货价格</view>
<input placeholder="请输入进货价格" bindinput="inputChange" data-name="g_cost_price" value="{{goodsInfo.g_cost_price}}"></input>
</view>
<view class="info_item">
<view class="info_title"><span class="red_color">*</span>下级进货价</view>
<input placeholder="请输入下级进货价" bindinput="inputChange" data-name="g_son_cost_price" value="{{goodsInfo.g_son_cost_price}}"></input>
</view>
<view class="info_item">
<view class="info_title"><span class="red_color">*</span>销售价格</view>
<input placeholder="请输入商品销售价" type="digit" bindinput="inputChange" data-name="g_sale_price" value="{{goodsInfo.g_sale_price}}"></input>
</view>
<view class="info_item info_image_item">
<view class="info_title"><span class="red_color">*</span>商品主图</view>
<view class="cb"></view>
<view class="img_content">
<view class="image_item">
<image src="{{mainImg.filePath}}" data-type="main" bindtap="chooseImage"></image>
</view>
</view>
<view class="cb"></view>
</view>
<view class="info_item">
<view class="info_title"><span class="red_color">*</span>商品分类</view>
<view class="info_content">
<picker range="{{cateList}}" bindchange="cateChange">
<span>{{cateTitle}}</span>
<image class="info_content_img" src="../../images/icons/icon(55).png"></image>
</picker>
</view>
</view>
<view class="info_item">
<view class="info_title">商品描述</view>
<input placeholder="请输入商品描述" bindinput="inputChange" data-name="g_introduce" value="{{goodsInfo.g_introduce}}"></input>
</view>
<view class="info_item info_image_item">
<view class="info_title">商品详情</view>
<view class="info_content right_tips">(最多上传10张详情图)</view>
<view class="cb"></view>
<view class="img_content" wx:for="{{detailImg}}" wx:key="k">
<view class="image_item">
<image src="{{item.filePath}}"></image>
<image bindtap="delImage" data-type="detail" class="del_img_btn" src="../../images/icons/icon(49).png" data-name="{{item.filePath}}"></image>
</view>
</view>
<view class="img_content" wx:if="{{detailImgCount <= 9}}">
<view class="image_item" bindtap="chooseImage" data-type="detail">
<image src="../../images/icons/add_img.png"></image>
</view>
</view>
<view class="cb"></view>
</view>
<view class="main_btn" bindtap="uploadImgs">保存</view>
\ No newline at end of file
.del_img_btn{
position: absolute;
width: 5vw !important;
height: 5vw !important;
background-size: 100% 100%;
right: -2vw;
top: -2vw;
background-color: #FFFFFF;
border-radius: 50%;
}
.right_tips{
font-size: 3vw;
text-align: right;
color: #cccccc;
}
\ No newline at end of file
// pages/createGoodsPlan/index.js
const app = getApp();
Page({
data: {
userInfo: wx.getStorageSync('userInfo'),
lat_type: [],
lat_type_value: [],
lat_type_name: "请选择格子机型",
goods_list: [],
goods_list_value: [],
planInfo: {
"gp_title": "",
"gp_lat_type_id": 0,
"gp_content": {}
}
},
onLoad: function (options) {
var id = options.id;
var PageThis = this;
PageThis.setData({
userInfo:wx.getStorageSync('userInfo')
})
this.getLatticeType();
this.getGoodsList();
this.getPlanDetail(id);
},
getPlanDetail:function(id){
var PageThis = this;
wx.request({
url: app.globalData.serverInfo.gateWayUrl,
header: {
'content-type': 'application/json'
},
method: 'POST',
data: {
api_name: "goods_plan_detail",
gp_id: id,
login_manager_id: PageThis.data.userInfo.manager_id
},
success: function (res) {
var data = res.data.data
PageThis.setData({
"planInfo": data,
"lat_type_name":data['lt_title']
})
}
})
},
getLatticeType: function () {
var PageThis = this;
wx.request({
url: app.globalData.serverInfo.gateWayUrl,
header: {
'content-type': 'application/json'
},
method: 'POST',
data: {
api_name: "lattice_type",
login_manager_id: PageThis.data.userInfo.manager_id
},
success: function (res) {
var data = res.data.data;
var lat_list = [];
for (var i in data) {
lat_list.push(data[i].lt_title);
}
PageThis.setData({
"lat_type_value": data,
"lat_type": lat_list
})
}
})
},
getGoodsList: function () {
var PageThis = this;
wx.request({
url: app.globalData.serverInfo.gateWayUrl,
header: {
'content-type': 'application/json'
},
method: 'POST',
data: {
api_name: "goods_list",
search_title: PageThis.data.searchTitle,
login_manager_id: PageThis.data.userInfo.manager_id
},
success: function (res) {
var data = res.data.data;
var goods_list = [];
for (var i in data) {
goods_list.push(data[i].g_title);
}
PageThis.setData({
"goods_list_value": data,
"goods_list": goods_list
})
}
})
},
changeName: function (e) {
var PageThis = this;
var planInfo = PageThis.data.planInfo;
planInfo['gp_title'] = e.detail.value;
PageThis.setData({
"planInfo": planInfo
})
},
latTypeChange: function (e) {
var PageThis = this;
var index = e.detail.value;
var lat_type = PageThis.data.lat_type_value;
var obj = lat_type[index];
var planInfo = PageThis.data.planInfo;
var new_content = [];
for (var i = 0; i < obj.lt_num; i++) {
var item = planInfo.gp_content[i] ? planInfo.gp_content[i] : { "plan_goods_id": 0, "plan_goods_title": "请选择商品" ,"plan_goods_price":0};
new_content.push(item);
}
planInfo['gp_lat_type_id'] = obj['lt_id'];
planInfo['gp_content'] = new_content;
PageThis.setData({
"lat_type_name": obj['lt_title'],
"planInfo": planInfo
})
},
goodsChange: function (e) {
var PageThis = this;
var index = e.target.dataset.index;
var val = e.detail.value;
var planInfo = PageThis.data.planInfo;
var goodsInfo = PageThis.data.goods_list_value[val];
planInfo['gp_content'][index]['plan_goods_title'] = goodsInfo['g_title'];
planInfo['gp_content'][index]['plan_goods_id'] = goodsInfo['g_id'];
planInfo['gp_content'][index]['plan_goods_price'] = goodsInfo['g_sale_price'];
PageThis.setData({
"planInfo": planInfo
});
},
createPlan: function () {
var PageThis = this;
var planInfo = PageThis.data.planInfo;
planInfo['api_name'] = "update_goods_plan";
planInfo['login_manager_id'] = PageThis.data.userInfo.manager_id
wx.request({
url: app.globalData.serverInfo.gateWayUrl,
header: {
'content-type': 'application/json'
},
method: 'POST',
data: planInfo,
success: function (res) {
res = res.data;
if (res.state == 1) {
wx.showToast({
title: "保存成功",
icon: 'success',
duration: 2000,
success: function () {
setTimeout(function () {
wx.navigateBack({})
}, 1500);
}
})
} else {
wx.showToast({
title: res.msg,
icon: 'none',
duration: 2000
})
}
}
})
}
})
\ No newline at end of file
{
"usingComponents": {}
}
\ No newline at end of file
<view class="info_item">
<view class="info_title">方案名称</view>
<input placeholder="请输入方案名称" bindinput="changeName" value="{{planInfo.gp_title}}"></input>
</view>
<view class="info_item">
<view class="info_title">格子机型</view>
<view class="info_content">
<picker range="{{lat_type}}" bindchange="latTypeChange" value="{{planInfo.gp_id}}">
<span>{{lat_type_name}}</span>
<image class="info_content_img" src="../../images/icons/icon(55).png"></image>
</picker>
</view>
</view>
<view class="top_line"></view>
<view class="info_item" wx:for="{{planInfo.gp_content}}" wx:key="k" wx:for-index="index">
<view class="info_title">{{index+1}}号格子</view>
<view class="info_plan">
<picker range="{{goods_list}}" data-index="{{index}}" bindchange="goodsChange">{{item.plan_goods_title}}</picker>
</view>
<view class="info_price">{{item.plan_goods_price}}</view>
</view>
<view class="main_btn" bindtap="createPlan">保存</view>
\ No newline at end of file
/* pages/updateGoodsPlan/index.wxss */
\ No newline at end of file
// pages/createHotel/index.js
const app = getApp();
Page({
data: {
userInfo: wx.getStorageSync('userInfo'),
hotelInfo: {},
hotel_type_name: "请选择酒店类型",
hotel_type_list: [],
hotel_type_value: [],
plan_title: "请选择商品方案",
plan_list: [],
plan_list_value: [],
introduce_list:[],
rep_list:[],
user_list:[],
area_list:[],
area_val:0,
introduce_val:0,
user_val:0,
rep_val:0
},
onLoad: function (options) {
var id = options.id;
var PageThis = this;
PageThis.setData({
userInfo:wx.getStorageSync('userInfo')
})
this.getArea();
this.getHotelType();
this.getPlanList();
this.getHotelDetail(id);
this.getHotelManager();
},
/**
* 获取位置地段
*/
getArea(){
var PageThis = this;
wx.request({
url: app.globalData.serverInfo.gateWayUrl,
header: {
'content-type': 'application/json'
},
method: 'POST',
data:{
api_name: "get_hotel_lot",
},
success:function(res){
var ret = res.data;
if(Number(ret.state) === 1){
var obj = {
lot_id:0,
lot_title:"请选择位置地段"
}
ret.data.unshift(obj);
PageThis.setData({
"area_list": ret.data
})
}
}
})
},
getHotelDetail: function (id) {
var PageThis = this;
wx.request({
url: app.globalData.serverInfo.gateWayUrl,
header: {
'content-type': 'application/json'
},
method: 'POST',
data: {
api_name: "hotel_detail",
hotel_id: id,
login_manager_id: PageThis.data.userInfo.manager_id
},
success: function (res) {
var data = res.data.data;
var h_lot_id = data.h_lot_id;
var area_list = PageThis.data.area_list;
var area_value = 0;
for(var i in area_list){
if(Number(area_list[i].lot_id) == Number(h_lot_id)){
area_value = i;
break;
}
}
PageThis.setData({
"hotelInfo": data,
"hotel_type_name": data.t_title,
"plan_title": data.gp_title,
"area_value":area_value
})
}
})
},
getHotelType: function () {
var PageThis = this;
wx.request({
url: app.globalData.serverInfo.gateWayUrl,
header: {
'content-type': 'application/json'
},
method: 'POST',
data: {
api_name: "hotel_type",
login_manager_id: PageThis.data.userInfo.manager_id
},
success: function (res) {
var data = res.data.data;
var hotel_type_list = [];
for (var i in data) {
hotel_type_list.push(data[i].t_title);
}
PageThis.setData({
"hotel_type_value": data,
"hotel_type_list": hotel_type_list
})
}
})
},
getPlanList: function () {
var PageThis = this;
wx.request({
url: app.globalData.serverInfo.gateWayUrl,
header: {
'content-type': 'application/json'
},
method: 'POST',
data: {
api_name: "goods_plan",
login_manager_id: PageThis.data.userInfo.manager_id
},
success: function (ret) {
var data = ret.data.data;
var plan_list = [];
for (var i in data) {
plan_list.push(data[i].gp_title);
}
PageThis.setData({
"plan_list_value": data,
"plan_list": plan_list
})
}
})
},
changeInput: function (e) {
var PageThis = this;
var name = e.currentTarget.dataset.name;
var data = PageThis.data.hotelInfo;
data[name] = e.detail.value;
PageThis.setData({
"hotelInfo": data
})
},
changePicker: function (e) {
var PageThis = this;
var name = e.currentTarget.dataset.name;
var data = PageThis.data.hotelInfo;
var value = e.detail.value;
switch (name) {
case "h_type_id":
var typeId = PageThis.data.hotel_type_value[value].t_id;
data['h_type_id'] = typeId;
PageThis.setData({
"hotel_type_name": PageThis.data.hotel_type_value[value].t_title,
"hotelInfo": data
})
break;
case "h_default_goods_plan":
var planId = PageThis.data.plan_list_value[value].gp_id;
data['h_default_goods_plan'] = planId;
PageThis.setData({
"plan_title": PageThis.data.plan_list_value[value].gp_title,
"hotelInfo": data
})
break;
case "h_introduce_id":
var introduce_list = PageThis.data.introduce_list;
data['h_introduce_id'] = introduce_list[value].manager_id;
PageThis.setData({
"hotelInfo": data,
"introduce_val":value
})
break;
case "h_rep_id":
var rep_list = PageThis.data.rep_list;
data['h_rep_id'] = rep_list[value].manager_id;
PageThis.setData({
"hotelInfo": data,
"rep_val":value
})
break;
case "h_user_id":
var user_list = PageThis.data.user_list;
data['h_user_id'] = user_list[value].manager_id;
PageThis.setData({
"hotelInfo": data,
"user_val":value
})
break;
case "h_lot_id":
var area_list = PageThis.data.area_list;
data['h_lot_id'] = area_list[value].lot_id;
PageThis.setData({
"hotelInfo": data,
"area_val":value
})
break;
}
},
/**
* 获取酒店管理人员
*/
getHotelManager(){
var PageThis = this;
wx.request({
url: app.globalData.serverInfo.gateWayUrl,
header: {
'content-type': 'application/json'
},
method: 'POST',
data: {
api_name: "get_hotel_manager",
login_manager_id: PageThis.data.userInfo.manager_id
},
success: function (ret) {
var data = ret.data.data;
data['introduce'].unshift({
"manager_id":0,
"manager_nickname":"请选择介绍人"
});
data['manager_hotel'].unshift({
"manager_id":0,
"manager_nickname":"请选择酒店管理员"
});
data['rep'].unshift({
"manager_id":0,
"manager_nickname":"请选择补货员"
});
var introduce_val = 0;
var rep_val = 0;
var user_val = 0;
var hotelInfo = PageThis.data.hotelInfo;
for(var i in data['introduce']){
if(Number(data['introduce'][i].manager_id) === Number(hotelInfo.h_introduce_id)){
introduce_val = i;
break;
}
}
for(var i in data['manager_hotel']){
if(Number(data['manager_hotel'][i].manager_id) === Number(hotelInfo.h_user_id)){
user_val = i;
break;
}
}
for(var i in data['rep']){
if(Number(data['rep'][i].manager_id) === Number(hotelInfo.h_rep_id)){
rep_val = i;
break;
}
}
PageThis.setData({
introduce_list: data['introduce'],
user_list: data['manager_hotel'],
rep_list: data['rep'],
introduce_val:introduce_val,
rep_val:rep_val,
user_val:user_val,
})
}
})
},
/**
* 编辑酒店
*/
createHotel: function () {
var PageThis = this;
var hotelInfo = PageThis.data.hotelInfo;
hotelInfo['api_name'] = "update_hotel";
hotelInfo['login_manager_id'] = PageThis.data.userInfo.manager_id
wx.request({
url: app.globalData.serverInfo.gateWayUrl,
header: {
'content-type': 'application/json'
},
method: 'POST',
data: hotelInfo,
success: function (res) {
res = res.data;
if (Number(res.state) == 1) {
wx.showToast({
title: '保存成功',
icon: 'success',
duration: 2000,
success: function () {
wx.navigateBack({})
}
})
} else {
wx.showToast({
title: res.msg,
icon: 'none',
duration: 2000
})
}
}
})
}
})
\ No newline at end of file
{
"usingComponents": {}
}
\ No newline at end of file
<view class="info_item">
<view class="info_title">酒店名称</view>
<input placeholder="请输入酒店名称" data-name="h_title" bindinput="changeInput" value="{{hotelInfo.h_title}}"></input>
</view>
<view class="info_item">
<view class="info_title">酒店负责人</view>
<input placeholder="请输入酒店负责人名称" data-name="h_lead" bindinput="changeInput" value="{{hotelInfo.h_lead}}"></input>
</view>
<view class="info_item">
<view class="info_title">酒店类型</view>
<view class="info_content">
<picker range="{{hotel_type_list}}" bindchange="changePicker" data-name="h_type_id" value="{{hotelInfo.h_type_id}}">
<span>{{hotel_type_name}}</span>
<image class="info_content_img" src="../../images/icons/icon(55).png"></image>
</picker>
</view>
</view>
<view class="info_item">
<view class="info_title">介绍人</view>
<view class="info_content">
<picker range="{{introduce_list}}" value="{{introduce_val}}" range-key="manager_nickname" bindchange="changePicker" data-name="h_introduce_id">
<span>{{introduce_list[introduce_val].manager_nickname}}</span>
<image class="info_content_img" src="../../images/icons/icon(55).png"></image>
</picker>
</view>
</view>
<view class="info_item">
<view class="info_title">酒店管理员</view>
<view class="info_content">
<picker range="{{user_list}}" value="{{user_val}}" range-key="manager_nickname" bindchange="changePicker" data-name="h_user_id">
<span>{{user_list[user_val].manager_nickname}}</span>
<image class="info_content_img" src="../../images/icons/icon(55).png"></image>
</picker>
</view>
</view>
<view class="info_item">
<view class="info_title">补货员</view>
<view class="info_content">
<picker range="{{rep_list}}" value="{{rep_val}}" range-key="manager_nickname" bindchange="changePicker" data-name="h_rep_id">
<span>{{rep_list[rep_val].manager_nickname}}</span>
<image class="info_content_img" src="../../images/icons/icon(55).png"></image>
</picker>
</view>
</view>
<view class="info_item">
<view class="info_title">负责人电话</view>
<input type="number" placeholder="请输入酒店负责人手机号" data-name="h_mobile" value="{{hotelInfo.h_mobile}}" bindinput="changeInput"></input>
</view>
<view class="info_item">
<view class="info_title">酒店电话</view>
<input type="number" placeholder="请输入酒店电话" data-name="h_phone" value="{{hotelInfo.h_phone}}" bindinput="changeInput"></input>
</view>
<view class="info_item">
<view class="info_title">酒店地址</view>
<view class="info_content">
<input placeholder="请输入酒店地址" data-name="h_address" value="{{hotelInfo.h_address}}" style="width:60vw;float:left;" bindinput="changeInput"></input>
<image class="info_content_img" src="../../images/icons/icon(50).png"></image>
</view>
</view>
<view class="info_item">
<view class="info_title">位置地段</view>
<view class="info_content">
<picker range="{{area_list}}" value="{{area_val}}" range-key="lot_title" bindchange="changePicker" data-name="h_lot_id">
<span>{{area_list[area_val].lot_title}}</span>
<image class="info_content_img" src="../../images/icons/icon(55).png"></image>
</picker>
</view>
</view>
<view class="info_item">
<view class="info_title">房间数量</view>
<view class="info_content">
<input placeholder="请输入房间数量" data-name="h_room_num" value="{{hotelInfo.h_room_num}}" bindinput="changeInput"></input>
</view>
</view>
<view class="info_item">
<view class="info_title">默认方案</view>
<view class="info_content">
<picker range="{{plan_list}}" bindchange="changePicker" data-name="h_default_goods_plan" value="{{hotelInfo.h_default_goods_plan}}">
<span>{{plan_title}}</span>
<image class="info_content_img" src="../../images/icons/icon(55).png"></image>
</picker>
</view>
</view>
<view class="main_btn" bindtap="createHotel">保存</view>
\ No newline at end of file
.info_content input{
height: 4vw;
line-height: 4vw;
font-size: 3.5vw;
margin-top: 3vw;
padding: 0;
}
\ No newline at end of file
// pages/updateUser/index.js
const app = getApp();
Page({
/**
* 页面的初始数据
*/
data: {
userInfo:{},
managerInfo:{},
manager_type_name:"合伙人",
manager_type_list:["合伙人","运维人员","介绍人","酒店管理员","补货员"],
manager_type:[
{
type_title:"合伙人",
type_id:3
},
{
type_title:"运维人员",
type_id:4
},
{
type_title:"介绍人",
type_id:5
},
{
type_title:"酒店管理员",
type_id:6
},
{
type_title:"补货员",
type_id:7
},
],
managerId:0,
password:""
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
var id = options.id;
this.setData({
userInfo:wx.getStorageSync('userInfo'),
"managerId": id
})
},
onShow(){
this.getManagerInfo();
},
changeInput:function(e){
var PageThis = this;
var name = e.currentTarget.dataset.name;
var data = PageThis.data.managerInfo;
data[name] = e.detail.value;
PageThis.setData({
"managerInfo": data
})
console.log(name);
console.log(data);
console.log(data[name]);
console.log(PageThis.data);
},
changePicker:function(e){
var PageThis = this;
var data = PageThis.data.managerInfo;
var value = e.detail.value;
var type_id = PageThis.data.manager_type[value].type_id;
data['manager_type'] = type_id;
PageThis.setData({
"manager_type_name": PageThis.data.manager_type[value].type_title,
"managerInfo": data
})
},
changePasswordInput:function(e){
var PageThis = this;
PageThis.setData({
"password": e.detail.value
})
},
//获取用户信息
getManagerInfo(){
var PageThis = this;
var id = PageThis.data.managerId;
wx.request({
url: app.globalData.serverInfo.gateWayUrl,
header: {
'content-type': 'application/json'
},
method: 'POST',
data: {
api_name: "get_manager_info",
manager_id: id,
login_manager_id: PageThis.data.userInfo.manager_id
},
success:function(res){
var data = res.data.data;
var manager_type_name = "";
switch(Number(data.manager_type)){
case 1:
manager_type_name = "平台";
break;
case 2:
manager_type_name = "生产厂商";
break;
case 3:
manager_type_name = "合伙人";
break;
case 4:
manager_type_name = "运维人员";
break;
case 5:
manager_type_name = "介绍人";
break;
case 6:
manager_type_name = "酒店管理员";
break;
case 7:
manager_type_name = "补货员";
break;
}
console.log(manager_type_name);
PageThis.setData({
"managerInfo": data,
"manager_type_name":manager_type_name
})
}
})
},
updateManager:function(){
var PageThis = this;
var managerInfo = PageThis.data.managerInfo;
managerInfo['api_name'] = "update_manager";
managerInfo['login_manager_id'] = PageThis.data.userInfo.manager_id;
wx.request({
url: app.globalData.serverInfo.gateWayUrl,
header: {
'content-type': 'application/json'
},
method: 'POST',
data: {
"api_name":'update_manager',
"login_manager_id":PageThis.data.userInfo.manager_id,
"manager_id":PageThis.data.managerInfo.manager_id,
"manager_type":PageThis.data.managerInfo.manager_type,
"manager_nickname":PageThis.data.managerInfo.manager_nickname,
"manager_username":PageThis.data.managerInfo.manager_username,
"manager_percent":PageThis.data.managerInfo.manager_percent,
"manager_fee":PageThis.data.managerInfo.manager_fee,
"manager_pid":PageThis.data.managerInfo.manager_pid,
"manager_password":PageThis.data.password,
},
success:function(res){
res = res.data;
console.log(res);
if (Number(res.state) == 1) {
wx.showToast({
title: res.msg,
icon: 'none',
duration: 2000,
success: function () {
wx.navigateTo({
url: '../userList/index',
})
}
})
} else {
wx.showToast({
title: res.msg,
icon: 'none',
duration: 2000
})
}
}
})
}
})
\ No newline at end of file
{
"usingComponents": {}
}
\ No newline at end of file
<view class="info_item">
<view class="info_title">用户名称</view>
<input placeholder="请输入用户名称" data-name="manager_nickname" bindinput="changeInput" value="{{managerInfo.manager_nickname}}"></input>
</view>
<!-- <view class="info_item">
<view class="info_title">账号类型</view>
<view class="info_content">
<picker range="{{manager_type_list}}" bindchange="changePicker">
<span>{{manager_type_name}}</span>
<image class="info_content_img" src="../../images/icons/icon(55).png"></image>
</picker>
</view>
</view> -->
<view class="info_item">
<view class="info_title">登陆账号</view>
<input placeholder="请输入登陆账号" data-name="manager_username" bindinput="changeInput" value="{{managerInfo.manager_username}}"></input>
</view>
<view class="info_item">
<view class="info_title">登陆密码</view>
<input placeholder="请输入登陆密码" data-name="manager_password" bindinput="changePasswordInput"></input>
</view>
<view class="info_item">
<view class="info_title">分成比例(%)</view>
<input placeholder="请输入分成比例" data-name="manager_percent" bindinput="changeInput" value="{{managerInfo.manager_percent}}"></input>
</view>
<view class="info_item">
<view class="info_title">提现手续费</view>
<input placeholder="请输入提现手续费" data-name="manager_fee" bindinput="changeInput" value="{{managerInfo.manager_fee}}"></input>
</view>
<view class="main_btn" bindtap="updateManager">确认编辑</view>
\ No newline at end of file
/* pages/updateUser/index.wxss */
\ No newline at end of file
// pages/userDetail/index.js
const app = getApp();
Page({
/**
* 页面的初始数据
*/
data: {
userInfo:[],
managerId:0,
managerDetail:{},
showPer:"none"
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
var id = options.id;
var PageThis = this;
PageThis.setData({
userInfo:wx.getStorageSync('userInfo')
})
this.setData({
"managerId": id
})
},
/**
* 生命周期函数--监听页面显示
*/
onShow: function () {
this.getManagerInfo();
},
//**页面跳转 */
navigateTo: function (e) {
var _url = e.currentTarget.dataset.url;
var _id = e.currentTarget.dataset.id;
wx.navigateTo({
url: _url + "?id=" + _id,
})
},
//获取用户信息
getManagerInfo(){
var PageThis = this;
var id = PageThis.data.managerId;
wx.request({
url: app.globalData.serverInfo.gateWayUrl,
header: {
'content-type': 'application/json'
},
method: 'POST',
data: {
api_name: "get_manager_info",
manager_id: id,
login_manager_id: PageThis.data.userInfo.manager_id
},
success:function(res){
console.log(res);
var data = res.data.data;
switch(Number(data.manager_type)){
case 1:
data['manager_type_name'] = "平台";
break;
case 2:
data['manager_type_name'] = "生产厂商";
break;
case 3:
data['manager_type_name'] = "合伙人";
break;
case 4:
data['manager_type_name'] = "运维人员";
break;
case 5:
data['manager_type_name'] = "介绍人";
break;
case 6:
data['manager_type_name'] = "酒店管理员";
break;
case 7:
data['manager_type_name'] = "补货员";
break;
}
var showPer = "none";
if(Number(data.manager_type) == 3 || Number(data.manager_type) == 5 || Number(data.manager_type) == 6){
showPer = "block";
}
PageThis.setData({
"managerDetail": data,
"showPer":showPer
})
}
})
},
withdrawal_balance(){
var PageThis = this;
var id = PageThis.data.managerId;
wx.showModal({
title: '温馨提示',
content: '确定要提取该用户余额?',
success(ret){
if(ret.confirm){
wx.request({
url: app.globalData.serverInfo.gateWayUrl,
header: {
'content-type': 'application/json'
},
method: 'POST',
data: {
api_name: "extract_manager_balance",
manager_id: id,
login_manager_id: PageThis.data.userInfo.manager_id
},
success:function(ret){
if(Number(ret.data.state) === 1){
wx.showToast({
title: ret.data.msg,
})
}else{
wx.showToast({
title: ret.data.msg,
icon: 'none'
})
}
}
})
}else{
}
}
})
},
disable_account(){
var PageThis = this;
var id = PageThis.data.managerId;
wx.showModal({
title: '温馨提示',
content: '确定要禁用该用户账号?',
success(ret){
if(ret.confirm){
wx.request({
url: app.globalData.serverInfo.gateWayUrl,
header: {
'content-type': 'application/json'
},
method: 'POST',
data: {
api_name: "disable_manager_info",
manager_id: id,
login_manager_id: PageThis.data.userInfo.manager_id
},
success:function(ret){
if(Number(ret.data.state) === 1){
wx.showToast({
title: ret.data.msg,
})
}else{
wx.showToast({
title: ret.data.msg,
icon: 'none'
})
}
}
})
}else{
}
}
})
},
reset_password(){
var PageThis = this;
var id = PageThis.data.managerId;
wx.showModal({
title: '温馨提示',
content: '该用户登陆密码将会重置为【123456】',
success(ret){
if(ret.confirm){
wx.request({
url: app.globalData.serverInfo.gateWayUrl,
header: {
'content-type': 'application/json'
},
method: 'POST',
data: {
api_name: "reset_manager_password",
manager_id: id,
login_manager_id: PageThis.data.userInfo.manager_id
},
success:function(ret){
if(Number(ret.data.state) === 1){
wx.showToast({
title: ret.data.msg,
})
}else{
wx.showToast({
title: ret.data.msg,
icon: 'none'
})
}
}
})
}else{
}
}
})
}
})
\ No newline at end of file
{
"usingComponents": {}
}
\ No newline at end of file
<view class="info_item">
<view class="info_title">用户名称</view>
<view class="info_content">{{managerDetail.manager_nickname}}</view>
</view>
<view class="info_item">
<view class="info_title">用户账号</view>
<view class="info_content">{{managerDetail.manager_username}}</view>
</view>
<view class="info_item">
<view class="info_title">用户类型</view>
<view class="info_content">{{managerDetail.manager_type_name}}</view>
</view>
<view class="info_item" wx:if="{{showPer != none}}">
<view class="info_title">分成比例</view>
<view class="info_content">{{managerDetail.manager_percent}}%</view>
</view>
<view class="info_item" wx:if="{{showPer != none}}">
<view class="info_title">手续费</view>
<view class="info_content">{{managerDetail.manager_fee}}</view>
</view>
<view class="info_item">
<view class="info_title">创建时间</view>
<view class="info_content">{{managerDetail.manager_create}}</view>
</view>
<view class="info_item">
<view class="info_title">最后登录时间</view>
<view class="info_content">{{managerDetail.manager_last_login}}</view>
</view>
<view class="info_item">
<view class="info_title">最后登录IP</view>
<view class="info_content">{{managerDetail.manager_last_ip}}</view>
</view>
<view class="main_btn" bindtap="navigateTo" data-id="{{managerDetail.manager_id}}" data-url="../updateUser/index">编辑账号</view>
<view class="main_btn sec_btn" bindtap="withdrawal_balance">提取余额</view>
<view class="main_btn thi_btn" bindtap="disable_account">禁用账号</view>
<view class="main_btn four_btn" bindtap="reset_password">重置密码</view>
\ No newline at end of file
/* pages/userDetail/index.wxss */
\ No newline at end of file
// pages/userList/index.js
const app = getApp();
Page({
data: {
userInfo: wx.getStorageSync('userInfo'),
userType: ['平台管理员', '生产厂商', '合伙人', '运维人员', '介绍人', '酒店管理员', '补货员'],
userList: [],
search_value: "",
},
onLoad: function (options) {
var PageThis = this;
PageThis.setData({
userInfo:wx.getStorageSync('userInfo')
})
},
onShow: function () {
this.getManagerList();
},
//**页面跳转 */
navigateTo: function (e) {
var _url = e.currentTarget.dataset.url;
var _id = e.currentTarget.dataset.id;
wx.navigateTo({
url: _url + "?id=" + _id,
})
},
getManagerList:function(){
var PageThis = this;
wx.request({
url: app.globalData.serverInfo.gateWayUrl,
header: {
'content-type': 'application/json'
},
method: 'POST',
data: {
api_name: "manager_list",
keywords: PageThis.data.search_value,
login_manager_id: PageThis.data.userInfo.manager_id
},
success:function(res){
var data = res.data.data;
for (var i in data){
data[i]['manager_type'] = PageThis.data.userType[data[i]['manager_type']-1];
}
PageThis.setData({
"userList": data
})
}
})
},
inputChange:function(e){
var PageThis = this;
PageThis.setData({
"search_value": e.detail.value
})
}
})
\ No newline at end of file
{
"usingComponents": {}
}
\ No newline at end of file
<view id="search_box">
<view id="search_content_box">
<image src="../../images/icons/icon(51).png"></image>
<input placeholder="请输入联系人名称或用户名" bindinput="inputChange"></input>
</view>
<view id="search_btn" bindtap="getManagerList">搜索</view>
</view>
<view id="list_box">
<view class="list_item" wx:for="{{userList}}" wx:key="k" bindtap="navigateTo" data-url="../userDetail/index" data-id="{{item.manager_id}}">
<view class="list_title_box">
<view class="list_title">{{item.manager_username}}-{{item.manager_nickname}} <span class="blue_color">({{item.manager_type}})</span></view>
</view>
<view class="cb"></view>
</view>
</view>
<image class="add_btn" src="../../images/icons/icon(33).png" bindtap="navigateTo" data-url="../createUser/index"></image>
\ No newline at end of file
.list_title_box{
border: none;
width: 95%;
padding-left: 5%;
}
.list_item{
border-bottom: 1px solid rgb(245, 245, 245);
}
\ No newline at end of file
const app = getApp();
Page({
data: {
userInfo: {},
userName:"",
pageData:[]
},
onLoad: function (options) {
this.setData({
userInfo:wx.getStorageSync('userInfo'),
});
},
onShow: function () {
this.getData();
},
inputChange:function(e){
var PageThis = this;
PageThis.setData({
"userName": e.detail.value
})
},
getData(){
var PageThis = this;
wx.request({
url: app.globalData.serverInfo.gateWayUrl,
header: {
'content-type': 'application/json'
},
method: 'POST',
data: {
api_name: "get_user_data_count",
login_manager_id: PageThis.data.userInfo.manager_id,
username:PageThis.data.userName,
},
success:function(res){
var data = res.data.data;
PageThis.setData({
pageData:data
})
}
})
}
})
\ No newline at end of file
{
"usingComponents": {}
}
\ No newline at end of file
<view id="search_box">
<view id="search_content_box">
<image src="../../images/icons/icon(51).png"></image>
<input placeholder="请输入用户名" bindinput="inputChange"></input>
</view>
<view id="search_btn" bindtap="getData">搜索</view>
</view>
<view class="device_statistics_list">
<view class="device_statistics_item" wx:for="{{pageData}}" wx:key="k">
<view>{{item.manager_username}}</view>
<view></view>
<view>分成比例:<span class="blue_color">{{item.manager_percent}}</span></view>
<view>分成金额:<span class="blue_color">¥{{item.sep_money}}</span></view>
<view>已提现金额:<span class="blue_color">¥{{item.manager_total_cash}}</span></view>
<view>提现中金额:<span class="blue_color">¥{{item.manager_frozen}}</span></view>
<view>未提现金额:<span class="blue_color">¥{{item.manager_money}}</span></view>
<view>手续费:<span class="blue_color">¥{{item.fee_money}}</span></view>
<view class="cb"></view>
</view>
</view>
\ No newline at end of file
.data_box{
width: calc(90vw + 3px);
height: 24vw;
border-radius: 15px;
background-image: linear-gradient(90deg, #77adff 0%, #387ee8 100%);
color: #FFFFFF;
margin: 8vw auto;
}
.data_item{
width: calc(90vw / 4);
text-align: center;
float: left;
margin-top: 5vw;
}
.data_item:nth-child(2){
border-left: 1px solid rgb(128, 174, 248);
border-right: 1px solid rgb(106,160,245);
}
.data_item:nth-child(3){
border-right: 1px solid rgb(106,160,245);
}
.data_item view:nth-child(1){
font-size: 5vw;
height: 8vw;
line-height: 8vw;
}
.data_item view:nth-child(2){
font-size: 3vw;
height: 6vw;
line-height: 6vw;
}
.device_statistics_list{
width: 100%;
border-top: 3vw solid rgb(248,248,248);
}
.device_statistics_item{
color: #999999;
font-size: 3.5vw;
width: 94vw;
padding: 3vw;
border-bottom: 1px solid rgb(248,248,248);
}
.device_statistics_item view{
width: 50%;
float: left;
height: 8vw;
line-height: 8vw;
}
.device_statistics_item view:nth-child(1){
font-size: 4vw;
color: #000000;
}
.device_statistics_item view:nth-child(2){
color: #000000;
}
.device_statistics_item view:nth-child(2n){
text-align: right;
}
.blue_color{
color: rgb(55,126,232) !important;
}
\ No newline at end of file
// pages/wallet/index.js
const app = getApp();
var com=require('../com/com.js')
Page({
data: {
userInfo: wx.getStorageSync('userInfo'),
},
onLoad(){
this.setData({
userInfo:wx.getStorageSync('userInfo')
});
},
onShow: function () {
var PageThis = this;
com.comUserInfo(PageThis.data.userInfo.manager_id);
PageThis.setData({
userInfo:wx.getStorageSync('userInfo')
});
},
//**页面跳转 */
navigateTo: function (e) {
var _url = e.currentTarget.dataset.url;
wx.navigateTo({
url: _url,
})
},
pickerChange:function(e){
var PageThis = this;
}
})
\ No newline at end of file
{
"usingComponents": {}
}
\ No newline at end of file
<view id="wallet_banner">
<image src="../../images/top_banner/wallet_banner.png"></image>
<view class="wallet_title">当前总余额</view>
<view class="wallet_money_box">
<view>{{userInfo.manager_money}}</view>
<view>元</view>
</view>
</view>
<view class="main_btn" bindtap="navigateTo" data-url="../withdrawal/index?tpye=1">银行卡提现</view>
<view class="wechatBtn" bindtap="navigateTo" data-url="../withdrawal/index?tpye=2">微信提现</view>
<view class="tips_btn" bindtap="navigateTo" data-url="../withdrawalsRecord/index">提现记录</view>
\ No newline at end of file
#wallet_banner{
width: 100%;
height: 45vw;
position: relative;
}
#wallet_banner image{
width: 100%;
height: 100%;
background-size: 100% 100%;
position: absolute;
top: 0;
left: 0;
}
.wallet_title{
color: #FFFFFF;
font-size: 3.8vw;
position: absolute;
z-index: 1;
top: 17vw;
left: 10vw;
}
.wallet_money_box{
top: 22vw;
left: 10vw;
z-index: 1;
position: absolute;
}
.wallet_money_box view:nth-child(1){
font-size: 9vw;
color: #FFFFFF;
display: inline-block;
}
.wallet_money_box view:nth-child(2){
font-size: 3.5vw;
color: #FFFFFF;
display: inline-block;
margin-left: 1vw;
}
.main_btn{
margin-top: 10vw;
}
.input_box{
width: 100%;
}
.input_box input{
color: rgb(55,126,232);
font-size: 6vw;
border-bottom: 0.8vw solid rgb(105,162,250);
width: 85vw;
margin: 5vw;
padding-left:5vw;
height: 10vw;
line-height: 10vw;
}
\ No newline at end of file
// pages/warehouse/index.js
const app = getApp();
Page({
data: {
},
//**页面跳转 */
navigateTo: function (e) {
var _url = e.currentTarget.dataset.url;
wx.navigateTo({
url: _url,
})
},
})
\ No newline at end of file
{
"usingComponents": {}
}
\ No newline at end of file
<view id="list_box">
<view class="list_item" bindtap="navigateTo" data-url="../hotelInventory/index">
<image class="list_icon" src="../../images/icons/icon(38).png"></image>
<view class="list_title_box">
<view class="list_title">酒店库存</view>
<image class="list_item_icon" src="../../images/icons/icon(55).png"></image>
</view>
<view class="cb"></view>
</view>
</view>
\ No newline at end of file
.list_title_box{
border: none
}
.list_item{
border-top: 1px solid rgb(245, 245, 245);
border-bottom: 1px solid rgb(245, 245, 245);
}
\ No newline at end of file
// pages/withdrawal/index.js
var com=require('../com/com.js');
const app = getApp();
Page({
data: {
userInfo: wx.getStorageSync('userInfo'),
money: 0,
cardId: 0,
cardList: [],
cardName: "请选择收款账号",
PageTpye:1,
},
onLoad: function (options) {
var PageThis = this;
PageThis.setData({
userInfo:wx.getStorageSync('userInfo'),
PageTpye:options.tpye,
})
this.getCardList();
},
getCardList: function () {
var PageThis = this;
wx.request({
url: app.globalData.serverInfo.gateWayUrl,
header: {
'content-type': 'application/json'
},
method: 'POST',
data: {
api_name: "get_bank_card",
login_manager_id: PageThis.data.userInfo.manager_id
},
success: function (res) {
res = res.data;
if (res.state == 1) {
var cardList = [];
for (var i in res.data){
cardList.push(res.data[i]['card_no'] + "-" + res.data[i]['card_bank'])
}
PageThis.setData({
"cardList": cardList,
"cardListValue": res.data
})
}
}
})
},
pickerChange:function(e){
var PageThis = this;
var id = e.detail.value;
var cardList = PageThis.data.cardList;
var cardListValue = PageThis.data.cardListValue;
PageThis.setData({
"cardName": cardList[id],
"cardId": cardListValue[id]['card_id']
})
},
inputChange: function (e) {
var PageThis = this;
PageThis.setData({
"money": e.detail.value
})
},
applySubmit:function(){
var PageThis = this;
wx.request({
url: app.globalData.serverInfo.gateWayUrl,
header: {
'content-type': 'application/json'
},
method: 'POST',
data: {
api_name: "get_bank_card",
money: Number(PageThis.data.money),
card_id: PageThis.data.cardId,
login_manager_id: PageThis.data.userInfo.manager_id
},
success:function(res){
com.comUserInfo(PageThis.data.userInfo.manager_id);
res = res.data;
if(res.state == 1){
wx.showToast({
title: '申请成功',
icon:"success",
duration:1500
})
setTimeout(function(){
wx.redirectTo({
url: '../withdrawalsRecord/index',
})
},1500);
}else{
wx.showToast({
title: res.msg,
icon:"none",
duration: 2000
})
}
}
})
},
wechatSubmit:function(){
var PageThis = this;
wx.request({
url: app.globalData.serverInfo.gateWayUrl,
header: {
'content-type': 'application/json'
},
method: 'POST',
data: {
api_name: "apply_wx_withdraw",
target: app.globalData.ThisWechatTarget,
type: app.globalData.ThisWechatType,
money: Number(PageThis.data.money),
login_manager_id: PageThis.data.userInfo.manager_id
},
success:function(res){
com.comUserInfo(PageThis.data.userInfo.manager_id);
res = res.data;
if(res.state == 1){
wx.showToast({
title: '申请成功',
icon:"none",
duration:1500
})
setTimeout(function(){
wx.redirectTo({
url: '../withdrawalsRecord/index',
})
},1500);
}else{
wx.showToast({
title: res.msg,
icon:"none",
duration: 2000
})
}
}
})
}
})
\ No newline at end of file
{
"usingComponents": {}
}
\ No newline at end of file
<view class="info_item">
<view class="info_title">可用余额</view>
<view class="info_content">{{userInfo.manager_money}}元</view>
</view>
<view class="info_item">
<view class="info_title">提现金额</view>
<input placeholder="请输入提现金额" bindinput="inputChange" data-name="money"></input>
</view>
<view class="info_item" wx:if="{{PageTpye == 1}}">
<view class="info_title">提现账号</view>
<view class="info_content">
<picker range="{{cardList}}" bindchange="pickerChange">
<span>{{cardName}}</span>
</picker>
</view>
</view>
<view class="main_btn" bindtap="applySubmit" wx:if="{{PageTpye == 1}}">提交申请</view>
<view class="wechatBtn" bindtap="wechatSubmit" wx:if="{{PageTpye == 2}}">提交申请</view>
\ No newline at end of file
/* pages/withdrawal/index.wxss */
\ No newline at end of file
// pages/withdrawalsRecord/index.js
const app = getApp();
Page({
data: {
userInfo: wx.getStorageSync('userInfo'),
recordList:[]
},
onLoad: function (options) {
var PageThis = this;
PageThis.setData({
userInfo:wx.getStorageSync('userInfo')
})
this.getRecord();
},
getRecord:function(){
var PageThis = this;
wx.request({
url: app.globalData.serverInfo.gateWayUrl,
header: {
'content-type': 'application/json'
},
method: 'POST',
data:{
api_name: "get_withdraw_list",
login_manager_id: PageThis.data.userInfo.manager_id
},
success:function(res){
console.log(res.data.data);
PageThis.setData({
"recordList": res.data.data
})
}
})
}
})
\ No newline at end of file
{
"usingComponents": {}
}
\ No newline at end of file
<view class="record_date_box">
<view class="record_date_title">提现时间</view>
<picker mode="date" fields="day" value="2019-11-13" start="2015-09-01" end="2020-12-01"></picker>
<view>~</view>
<picker mode="date" fields="day" value="2019-11-13" start="2015-09-01" end="2020-12-01"></picker>
</view>
<view id="record_list">
<view class="record_item" wx:for="{{recordList}}" wx:key="k">
<view class="record_state">
<view>提现</view>
<view>{{item.w_create}}</view>
</view>
<view class="record_money">-{{item.w_money}}</view>
</view>
</view>
\ No newline at end of file
.record_date_box{
width: 100%;
height: 15vw;
background-color: #FFFFFF;
border-top: 1px solid rgb(248,248,248);
}
.record_date_title{
font-size: 4vw;
margin: 0 4vw;
}
picker{
float: left;
width: 30vw;
height: 8vw;
margin: 3.5vw 2.5vw;
background-color: rgb(248,248,248);
color: #999999;
border-radius: 5px;
}
.record_date_box view{
float: left;
height: 15vw;
line-height: 15vw;
}
#record_list{
width: 100%;
border-top: 3vw solid rgb(248,248,248);
}
.record_item{
width: 100%;
height: 20vw;
border-bottom: 1px solid rgb(248,248,248);
}
.record_state{
height: 13vw;
margin: 3.5vw;
float: left;
}
.record_state view:nth-child(1){
font-size: 4.2vw;
color: rgb(49,66,92);
}
.record_state view:nth-child(2){
color: rgb(156,156,156);
font-size: 3.5vw;
margin-top: 2vw;
}
.record_money{
height: 20vw;
line-height: 20vw;
font-size: 4vw;
float: right;
margin-right: 5vw;
color: red;
}
\ No newline at end of file
// pages/wxBindList/index.js
const app = getApp();
Page({
data: {
userInfo:{},
userName:"",
list:[]
},
onLoad: function (options) {
this.setData({
userInfo:wx.getStorageSync('userInfo'),
});
},
onShow: function () {
this.getList();
},
inputChange:function(e){
var PageThis = this;
PageThis.setData({
"userName": e.detail.value
})
},
getList(){
var PageThis = this;
wx.request({
url: app.globalData.serverInfo.gateWayUrl,
header: {
'content-type': 'application/json'
},
method: 'POST',
data: {
api_name: "get_bind_manager",
login_manager_id: PageThis.data.userInfo.manager_id,
username:PageThis.data.userName,
},
success:function(res){
var data = res.data.data;
PageThis.setData({
list:data
})
}
})
},
unbind(e){
var PageThis = this;
var id = e.currentTarget.dataset.id;
console.log(id);
if(Number(id) > 0){
wx.showModal({
title: '温馨提示',
content: "确认要解绑该用户?",
success(res){
if(res.confirm){
wx.request({
url: app.globalData.serverInfo.gateWayUrl,
header: {
'content-type': 'application/json'
},
method: 'POST',
data: {
"api_name":"unbind_manager_wx",
"manager_id":id,
"login_manager_id":PageThis.data.userInfo.manager_id
},
success(res){
var ret = res.data;
if(Number(ret.state) === 1){
wx.showToast({
title: ret.msg,
})
PageThis.getList();
}else{
wx.showToast({
title: ret.msg,
icon: 'none'
})
}
}
})
}
}
})
}
}
})
\ No newline at end of file
{
"usingComponents": {}
}
\ No newline at end of file
<view id="search_box">
<view id="search_content_box">
<image src="../../images/icons/icon(51).png"></image>
<input placeholder="请输入用户名" bindinput="inputChange" value="{{userName}}"></input>
</view>
<view id="search_btn" bindtap="getData">搜索</view>
</view>
<view class="user_item" wx:for="{{list}}">
<image src="{{item.manager_bind_avatar}}"></image>
<view class="user_item_content">
<view>{{item.manager_nickname}}-({{item.manager_username}})</view>
<view>绑定账号:{{item.manager_bind_nickname}}</view>
</view>
<view class="unbind_btn" bindtap="unbind" data-id="{{item.manager_id}}">解绑</view>
<view class="cb"></view>
</view>
.user_item{
width: 95vw;
margin: 0 auto;
border-bottom: 1px solid #eeeeee;
background-color: #FFFFFF;
height: 20vw;
}
.user_item image{
width: 10vw;
height: 10vw;
margin: 5vw;
background-size: 100% 100%;
border-radius: 50%;
float: left;
}
.user_item_content{
line-height: 5vw;
font-size:3.8vw;
float: left;
margin-top: 5vw;
width: 55vw;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.user_item_content view:nth-child(2){
color: #666666;
}
.unbind_btn{
float: right;
color: #FFFFFF;
background-color: #387ee8;
width: 15vw;
text-align: center;
height: 6vw;
line-height: 6vw;
margin: 7.5vw 2vw 0 0;
font-size: 3.5vw;
border-radius: 5px;
}
{
"description": "项目配置文件",
"packOptions": {
"ignore": []
},
"setting": {
"urlCheck": false,
"es6": true,
"enhance": true,
"postcss": true,
"preloadBackgroundData": false,
"minified": true,
"newFeature": false,
"coverView": true,
"nodeModules": false,
"autoAudits": false,
"showShadowRootInWxmlPanel": true,
"scopeDataCheck": false,
"uglifyFileName": false,
"checkInvalidKey": true,
"checkSiteMap": true,
"uploadWithSourceMap": true,
"compileHotReLoad": false,
"lazyloadPlaceholderEnable": false,
"useMultiFrameRuntime": true,
"useApiHook": true,
"useApiHostProcess": true,
"babelSetting": {
"ignore": [],
"disablePlugins": [],
"outputPath": ""
},
"enableEngineNative": false,
"useIsolateContext": true,
"userConfirmedBundleSwitch": false,
"packNpmManually": false,
"packNpmRelationList": [],
"minifyWXSS": true,
"disableUseStrict": false,
"showES6CompileOption": false,
"useCompilerPlugins": false,
"minifyWXML": true
},
"compileType": "miniprogram",
"libVersion": "2.11.3",
"appid": "wx0fc3395b6c4b684d",
"projectname": "%E9%85%92%E5%BA%97%E6%A0%BC%E5%AD%90%E6%9F%9C%E7%AE%A1%E7%90%86%E7%AB%AF-%E5%B0%8F%E7%BF%9F%E6%80%BB(%E5%88%A0%E5%87%8F)",
"debugOptions": {
"hidedInDevtools": []
},
"isGameTourist": false,
"simulatorType": "wechat",
"simulatorPluginLibVersion": {},
"condition": {
"search": {
"list": []
},
"conversation": {
"list": []
},
"game": {
"currentL": -1,
"list": []
},
"miniprogram": {
"list": []
}
}
}
\ No newline at end of file
{
"desc": "关于本文件的更多信息,请参考文档 https://developers.weixin.qq.com/miniprogram/dev/framework/sitemap.html",
"rules": [{
"action": "allow",
"page": "*"
}]
}
\ No newline at end of file
const serviceId = "6E400001-B5A3-F393-E0A9-E50E24DCCA9E";
const readCharacteristic = "6E400003-B5A3-F393-E0A9-E50E24DCCA9E";
const writeCharacteristic = "6E400002-B5A3-F393-E0A9-E50E24DCCA9E";
const encodeKey = "aabbccdd20191210aabbccdd20191210";
const deviceId = "";
const deviceNum = "";
const pwdCode = "";
const pwdEncode = "";
const isConnect = false;
class D600{
constructor(devNum,deviceId) {
this.deviceNum = devNum;
this.deviceId = deviceId;
this.isConnect = false;
}
//获取连接状态
getConnect(){
return this.isConnect;
}
getPower(){
return this.power;
}
//打开格子
openLat(lat){
console.log("openLat");
var device_num = this.deviceNum;
var hex = [];
hex.push(parseInt('AA',16));
hex.push(parseInt('02',16));
for(var i in device_num){
hex.push(parseInt(device_num[i],16));
}
hex.push(parseInt(Number(lat),16))
wx.showLoading({
title: '打开格子中',
})
this.writeBLECharacteristicValue(hex);
}
//打开缺货格子
openNoStockLat(){
var device_num = this.deviceNum;
var hex = [];
hex.push(parseInt('AA',16));
hex.push(parseInt('03',16));
for(var i in device_num){
hex.push(parseInt(device_num[i],16));
}
wx.showLoading({
title: '打开格子中',
})
this.writeBLECharacteristicValue(hex);
}
//读取电池电量
readPower(){
var device_num = this.deviceNum;
var hex = [];
hex.push(parseInt('AA',16));
hex.push(parseInt('06',16));
for(var i in device_num){
hex.push(parseInt(device_num[i],16));
}
this.writeBLECharacteristicValue(hex);
}
//连接蓝牙设备
createBLEConnection(){
var that = this;
var deviceId = this.deviceId;
return new Promise(function(resolve,reject){
wx.showLoading({
title: '设备连接中',
duration: 99999,
mask: true
})
wx.createBLEConnection({
deviceId: deviceId,
success: function (createBLEConnection_res) {
console.log("Create",createBLEConnection_res);
wx.getBLEDeviceServices({
deviceId: deviceId,
success: function (getBLEDeviceServices_res) {
console.log("Services",getBLEDeviceServices_res);
wx.getBLEDeviceCharacteristics({
deviceId: deviceId,
serviceId: serviceId,
success: function (res) {
console.log(res);
wx.notifyBLECharacteristicValueChange({
deviceId: deviceId,
serviceId: serviceId,
characteristicId: readCharacteristic,
state: true,
success: function (res) {
console.log('使能成功', res);
wx.showToast({
icon: "success",
title: '连接成功',
})
that.onBLECharacteristicValueChange();
let pwd = that.getRandomString(16);
that.pwdCode = pwd;
that.isConnect = true;
var hex = [];
for(var i in pwd){
hex.push(pwd.charCodeAt(i))
}
hex.unshift(parseInt("01",16));
hex.unshift(parseInt("AE",16));
// that.writeBLECharacteristicValue(hex);
resolve(true);
},
fail: function (err) {
that.connectFail();
resolve(false);
}
})
},
fail: function (err) {
console.log(err, "获取该服务失败getBLEDeviceCharacteristics");
that.connectFail();
resolve(false);
}
})
},
fail: function (err) {
console.log(err, "蓝牙连接失败getBLEDeviceServices");
that.connectFail();
resolve(false);
}
})
},
fail: function (err) {
console.log(err, "蓝牙连接失败createBLEConnection");
that.connectFail();
resolve(false);
}
})
})
}
// 获取返回值
onBLECharacteristicValueChange() {
var that = this;
wx.onBLECharacteristicValueChange(function (res) {
var turn_back = that.buf2hex(res.value);
console.log("接收=》"+turn_back);
turn_back = that.hexEncode(turn_back);
switch(turn_back[0]){
case "AE":
case "ae":
switch(Number(turn_back[1])){
case 2://接收到设备加密后的密文,App自己重新加密/解密认证,这是为重新对发出去的明文重新加密
var CryptoJS = require('./cryptojs-master/cryptojs.js').Crypto;
var pwdCode = that.pwdCode;
var pwdEncode = "";
for(var i=2;i<turn_back.length;i++){
pwdEncode += turn_back[i].toUpperCase();
}
var key = that.hexEncode(encodeKey);
var new_key = [];
for(let i in key){
new_key.push(parseInt(key[i],16));
}
var mode = new CryptoJS.mode.ECB(CryptoJS.pad.pkcs7);
var bytes = CryptoJS.AES.encrypt(pwdCode, new_key, {
asBpytes: true,
mode: mode
});
var encryptResult = wx.base64ToArrayBuffer(bytes);
encryptResult = that.buf2hex(encryptResult);
encryptResult = encryptResult.substr(0,32).toUpperCase();
//App自己加密密文与设备返回密文相同则为成功
if(pwdEncode == encryptResult){
console.log("第一遍认证成功");
}else{
//TODO:断开蓝牙连接
}
break;
case 3://接收到设备测试指令,App加密后返回设备进行认证
var CryptoJS = require('./cryptojs-master/cryptojs.js').Crypto;
var pwdEncode = "";
for(var i=2;i<turn_back.length;i++){
pwdEncode += turn_back[i].toUpperCase();
}
pwdEncode = that.hexEncode(pwdEncode);
for(var i in pwdEncode){
pwdEncode[i] = parseInt(pwdEncode[i],16);
}
var key = that.hexEncode(encodeKey);
var new_key = [];
for(let i in key){
new_key.push(parseInt(key[i],16));
}
var mode = new CryptoJS.mode.ECB(CryptoJS.pad.pkcs7);
var bytes = CryptoJS.AES.encrypt(pwdEncode, new_key, {
asBpytes: true,
mode: mode
});
var encryptResult = wx.base64ToArrayBuffer(bytes);
encryptResult = that.buf2hex(encryptResult);
encryptResult = encryptResult.substr(0,32).toUpperCase();
encryptResult = that.hexEncode(encryptResult);
console.log(encryptResult);
var hex = [];
for(var i in encryptResult){
hex.push(parseInt(encryptResult[i],16))
}
hex.unshift(parseInt("04",16));
hex.unshift(parseInt("AE",16));
that.writeBLECharacteristicValue(hex);//返回App加密后的指令
}
break;
case "BB":
case "bb":
switch(turn_back[1]){
case '02'://开启格子反馈
wx.hideLoading({
success: (res) => {
wx.showToast({
title: '开启成功',
})
},
})
break;
case '03':
setTimeout(function(){
wx.hideLoading({
success: (res) => {
wx.showToast({
title: '执行完毕',
})
},
})
},3000);
break;
case '06'://电量返回
var power = turn_back[Number(turn_back.length-1)];
power = Number(power)/10;
that.power = power;
break;
}
break;
}
}, function (err) {
console.log(err)
})
}
// 发送指令API
writeBLECharacteristicValue(hex){
var that = this;
var deviceId = this.deviceId;
var buffer = new ArrayBuffer(Number(hex.length));
console.log(deviceId);
console.log(serviceId);
console.log(writeCharacteristic);
if(hex){
for(var i in hex){
new DataView(buffer).setInt8(Number(i),hex[i]);
}
}else{
console.log("未输入指令");
return;
}
console.log("发送=》"+that.buf2hex(buffer));
wx.writeBLECharacteristicValue({
deviceId: deviceId,
serviceId: serviceId,
characteristicId: writeCharacteristic,
value: buffer,
success: function (res) {
console.log("发送指令成功")
},
fail: function (err) {
console.log("指令发送失败", err)
}
})
}
//停止搜索设备
stopBluetoothDevicesDiscovery() {
wx.stopBluetoothDevicesDiscovery({
success: function (res) {
console.log("停止搜索设备" + JSON.stringify(res.errMsg))
}
})
}
//连接失败
connectFail(){
wx.hideLoading({
success: (res) => {
wx.showToast({
title: '连接失败',
icon: "none"
})
},
})
return false;
}
//关闭蓝牙适配器
closeBluetoothAdapter() {
var that = this;
wx.closeBluetoothAdapter({
success(res) {
that.isConnect = false;
console.log("断开蓝牙模块", res);
}
})
}
//关闭蓝牙连接
closeBLEConnection() {
var that = this;
var deviceId = this.deviceId;
wx.closeBLEConnection({
deviceId: deviceId,
success(res) {
console.log("断开蓝牙连接", res);
that.isConnect = false;
wx.showToast({
title: '已断开连接',
icon:"none"
})
}
})
}
buf2hex(buffer) {
return Array.prototype.map.call(new Uint8Array(buffer), x => ('00' + x.toString(16)).slice(-2)).join('');
}
//16进制转字符串
hex2str(hex) {
var rawStr = hex.substr(0, 2).toLowerCase() === "0x" ? hex.substr(2) : hex;
var len = rawStr.length;
if (len % 2 !== 0) {
console.log("Illegal Format ASCII Code!");
return "";
}
var curCharCode;
var resultStr = [];
for (var i = 0; i < len; i = i + 2) {
curCharCode = parseInt(rawStr.substr(i, 2), 16);
resultStr.push(String.fromCharCode(curCharCode));
}
return resultStr.join("");
}
// 字符串转16进制
str2hex(str) {
if (str === "") {
return "";
}
var arr = [];
// arr.push("0x");
for (var i = 0; i < str.length; i++) {
arr.push(str.charCodeAt(i).toString(16));
}
return arr.join('');
}
//格式化hex
hexEncode(hex){
let hex_arr = [];
for(let i=0;i<hex.length;i+=2){
hex_arr.push(hex.substr(i,2).toUpperCase());
}
return hex_arr;
}
//生成随机字符串
getRandomString(len){
len = len || 16;
var $chars = 'qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM1234567890';
var maxPos = $chars.length;
var pwd = '';
for (let i = 0; i < len; i++) {
pwd += $chars.charAt(Math.floor(Math.random() * maxPos));
}
return pwd;
}
}
module.exports = D600;
\ No newline at end of file
var Crypto = exports.Crypto = require('./lib/Crypto').Crypto;
[ 'CryptoMath'
, 'BlockModes'
, 'DES'
, 'AES'
, 'HMAC'
, 'MARC4'
, 'MD5'
, 'PBKDF2'
, 'PBKDF2Async'
, 'Rabbit'
, 'SHA1'
, 'SHA256'
].forEach( function (path) {
require('./lib/' + path);
});
(function(){
var C = (typeof window === 'undefined') ? require('./Crypto').Crypto : window.Crypto;
// Shortcuts
var util = C.util,
charenc = C.charenc,
UTF8 = charenc.UTF8;
// Precomputed SBOX
var SBOX = [ 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5,
0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0,
0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc,
0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a,
0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0,
0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b,
0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85,
0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5,
0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17,
0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88,
0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c,
0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9,
0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6,
0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e,
0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94,
0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68,
0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 ];
// Compute inverse SBOX lookup table
for (var INVSBOX = [], i = 0; i < 256; i++) INVSBOX[SBOX[i]] = i;
// Compute mulitplication in GF(2^8) lookup tables
var MULT2 = [],
MULT3 = [],
MULT9 = [],
MULTB = [],
MULTD = [],
MULTE = [];
function xtime(a, b) {
for (var result = 0, i = 0; i < 8; i++) {
if (b & 1) result ^= a;
var hiBitSet = a & 0x80;
a = (a << 1) & 0xFF;
if (hiBitSet) a ^= 0x1b;
b >>>= 1;
}
return result;
}
for (var i = 0; i < 256; i++) {
MULT2[i] = xtime(i,2);
MULT3[i] = xtime(i,3);
MULT9[i] = xtime(i,9);
MULTB[i] = xtime(i,0xB);
MULTD[i] = xtime(i,0xD);
MULTE[i] = xtime(i,0xE);
}
// Precomputed RCon lookup
var RCON = [0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36];
// Inner state
var state = [[], [], [], []],
keylength,
nrounds,
keyschedule;
var AES = C.AES = {
/**
* Public API
*/
encrypt: function (message, password, options) {
options = options || {};
// Determine mode
var mode = options.mode || new C.mode.OFB;
// Allow mode to override options
if (mode.fixOptions) mode.fixOptions(options);
var
// Convert to bytes if message is a string
m = (
message.constructor == String ?
UTF8.stringToBytes(message) :
message
),
// Generate random IV
iv = options.iv || util.randomBytes(AES._blocksize * 4),
// Generate key
k = (
password.constructor == String ?
// Derive key from passphrase
C.PBKDF2(password, iv, 32, { asBytes: true }) :
// else, assume byte array representing cryptographic key
password
);
// Encrypt
AES._init(k);
mode.encrypt(AES, m, iv);
// Return ciphertext
m = options.iv ? m : iv.concat(m);
return (options && options.asBytes) ? m : util.bytesToBase64(m);
},
decrypt: function (ciphertext, password, options) {
options = options || {};
// Determine mode
var mode = options.mode || new C.mode.OFB;
// Allow mode to override options
if (mode.fixOptions) mode.fixOptions(options);
var
// Convert to bytes if ciphertext is a string
c = (
ciphertext.constructor == String ?
util.base64ToBytes(ciphertext):
ciphertext
),
// Separate IV and message
iv = options.iv || c.splice(0, AES._blocksize * 4),
// Generate key
k = (
password.constructor == String ?
// Derive key from passphrase
C.PBKDF2(password, iv, 32, { asBytes: true }) :
// else, assume byte array representing cryptographic key
password
);
// Decrypt
AES._init(k);
mode.decrypt(AES, c, iv);
// Return plaintext
return (options && options.asBytes) ? c : UTF8.bytesToString(c);
},
/**
* Package private methods and properties
*/
_blocksize: 4,
_encryptblock: function (m, offset) {
// Set input
for (var row = 0; row < AES._blocksize; row++) {
for (var col = 0; col < 4; col++)
state[row][col] = m[offset + col * 4 + row];
}
// Add round key
for (var row = 0; row < 4; row++) {
for (var col = 0; col < 4; col++)
state[row][col] ^= keyschedule[col][row];
}
for (var round = 1; round < nrounds; round++) {
// Sub bytes
for (var row = 0; row < 4; row++) {
for (var col = 0; col < 4; col++)
state[row][col] = SBOX[state[row][col]];
}
// Shift rows
state[1].push(state[1].shift());
state[2].push(state[2].shift());
state[2].push(state[2].shift());
state[3].unshift(state[3].pop());
// Mix columns
for (var col = 0; col < 4; col++) {
var s0 = state[0][col],
s1 = state[1][col],
s2 = state[2][col],
s3 = state[3][col];
state[0][col] = MULT2[s0] ^ MULT3[s1] ^ s2 ^ s3;
state[1][col] = s0 ^ MULT2[s1] ^ MULT3[s2] ^ s3;
state[2][col] = s0 ^ s1 ^ MULT2[s2] ^ MULT3[s3];
state[3][col] = MULT3[s0] ^ s1 ^ s2 ^ MULT2[s3];
}
// Add round key
for (var row = 0; row < 4; row++) {
for (var col = 0; col < 4; col++)
state[row][col] ^= keyschedule[round * 4 + col][row];
}
}
// Sub bytes
for (var row = 0; row < 4; row++) {
for (var col = 0; col < 4; col++)
state[row][col] = SBOX[state[row][col]];
}
// Shift rows
state[1].push(state[1].shift());
state[2].push(state[2].shift());
state[2].push(state[2].shift());
state[3].unshift(state[3].pop());
// Add round key
for (var row = 0; row < 4; row++) {
for (var col = 0; col < 4; col++)
state[row][col] ^= keyschedule[nrounds * 4 + col][row];
}
// Set output
for (var row = 0; row < AES._blocksize; row++) {
for (var col = 0; col < 4; col++)
m[offset + col * 4 + row] = state[row][col];
}
},
_decryptblock: function (c, offset) {
// Set input
for (var row = 0; row < AES._blocksize; row++) {
for (var col = 0; col < 4; col++)
state[row][col] = c[offset + col * 4 + row];
}
// Add round key
for (var row = 0; row < 4; row++) {
for (var col = 0; col < 4; col++)
state[row][col] ^= keyschedule[nrounds * 4 + col][row];
}
for (var round = 1; round < nrounds; round++) {
// Inv shift rows
state[1].unshift(state[1].pop());
state[2].push(state[2].shift());
state[2].push(state[2].shift());
state[3].push(state[3].shift());
// Inv sub bytes
for (var row = 0; row < 4; row++) {
for (var col = 0; col < 4; col++)
state[row][col] = INVSBOX[state[row][col]];
}
// Add round key
for (var row = 0; row < 4; row++) {
for (var col = 0; col < 4; col++)
state[row][col] ^= keyschedule[(nrounds - round) * 4 + col][row];
}
// Inv mix columns
for (var col = 0; col < 4; col++) {
var s0 = state[0][col],
s1 = state[1][col],
s2 = state[2][col],
s3 = state[3][col];
state[0][col] = MULTE[s0] ^ MULTB[s1] ^ MULTD[s2] ^ MULT9[s3];
state[1][col] = MULT9[s0] ^ MULTE[s1] ^ MULTB[s2] ^ MULTD[s3];
state[2][col] = MULTD[s0] ^ MULT9[s1] ^ MULTE[s2] ^ MULTB[s3];
state[3][col] = MULTB[s0] ^ MULTD[s1] ^ MULT9[s2] ^ MULTE[s3];
}
}
// Inv shift rows
state[1].unshift(state[1].pop());
state[2].push(state[2].shift());
state[2].push(state[2].shift());
state[3].push(state[3].shift());
// Inv sub bytes
for (var row = 0; row < 4; row++) {
for (var col = 0; col < 4; col++)
state[row][col] = INVSBOX[state[row][col]];
}
// Add round key
for (var row = 0; row < 4; row++) {
for (var col = 0; col < 4; col++)
state[row][col] ^= keyschedule[col][row];
}
// Set output
for (var row = 0; row < AES._blocksize; row++) {
for (var col = 0; col < 4; col++)
c[offset + col * 4 + row] = state[row][col];
}
},
/**
* Private methods
*/
_init: function (k) {
keylength = k.length / 4;
nrounds = keylength + 6;
AES._keyexpansion(k);
},
// Generate a key schedule
_keyexpansion: function (k) {
keyschedule = [];
for (var row = 0; row < keylength; row++) {
keyschedule[row] = [
k[row * 4],
k[row * 4 + 1],
k[row * 4 + 2],
k[row * 4 + 3]
];
}
for (var row = keylength; row < AES._blocksize * (nrounds + 1); row++) {
var temp = [
keyschedule[row - 1][0],
keyschedule[row - 1][1],
keyschedule[row - 1][2],
keyschedule[row - 1][3]
];
if (row % keylength == 0) {
// Rot word
temp.push(temp.shift());
// Sub word
temp[0] = SBOX[temp[0]];
temp[1] = SBOX[temp[1]];
temp[2] = SBOX[temp[2]];
temp[3] = SBOX[temp[3]];
temp[0] ^= RCON[row / keylength];
} else if (keylength > 6 && row % keylength == 4) {
// Sub word
temp[0] = SBOX[temp[0]];
temp[1] = SBOX[temp[1]];
temp[2] = SBOX[temp[2]];
temp[3] = SBOX[temp[3]];
}
keyschedule[row] = [
keyschedule[row - keylength][0] ^ temp[0],
keyschedule[row - keylength][1] ^ temp[1],
keyschedule[row - keylength][2] ^ temp[2],
keyschedule[row - keylength][3] ^ temp[3]
];
}
}
};
})();
/*!
* Crypto-JS contribution from Simon Greatrix
*/
(function(){
var C = (typeof window === 'undefined') ? require('./Crypto').Crypto : window.Crypto;
// Create pad namespace
var C_pad = C.pad = {};
// Calculate the number of padding bytes required.
function _requiredPadding(cipher, message) {
var blockSizeInBytes = cipher._blocksize * 4;
var reqd = blockSizeInBytes - message.length % blockSizeInBytes;
return reqd;
};
// Remove padding when the final byte gives the number of padding bytes.
var _unpadLength = function (message) {
var pad = message.pop();
for (var i = 1; i < pad; i++) {
message.pop();
}
};
// No-operation padding, used for stream ciphers
C_pad.NoPadding = {
pad : function (cipher,message) {},
unpad : function (message) {}
};
// Zero Padding.
//
// If the message is not an exact number of blocks, the final block is
// completed with 0x00 bytes. There is no unpadding.
C_pad.ZeroPadding = {
pad : function (cipher, message) {
var blockSizeInBytes = cipher._blocksize * 4;
var reqd = message.length % blockSizeInBytes;
if( reqd!=0 ) {
for(reqd = blockSizeInBytes - reqd; reqd>0; reqd--) {
message.push(0x00);
}
}
},
unpad : function (message) {}
};
// ISO/IEC 7816-4 padding.
//
// Pads the plain text with an 0x80 byte followed by as many 0x00
// bytes are required to complete the block.
C_pad.iso7816 = {
pad : function (cipher, message) {
var reqd = _requiredPadding(cipher, message);
message.push(0x80);
for (; reqd > 1; reqd--) {
message.push(0x00);
}
},
unpad : function (message) {
while (message.pop() != 0x80) {}
}
};
// ANSI X.923 padding
//
// The final block is padded with zeros except for the last byte of the
// last block which contains the number of padding bytes.
C_pad.ansix923 = {
pad : function (cipher, message) {
var reqd = _requiredPadding(cipher, message);
for (var i = 1; i < reqd; i++) {
message.push(0x00);
}
message.push(reqd);
},
unpad : _unpadLength
};
// ISO 10126
//
// The final block is padded with random bytes except for the last
// byte of the last block which contains the number of padding bytes.
C_pad.iso10126 = {
pad : function (cipher, message) {
var reqd = _requiredPadding(cipher, message);
for (var i = 1; i < reqd; i++) {
message.push(Math.floor(Math.random() * 256));
}
message.push(reqd);
},
unpad : _unpadLength
};
// PKCS7 padding
//
// PKCS7 is described in RFC 5652. Padding is in whole bytes. The
// value of each added byte is the number of bytes that are added,
// i.e. N bytes, each of value N are added.
C_pad.pkcs7 = {
pad : function (cipher, message) {
var reqd = _requiredPadding(cipher, message);
for (var i = 0; i < reqd; i++) {
message.push(reqd);
}
},
unpad : _unpadLength
};
// Create mode namespace
var C_mode = C.mode = {};
/**
* Mode base "class".
*/
var Mode = C_mode.Mode = function (padding) {
if (padding) {
this._padding = padding;
}
};
Mode.prototype = {
encrypt: function (cipher, m, iv) {
this._padding.pad(cipher, m);
this._doEncrypt(cipher, m, iv);
},
decrypt: function (cipher, m, iv) {
this._doDecrypt(cipher, m, iv);
this._padding.unpad(m);
},
// Default padding
_padding: C_pad.iso7816
};
/**
* Electronic Code Book mode.
*
* ECB applies the cipher directly against each block of the input.
*
* ECB does not require an initialization vector.
*/
var ECB = C_mode.ECB = function () {
// Call parent constructor
Mode.apply(this, arguments);
};
// Inherit from Mode
var ECB_prototype = ECB.prototype = new Mode;
// Concrete steps for Mode template
ECB_prototype._doEncrypt = function (cipher, m, iv) {
var blockSizeInBytes = cipher._blocksize * 4;
// Encrypt each block
for (var offset = 0; offset < m.length; offset += blockSizeInBytes) {
cipher._encryptblock(m, offset);
}
};
ECB_prototype._doDecrypt = function (cipher, c, iv) {
var blockSizeInBytes = cipher._blocksize * 4;
// Decrypt each block
for (var offset = 0; offset < c.length; offset += blockSizeInBytes) {
cipher._decryptblock(c, offset);
}
};
// ECB never uses an IV
ECB_prototype.fixOptions = function (options) {
options.iv = [];
};
/**
* Cipher block chaining
*
* The first block is XORed with the IV. Subsequent blocks are XOR with the
* previous cipher output.
*/
var CBC = C_mode.CBC = function () {
// Call parent constructor
Mode.apply(this, arguments);
};
// Inherit from Mode
var CBC_prototype = CBC.prototype = new Mode;
// Concrete steps for Mode template
CBC_prototype._doEncrypt = function (cipher, m, iv) {
var blockSizeInBytes = cipher._blocksize * 4;
// Encrypt each block
for (var offset = 0; offset < m.length; offset += blockSizeInBytes) {
if (offset == 0) {
// XOR first block using IV
for (var i = 0; i < blockSizeInBytes; i++)
m[i] ^= iv[i];
} else {
// XOR this block using previous crypted block
for (var i = 0; i < blockSizeInBytes; i++)
m[offset + i] ^= m[offset + i - blockSizeInBytes];
}
// Encrypt block
cipher._encryptblock(m, offset);
}
};
CBC_prototype._doDecrypt = function (cipher, c, iv) {
var blockSizeInBytes = cipher._blocksize * 4;
// At the start, the previously crypted block is the IV
var prevCryptedBlock = iv;
// Decrypt each block
for (var offset = 0; offset < c.length; offset += blockSizeInBytes) {
// Save this crypted block
var thisCryptedBlock = c.slice(offset, offset + blockSizeInBytes);
// Decrypt block
cipher._decryptblock(c, offset);
// XOR decrypted block using previous crypted block
for (var i = 0; i < blockSizeInBytes; i++) {
c[offset + i] ^= prevCryptedBlock[i];
}
prevCryptedBlock = thisCryptedBlock;
}
};
/**
* Cipher feed back
*
* The cipher output is XORed with the plain text to produce the cipher output,
* which is then fed back into the cipher to produce a bit pattern to XOR the
* next block with.
*
* This is a stream cipher mode and does not require padding.
*/
var CFB = C_mode.CFB = function () {
// Call parent constructor
Mode.apply(this, arguments);
};
// Inherit from Mode
var CFB_prototype = CFB.prototype = new Mode;
// Override padding
CFB_prototype._padding = C_pad.NoPadding;
// Concrete steps for Mode template
CFB_prototype._doEncrypt = function (cipher, m, iv) {
var blockSizeInBytes = cipher._blocksize * 4,
keystream = iv.slice(0);
// Encrypt each byte
for (var i = 0; i < m.length; i++) {
var j = i % blockSizeInBytes;
if (j == 0) cipher._encryptblock(keystream, 0);
m[i] ^= keystream[j];
keystream[j] = m[i];
}
};
CFB_prototype._doDecrypt = function (cipher, c, iv) {
var blockSizeInBytes = cipher._blocksize * 4,
keystream = iv.slice(0);
// Encrypt each byte
for (var i = 0; i < c.length; i++) {
var j = i % blockSizeInBytes;
if (j == 0) cipher._encryptblock(keystream, 0);
var b = c[i];
c[i] ^= keystream[j];
keystream[j] = b;
}
};
/**
* Output feed back
*
* The cipher repeatedly encrypts its own output. The output is XORed with the
* plain text to produce the cipher text.
*
* This is a stream cipher mode and does not require padding.
*/
var OFB = C_mode.OFB = function () {
// Call parent constructor
Mode.apply(this, arguments);
};
// Inherit from Mode
var OFB_prototype = OFB.prototype = new Mode;
// Override padding
OFB_prototype._padding = C_pad.NoPadding;
// Concrete steps for Mode template
OFB_prototype._doEncrypt = function (cipher, m, iv) {
var blockSizeInBytes = cipher._blocksize * 4,
keystream = iv.slice(0);
// Encrypt each byte
for (var i = 0; i < m.length; i++) {
// Generate keystream
if (i % blockSizeInBytes == 0)
cipher._encryptblock(keystream, 0);
// Encrypt byte
m[i] ^= keystream[i % blockSizeInBytes];
}
};
OFB_prototype._doDecrypt = OFB_prototype._doEncrypt;
/**
* Counter
* @author Gergely Risko
*
* After every block the last 4 bytes of the IV is increased by one
* with carry and that IV is used for the next block.
*
* This is a stream cipher mode and does not require padding.
*/
var CTR = C_mode.CTR = function () {
// Call parent constructor
Mode.apply(this, arguments);
};
// Inherit from Mode
var CTR_prototype = CTR.prototype = new Mode;
// Override padding
CTR_prototype._padding = C_pad.NoPadding;
CTR_prototype._doEncrypt = function (cipher, m, iv) {
var blockSizeInBytes = cipher._blocksize * 4;
var counter = iv.slice(0);
for (var i = 0; i < m.length;) {
// do not lose iv
var keystream = counter.slice(0);
// Generate keystream for next block
cipher._encryptblock(keystream, 0);
// XOR keystream with block
for (var j = 0; i < m.length && j < blockSizeInBytes; j++, i++) {
m[i] ^= keystream[j];
}
// Increase counter
if(++(counter[blockSizeInBytes-1]) == 256) {
counter[blockSizeInBytes-1] = 0;
if(++(counter[blockSizeInBytes-2]) == 256) {
counter[blockSizeInBytes-2] = 0;
if(++(counter[blockSizeInBytes-3]) == 256) {
counter[blockSizeInBytes-3] = 0;
++(counter[blockSizeInBytes-4]);
}
}
}
}
};
CTR_prototype._doDecrypt = CTR_prototype._doEncrypt;
})();
if (typeof Crypto == "undefined" || ! Crypto.util)
{
(function(){
var base64map = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
// Global Crypto object
// with browser window or with node module
var Crypto = (typeof window === 'undefined') ? exports.Crypto = {} : window.Crypto = {};
// Crypto utilities
var util = Crypto.util = {
// Bit-wise rotate left
rotl: function (n, b) {
return (n << b) | (n >>> (32 - b));
},
// Bit-wise rotate right
rotr: function (n, b) {
return (n << (32 - b)) | (n >>> b);
},
// Swap big-endian to little-endian and vice versa
endian: function (n) {
// If number given, swap endian
if (n.constructor == Number) {
return util.rotl(n, 8) & 0x00FF00FF |
util.rotl(n, 24) & 0xFF00FF00;
}
// Else, assume array and swap all items
for (var i = 0; i < n.length; i++)
n[i] = util.endian(n[i]);
return n;
},
// Generate an array of any length of random bytes
randomBytes: function (n) {
for (var bytes = []; n > 0; n--)
bytes.push(Math.floor(Math.random() * 256));
return bytes;
},
// Convert a byte array to big-endian 32-bit words
bytesToWords: function (bytes) {
for (var words = [], i = 0, b = 0; i < bytes.length; i++, b += 8)
words[b >>> 5] |= (bytes[i] & 0xFF) << (24 - b % 32);
return words;
},
// Convert big-endian 32-bit words to a byte array
wordsToBytes: function (words) {
for (var bytes = [], b = 0; b < words.length * 32; b += 8)
bytes.push((words[b >>> 5] >>> (24 - b % 32)) & 0xFF);
return bytes;
},
// Convert a byte array to a hex string
bytesToHex: function (bytes) {
for (var hex = [], i = 0; i < bytes.length; i++) {
hex.push((bytes[i] >>> 4).toString(16));
hex.push((bytes[i] & 0xF).toString(16));
}
return hex.join("");
},
// Convert a hex string to a byte array
hexToBytes: function (hex) {
for (var bytes = [], c = 0; c < hex.length; c += 2)
bytes.push(parseInt(hex.substr(c, 2), 16));
return bytes;
},
// Convert a byte array to a base-64 string
bytesToBase64: function (bytes) {
// Use browser-native function if it exists
if (typeof btoa == "function") return btoa(Binary.bytesToString(bytes));
for(var base64 = [], i = 0; i < bytes.length; i += 3) {
var triplet = (bytes[i] << 16) | (bytes[i + 1] << 8) | bytes[i + 2];
for (var j = 0; j < 4; j++) {
if (i * 8 + j * 6 <= bytes.length * 8)
base64.push(base64map.charAt((triplet >>> 6 * (3 - j)) & 0x3F));
else base64.push("=");
}
}
return base64.join("");
},
// Convert a base-64 string to a byte array
base64ToBytes: function (base64) {
// Use browser-native function if it exists
if (typeof atob == "function") return Binary.stringToBytes(atob(base64));
// Remove non-base-64 characters
base64 = base64.replace(/[^A-Z0-9+\/]/ig, "");
for (var bytes = [], i = 0, imod4 = 0; i < base64.length; imod4 = ++i % 4) {
if (imod4 == 0) continue;
bytes.push(((base64map.indexOf(base64.charAt(i - 1)) & (Math.pow(2, -2 * imod4 + 8) - 1)) << (imod4 * 2)) |
(base64map.indexOf(base64.charAt(i)) >>> (6 - imod4 * 2)));
}
return bytes;
}
};
// Crypto character encodings
var charenc = Crypto.charenc = {};
// UTF-8 encoding
var UTF8 = charenc.UTF8 = {
// Convert a string to a byte array
stringToBytes: function (str) {
return Binary.stringToBytes(unescape(encodeURIComponent(str)));
},
// Convert a byte array to a string
bytesToString: function (bytes) {
return decodeURIComponent(escape(Binary.bytesToString(bytes)));
}
};
// Binary encoding
var Binary = charenc.Binary = {
// Convert a string to a byte array
stringToBytes: function (str) {
for (var bytes = [], i = 0; i < str.length; i++)
bytes.push(str.charCodeAt(i) & 0xFF);
return bytes;
},
// Convert a byte array to a string
bytesToString: function (bytes) {
for (var str = [], i = 0; i < bytes.length; i++)
str.push(String.fromCharCode(bytes[i]));
return str.join("");
}
};
})();
}
(function(){
var C = (typeof window === 'undefined') ? require('./Crypto').Crypto : window.Crypto;
// Shortcut
var util = C.util;
// Convert n to unsigned 32-bit integer
util.u32 = function (n) {
return n >>> 0;
};
// Unsigned 32-bit addition
util.add = function () {
var result = this.u32(arguments[0]);
for (var i = 1; i < arguments.length; i++)
result = this.u32(result + this.u32(arguments[i]));
return result;
};
// Unsigned 32-bit multiplication
util.mult = function (m, n) {
return this.add((n & 0xFFFF0000) * m,
(n & 0x0000FFFF) * m);
};
// Unsigned 32-bit greater than (>) comparison
util.gt = function (m, n) {
return this.u32(m) > this.u32(n);
};
// Unsigned 32-bit less than (<) comparison
util.lt = function (m, n) {
return this.u32(m) < this.u32(n);
};
})();
/**
* Definition of Data Encryption Standard (DES) taken from:
* http://www.itl.nist.gov/fipspubs/fip46-2.htm
*/
(function() {
var C = (typeof window === 'undefined') ? require('./Crypto').Crypto : window.Crypto;
// Shortcuts
var util = C.util, charenc = C.charenc, UTF8 = charenc.UTF8;
/***************************************************************************
*
* DES Key Schedule.
*
* The Key consists of 16 sub-keys of 48 bits each. As each sub-key is
* applied to an expanded 32-bit value where each 4 bits of input is
* expanded into 6 bits of output the sub-key can be broken down into 8
* 32-bit values which allows the key to be used without expansion.
*
* To create the 16 sub-keys, 56 bits are selected from the input 64 bit key
* according to <i>PC1</i>. Each sub-key is generated by left rotating the
* bits a different amount and then selecting 48 bits according to <i>PC2</i>.
*
**************************************************************************/
var KeySchedule;
/**
* Representation of a DES key schedule.
*
* @param {Array
* of 8 bytes} key The cipher key
*
* @constructor
*/
KeySchedule = function(key) {
/**
* The schedule of 16 keys
*/
this.keys = new Array(16);
this._initialiseKeys(key);
};
/**
* Permuted Choice 1 (PC1) byte offsets into the key. Each of the 56 entries
* selects one bit of DES's 56 bit key.
* <p>
*
* <pre>
* The PC1 is defined as:
*
* 57, 49, 41, 33, 25, 17, 9,
* 1, 58, 50, 42, 34, 26, 18,
* 10, 2, 59, 51, 43, 35, 27,
* 19, 11, 3, 60, 52, 44, 36,
* 63, 55, 47, 39, 31, 23, 15,
* 7, 62, 54, 46, 38, 30, 22,
* 14, 6, 61, 53, 45, 37, 29,
* 21, 13, 5, 28, 20, 12, 4
* </pre>
*
* We represent this as an offset into an 8-byte array and a bit mask upon
* that byte. For example 57=(7*8)+1 so is the first (MSB) of the 7th byte.
*
* @constant
*/
KeySchedule.PC1_offsets = [ 7, 6, 5, 4, 3, 2, 1, 0, 7, 6, 5, 4, 3, 2, 1, 0,
7, 6, 5, 4, 3, 2, 1, 0, 7, 6, 5, 4, 7, 6, 5, 4, 3, 2, 1, 0, 7, 6,
5, 4, 3, 2, 1, 0, 7, 6, 5, 4, 3, 2, 1, 0, 3, 2, 1, 0 ];
/**
* Permuted Choice 1 (PC1) bit masks. Each of the 56 entries selects one bit
* of DES's 56 bit key.
*
* @constant
*/
KeySchedule.PC1_masks = [ 128, 128, 128, 128, 128, 128, 128, 128, 64, 64,
64, 64, 64, 64, 64, 64, 32, 32, 32, 32, 32, 32, 32, 32, 16, 16, 16,
16, 2, 2, 2, 2, 2, 2, 2, 2, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8, 8,
8, 8, 8, 16, 16, 16, 16 ];
/**
* Permuted Choice 2 (PC2) selects the active 48 bits from the 56 bits of
* the key.
* <p>
*
* <pre>
* The PC2 is defined as:
*
* 14, 17, 11, 24, 1, 5,
* 3, 28, 15, 6, 21, 10,
* 23, 19, 12, 4, 26, 8,
* 16, 7, 27, 20, 13, 2,
* 41, 52, 31, 37, 47, 55,
* 30, 40, 51, 45, 33, 48,
* 44, 49, 39, 56, 34, 53,
* 46, 42, 50, 36, 29, 32
* </pre>
*
* We invert the choice to specify what each bit adds to each 6-bit value of
* the key. For example, bit 1 is the 5th bit selected so this add 2 to the
* first 6-bit value.
*
* @constant
*/
KeySchedule.PC2_offsets1 = [ 0, 3, 1, 2, 0, 1, 3, 2, 0, 1, 0, 2, 3, 0, 1,
3, 0, 0, 2, 3, 1, 0, 2, 0, 0, 2, 3, 1 ];
/**
* PC2 offsets for 2nd block.
*
* @constant
*/
KeySchedule.PC2_offsets2 = [ 7, 5, 4, 7, 5, 6, 0, 7, 4, 0, 6, 5, 4, 7, 0,
6, 5, 7, 4, 5, 6, 7, 5, 4, 6, 0, 4, 6 ];
/**
* Permuted Choice 2 (PC2) masks for 1st block.
*
* @constant
*/
KeySchedule.PC2_masks1 = [ 2, 1, 32, 4, 1, 4, 16, 1, 0, 1, 8, 8, 2, 32, 8,
32, 16, 0, 16, 4, 2, 0, 32, 4, 0, 2, 8, 16 ];
/**
* PC2 masks for 2nd block.
*
* @constant
*/
KeySchedule.PC2_masks2 = [ 2, 32, 8, 1, 2, 2, 0, 4, 4, 0, 8, 16, 32, 16, 0,
32, 4, 32, 2, 1, 16, 8, 8, 16, 1, 0, 1, 4 ];
/**
* Cumulative key shifts.
*
* @constant
*/
KeySchedule.keyShifts = [ 1, 2, 4, 6, 8, 10, 12, 14, 15, 17, 19, 21, 23,
25, 27, 28 ];
KeySchedule.prototype._initialiseKeys = function(key) {
var i;
// extract 56 key bits in order determined by PC1
var bits = new Array(56);
for (i = 0; i < 56; i++) {
bits[i] = (key[KeySchedule.PC1_offsets[i]] & KeySchedule.PC1_masks[i]) != 0;
}
// split 56 bits into two 28-bit chunks
var bits1 = bits.slice(0, 28);
var bits2 = bits.slice(28, 56);
// duplicate each half to allow for easy bit shifts
bits1 = bits1.concat(bits1);
bits2 = bits2.concat(bits2);
// assemble the 16 keys
for (i = 0; i < 16; i++) {
var k = [ 0, 0, 0, 0, 0, 0, 0, 0 ];
// select the bits of the key according to PC2
var s = KeySchedule.keyShifts[i];
for ( var j = 0; j < 28; j++) {
if (bits1[j + s]) {
k[KeySchedule.PC2_offsets1[j]] += KeySchedule.PC2_masks1[j];
}
if (bits2[j + s]) {
k[KeySchedule.PC2_offsets2[j]] += KeySchedule.PC2_masks2[j];
}
}
// Scale each of the 8 blocks to a 32-bit mask.
k[0] = ((k[0] & 0x1f) << 27) + ((k[0] & 0x20) >> 5);
for ( var j = 1; j <= 6; j++) {
k[j] = k[j] << (27 - 4 * j);
}
k[7] = ((k[7] & 0x3e) >> 1) + ((k[7] & 0x1) << 31);
this.keys[i] = k;
}
};
/**
* Retrieve the key for a specified round
*
* @param i
* the round
* @returns the key
*/
KeySchedule.prototype.getKey = function(i) {
return this.keys[i];
};
/***************************************************************************
*
* DES Engine State
*
**************************************************************************/
var State;
/**
* The algorithm's state. DES operates on two sets of 32-bits, with each
* block of 32-bits treated as a single number.
*
* @class
*/
State = function() {
/** The LHS of the Feistel scheme */
this.lhs = 0;
/** The RHS of the Feistel scheme */
this.rhs = 0;
};
/**
* The masks that select the SBOX input. Each SBOX accepts 6 bits from the
* input.
*
* @constant
*/
State.SBOX_MASK = [ 0xf8000001, 0x1f800000, 0x01f80000, 0x001f8000,
0x0001f800, 0x00001f80, 0x000001f8, 0x8000001f ];
/**
* The SBOXes. The 8 SBOXes each map 6 bit masked bit of the input to 4 bits
* of output. These SBOXes include the post SBOX permutation and benefit
* from JavaScript's sparse arrays to make specifying the input match
* simple.
*
* @constant
*/
State.SBOX = new Array(8);
var SBOX = State.SBOX;
SBOX[0] = new Array();
SBOX[0][0] = 0x808200; // 0 (0, 0) = 14
SBOX[0][268435456] = 0x8000; // 10000000 (0, 1) = 4
SBOX[0][536870912] = 0x808002; // 20000000 (0, 2) = 13
SBOX[0][805306368] = 0x2; // 30000000 (0, 3) = 1
SBOX[0][1073741824] = 0x200; // 40000000 (0, 4) = 2
SBOX[0][1342177280] = 0x808202; // 50000000 (0, 5) = 15
SBOX[0][1610612736] = 0x800202; // 60000000 (0, 6) = 11
SBOX[0][1879048192] = 0x800000; // 70000000 (0, 7) = 8
SBOX[0][-2147483648] = 0x202; // 80000000 (0, 8) = 3
SBOX[0][-1879048192] = 0x800200; // 90000000 (0, 9) = 10
SBOX[0][-1610612736] = 0x8200; // a0000000 (0, 10) = 6
SBOX[0][-1342177280] = 0x808000; // b0000000 (0, 11) = 12
SBOX[0][-1073741824] = 0x8002; // c0000000 (0, 12) = 5
SBOX[0][-805306368] = 0x800002; // d0000000 (0, 13) = 9
SBOX[0][-536870912] = 0x0; // e0000000 (0, 14) = 0
SBOX[0][-268435456] = 0x8202; // f0000000 (0, 15) = 7
SBOX[0][134217728] = 0x0; // 8000000 (1, 0) = 0
SBOX[0][402653184] = 0x808202; // 18000000 (1, 1) = 15
SBOX[0][671088640] = 0x8202; // 28000000 (1, 2) = 7
SBOX[0][939524096] = 0x8000; // 38000000 (1, 3) = 4
SBOX[0][1207959552] = 0x808200; // 48000000 (1, 4) = 14
SBOX[0][1476395008] = 0x200; // 58000000 (1, 5) = 2
SBOX[0][1744830464] = 0x808002; // 68000000 (1, 6) = 13
SBOX[0][2013265920] = 0x2; // 78000000 (1, 7) = 1
SBOX[0][-2013265920] = 0x800200; // 88000000 (1, 8) = 10
SBOX[0][-1744830464] = 0x8200; // 98000000 (1, 9) = 6
SBOX[0][-1476395008] = 0x808000; // a8000000 (1, 10) = 12
SBOX[0][-1207959552] = 0x800202; // b8000000 (1, 11) = 11
SBOX[0][-939524096] = 0x800002; // c8000000 (1, 12) = 9
SBOX[0][-671088640] = 0x8002; // d8000000 (1, 13) = 5
SBOX[0][-402653184] = 0x202; // e8000000 (1, 14) = 3
SBOX[0][-134217728] = 0x800000; // f8000000 (1, 15) = 8
SBOX[0][1] = 0x8000; // 1 (2, 0) = 4
SBOX[0][268435457] = 0x2; // 10000001 (2, 1) = 1
SBOX[0][536870913] = 0x808200; // 20000001 (2, 2) = 14
SBOX[0][805306369] = 0x800000; // 30000001 (2, 3) = 8
SBOX[0][1073741825] = 0x808002; // 40000001 (2, 4) = 13
SBOX[0][1342177281] = 0x8200; // 50000001 (2, 5) = 6
SBOX[0][1610612737] = 0x200; // 60000001 (2, 6) = 2
SBOX[0][1879048193] = 0x800202; // 70000001 (2, 7) = 11
SBOX[0][-2147483647] = 0x808202; // 80000001 (2, 8) = 15
SBOX[0][-1879048191] = 0x808000; // 90000001 (2, 9) = 12
SBOX[0][-1610612735] = 0x800002; // a0000001 (2, 10) = 9
SBOX[0][-1342177279] = 0x8202; // b0000001 (2, 11) = 7
SBOX[0][-1073741823] = 0x202; // c0000001 (2, 12) = 3
SBOX[0][-805306367] = 0x800200; // d0000001 (2, 13) = 10
SBOX[0][-536870911] = 0x8002; // e0000001 (2, 14) = 5
SBOX[0][-268435455] = 0x0; // f0000001 (2, 15) = 0
SBOX[0][134217729] = 0x808202; // 8000001 (3, 0) = 15
SBOX[0][402653185] = 0x808000; // 18000001 (3, 1) = 12
SBOX[0][671088641] = 0x800000; // 28000001 (3, 2) = 8
SBOX[0][939524097] = 0x200; // 38000001 (3, 3) = 2
SBOX[0][1207959553] = 0x8000; // 48000001 (3, 4) = 4
SBOX[0][1476395009] = 0x800002; // 58000001 (3, 5) = 9
SBOX[0][1744830465] = 0x2; // 68000001 (3, 6) = 1
SBOX[0][2013265921] = 0x8202; // 78000001 (3, 7) = 7
SBOX[0][-2013265919] = 0x8002; // 88000001 (3, 8) = 5
SBOX[0][-1744830463] = 0x800202; // 98000001 (3, 9) = 11
SBOX[0][-1476395007] = 0x202; // a8000001 (3, 10) = 3
SBOX[0][-1207959551] = 0x808200; // b8000001 (3, 11) = 14
SBOX[0][-939524095] = 0x800200; // c8000001 (3, 12) = 10
SBOX[0][-671088639] = 0x0; // d8000001 (3, 13) = 0
SBOX[0][-402653183] = 0x8200; // e8000001 (3, 14) = 6
SBOX[0][-134217727] = 0x808002; // f8000001 (3, 15) = 13
SBOX[1] = new Array();
SBOX[1][0] = 0x40084010; // 0 (0, 0) = 15
SBOX[1][16777216] = 0x4000; // 1000000 (0, 1) = 1
SBOX[1][33554432] = 0x80000; // 2000000 (0, 2) = 8
SBOX[1][50331648] = 0x40080010; // 3000000 (0, 3) = 14
SBOX[1][67108864] = 0x40000010; // 4000000 (0, 4) = 6
SBOX[1][83886080] = 0x40084000; // 5000000 (0, 5) = 11
SBOX[1][100663296] = 0x40004000; // 6000000 (0, 6) = 3
SBOX[1][117440512] = 0x10; // 7000000 (0, 7) = 4
SBOX[1][134217728] = 0x84000; // 8000000 (0, 8) = 9
SBOX[1][150994944] = 0x40004010; // 9000000 (0, 9) = 7
SBOX[1][167772160] = 0x40000000; // a000000 (0, 10) = 2
SBOX[1][184549376] = 0x84010; // b000000 (0, 11) = 13
SBOX[1][201326592] = 0x80010; // c000000 (0, 12) = 12
SBOX[1][218103808] = 0x0; // d000000 (0, 13) = 0
SBOX[1][234881024] = 0x4010; // e000000 (0, 14) = 5
SBOX[1][251658240] = 0x40080000; // f000000 (0, 15) = 10
SBOX[1][8388608] = 0x40004000; // 800000 (1, 0) = 3
SBOX[1][25165824] = 0x84010; // 1800000 (1, 1) = 13
SBOX[1][41943040] = 0x10; // 2800000 (1, 2) = 4
SBOX[1][58720256] = 0x40004010; // 3800000 (1, 3) = 7
SBOX[1][75497472] = 0x40084010; // 4800000 (1, 4) = 15
SBOX[1][92274688] = 0x40000000; // 5800000 (1, 5) = 2
SBOX[1][109051904] = 0x80000; // 6800000 (1, 6) = 8
SBOX[1][125829120] = 0x40080010; // 7800000 (1, 7) = 14
SBOX[1][142606336] = 0x80010; // 8800000 (1, 8) = 12
SBOX[1][159383552] = 0x0; // 9800000 (1, 9) = 0
SBOX[1][176160768] = 0x4000; // a800000 (1, 10) = 1
SBOX[1][192937984] = 0x40080000; // b800000 (1, 11) = 10
SBOX[1][209715200] = 0x40000010; // c800000 (1, 12) = 6
SBOX[1][226492416] = 0x84000; // d800000 (1, 13) = 9
SBOX[1][243269632] = 0x40084000; // e800000 (1, 14) = 11
SBOX[1][260046848] = 0x4010; // f800000 (1, 15) = 5
SBOX[1][268435456] = 0x0; // 10000000 (2, 0) = 0
SBOX[1][285212672] = 0x40080010; // 11000000 (2, 1) = 14
SBOX[1][301989888] = 0x40004010; // 12000000 (2, 2) = 7
SBOX[1][318767104] = 0x40084000; // 13000000 (2, 3) = 11
SBOX[1][335544320] = 0x40080000; // 14000000 (2, 4) = 10
SBOX[1][352321536] = 0x10; // 15000000 (2, 5) = 4
SBOX[1][369098752] = 0x84010; // 16000000 (2, 6) = 13
SBOX[1][385875968] = 0x4000; // 17000000 (2, 7) = 1
SBOX[1][402653184] = 0x4010; // 18000000 (2, 8) = 5
SBOX[1][419430400] = 0x80000; // 19000000 (2, 9) = 8
SBOX[1][436207616] = 0x80010; // 1a000000 (2, 10) = 12
SBOX[1][452984832] = 0x40000010; // 1b000000 (2, 11) = 6
SBOX[1][469762048] = 0x84000; // 1c000000 (2, 12) = 9
SBOX[1][486539264] = 0x40004000; // 1d000000 (2, 13) = 3
SBOX[1][503316480] = 0x40000000; // 1e000000 (2, 14) = 2
SBOX[1][520093696] = 0x40084010; // 1f000000 (2, 15) = 15
SBOX[1][276824064] = 0x84010; // 10800000 (3, 0) = 13
SBOX[1][293601280] = 0x80000; // 11800000 (3, 1) = 8
SBOX[1][310378496] = 0x40080000; // 12800000 (3, 2) = 10
SBOX[1][327155712] = 0x4000; // 13800000 (3, 3) = 1
SBOX[1][343932928] = 0x40004000; // 14800000 (3, 4) = 3
SBOX[1][360710144] = 0x40084010; // 15800000 (3, 5) = 15
SBOX[1][377487360] = 0x10; // 16800000 (3, 6) = 4
SBOX[1][394264576] = 0x40000000; // 17800000 (3, 7) = 2
SBOX[1][411041792] = 0x40084000; // 18800000 (3, 8) = 11
SBOX[1][427819008] = 0x40000010; // 19800000 (3, 9) = 6
SBOX[1][444596224] = 0x40004010; // 1a800000 (3, 10) = 7
SBOX[1][461373440] = 0x80010; // 1b800000 (3, 11) = 12
SBOX[1][478150656] = 0x0; // 1c800000 (3, 12) = 0
SBOX[1][494927872] = 0x4010; // 1d800000 (3, 13) = 5
SBOX[1][511705088] = 0x40080010; // 1e800000 (3, 14) = 14
SBOX[1][528482304] = 0x84000; // 1f800000 (3, 15) = 9
SBOX[2] = new Array();
SBOX[2][0] = 0x104; // 0 (0, 0) = 10
SBOX[2][1048576] = 0x0; // 100000 (0, 1) = 0
SBOX[2][2097152] = 0x4000100; // 200000 (0, 2) = 9
SBOX[2][3145728] = 0x10104; // 300000 (0, 3) = 14
SBOX[2][4194304] = 0x10004; // 400000 (0, 4) = 6
SBOX[2][5242880] = 0x4000004; // 500000 (0, 5) = 3
SBOX[2][6291456] = 0x4010104; // 600000 (0, 6) = 15
SBOX[2][7340032] = 0x4010000; // 700000 (0, 7) = 5
SBOX[2][8388608] = 0x4000000; // 800000 (0, 8) = 1
SBOX[2][9437184] = 0x4010100; // 900000 (0, 9) = 13
SBOX[2][10485760] = 0x10100; // a00000 (0, 10) = 12
SBOX[2][11534336] = 0x4010004; // b00000 (0, 11) = 7
SBOX[2][12582912] = 0x4000104; // c00000 (0, 12) = 11
SBOX[2][13631488] = 0x10000; // d00000 (0, 13) = 4
SBOX[2][14680064] = 0x4; // e00000 (0, 14) = 2
SBOX[2][15728640] = 0x100; // f00000 (0, 15) = 8
SBOX[2][524288] = 0x4010100; // 80000 (1, 0) = 13
SBOX[2][1572864] = 0x4010004; // 180000 (1, 1) = 7
SBOX[2][2621440] = 0x0; // 280000 (1, 2) = 0
SBOX[2][3670016] = 0x4000100; // 380000 (1, 3) = 9
SBOX[2][4718592] = 0x4000004; // 480000 (1, 4) = 3
SBOX[2][5767168] = 0x10000; // 580000 (1, 5) = 4
SBOX[2][6815744] = 0x10004; // 680000 (1, 6) = 6
SBOX[2][7864320] = 0x104; // 780000 (1, 7) = 10
SBOX[2][8912896] = 0x4; // 880000 (1, 8) = 2
SBOX[2][9961472] = 0x100; // 980000 (1, 9) = 8
SBOX[2][11010048] = 0x4010000; // a80000 (1, 10) = 5
SBOX[2][12058624] = 0x10104; // b80000 (1, 11) = 14
SBOX[2][13107200] = 0x10100; // c80000 (1, 12) = 12
SBOX[2][14155776] = 0x4000104; // d80000 (1, 13) = 11
SBOX[2][15204352] = 0x4010104; // e80000 (1, 14) = 15
SBOX[2][16252928] = 0x4000000; // f80000 (1, 15) = 1
SBOX[2][16777216] = 0x4010100; // 1000000 (2, 0) = 13
SBOX[2][17825792] = 0x10004; // 1100000 (2, 1) = 6
SBOX[2][18874368] = 0x10000; // 1200000 (2, 2) = 4
SBOX[2][19922944] = 0x4000100; // 1300000 (2, 3) = 9
SBOX[2][20971520] = 0x100; // 1400000 (2, 4) = 8
SBOX[2][22020096] = 0x4010104; // 1500000 (2, 5) = 15
SBOX[2][23068672] = 0x4000004; // 1600000 (2, 6) = 3
SBOX[2][24117248] = 0x0; // 1700000 (2, 7) = 0
SBOX[2][25165824] = 0x4000104; // 1800000 (2, 8) = 11
SBOX[2][26214400] = 0x4000000; // 1900000 (2, 9) = 1
SBOX[2][27262976] = 0x4; // 1a00000 (2, 10) = 2
SBOX[2][28311552] = 0x10100; // 1b00000 (2, 11) = 12
SBOX[2][29360128] = 0x4010000; // 1c00000 (2, 12) = 5
SBOX[2][30408704] = 0x104; // 1d00000 (2, 13) = 10
SBOX[2][31457280] = 0x10104; // 1e00000 (2, 14) = 14
SBOX[2][32505856] = 0x4010004; // 1f00000 (2, 15) = 7
SBOX[2][17301504] = 0x4000000; // 1080000 (3, 0) = 1
SBOX[2][18350080] = 0x104; // 1180000 (3, 1) = 10
SBOX[2][19398656] = 0x4010100; // 1280000 (3, 2) = 13
SBOX[2][20447232] = 0x0; // 1380000 (3, 3) = 0
SBOX[2][21495808] = 0x10004; // 1480000 (3, 4) = 6
SBOX[2][22544384] = 0x4000100; // 1580000 (3, 5) = 9
SBOX[2][23592960] = 0x100; // 1680000 (3, 6) = 8
SBOX[2][24641536] = 0x4010004; // 1780000 (3, 7) = 7
SBOX[2][25690112] = 0x10000; // 1880000 (3, 8) = 4
SBOX[2][26738688] = 0x4010104; // 1980000 (3, 9) = 15
SBOX[2][27787264] = 0x10104; // 1a80000 (3, 10) = 14
SBOX[2][28835840] = 0x4000004; // 1b80000 (3, 11) = 3
SBOX[2][29884416] = 0x4000104; // 1c80000 (3, 12) = 11
SBOX[2][30932992] = 0x4010000; // 1d80000 (3, 13) = 5
SBOX[2][31981568] = 0x4; // 1e80000 (3, 14) = 2
SBOX[2][33030144] = 0x10100; // 1f80000 (3, 15) = 12
SBOX[3] = new Array();
SBOX[3][0] = 0x80401000; // 0 (0, 0) = 7
SBOX[3][65536] = 0x80001040; // 10000 (0, 1) = 13
SBOX[3][131072] = 0x401040; // 20000 (0, 2) = 14
SBOX[3][196608] = 0x80400000; // 30000 (0, 3) = 3
SBOX[3][262144] = 0x0; // 40000 (0, 4) = 0
SBOX[3][327680] = 0x401000; // 50000 (0, 5) = 6
SBOX[3][393216] = 0x80000040; // 60000 (0, 6) = 9
SBOX[3][458752] = 0x400040; // 70000 (0, 7) = 10
SBOX[3][524288] = 0x80000000; // 80000 (0, 8) = 1
SBOX[3][589824] = 0x400000; // 90000 (0, 9) = 2
SBOX[3][655360] = 0x40; // a0000 (0, 10) = 8
SBOX[3][720896] = 0x80001000; // b0000 (0, 11) = 5
SBOX[3][786432] = 0x80400040; // c0000 (0, 12) = 11
SBOX[3][851968] = 0x1040; // d0000 (0, 13) = 12
SBOX[3][917504] = 0x1000; // e0000 (0, 14) = 4
SBOX[3][983040] = 0x80401040; // f0000 (0, 15) = 15
SBOX[3][32768] = 0x80001040; // 8000 (1, 0) = 13
SBOX[3][98304] = 0x40; // 18000 (1, 1) = 8
SBOX[3][163840] = 0x80400040; // 28000 (1, 2) = 11
SBOX[3][229376] = 0x80001000; // 38000 (1, 3) = 5
SBOX[3][294912] = 0x401000; // 48000 (1, 4) = 6
SBOX[3][360448] = 0x80401040; // 58000 (1, 5) = 15
SBOX[3][425984] = 0x0; // 68000 (1, 6) = 0
SBOX[3][491520] = 0x80400000; // 78000 (1, 7) = 3
SBOX[3][557056] = 0x1000; // 88000 (1, 8) = 4
SBOX[3][622592] = 0x80401000; // 98000 (1, 9) = 7
SBOX[3][688128] = 0x400000; // a8000 (1, 10) = 2
SBOX[3][753664] = 0x1040; // b8000 (1, 11) = 12
SBOX[3][819200] = 0x80000000; // c8000 (1, 12) = 1
SBOX[3][884736] = 0x400040; // d8000 (1, 13) = 10
SBOX[3][950272] = 0x401040; // e8000 (1, 14) = 14
SBOX[3][1015808] = 0x80000040; // f8000 (1, 15) = 9
SBOX[3][1048576] = 0x400040; // 100000 (2, 0) = 10
SBOX[3][1114112] = 0x401000; // 110000 (2, 1) = 6
SBOX[3][1179648] = 0x80000040; // 120000 (2, 2) = 9
SBOX[3][1245184] = 0x0; // 130000 (2, 3) = 0
SBOX[3][1310720] = 0x1040; // 140000 (2, 4) = 12
SBOX[3][1376256] = 0x80400040; // 150000 (2, 5) = 11
SBOX[3][1441792] = 0x80401000; // 160000 (2, 6) = 7
SBOX[3][1507328] = 0x80001040; // 170000 (2, 7) = 13
SBOX[3][1572864] = 0x80401040; // 180000 (2, 8) = 15
SBOX[3][1638400] = 0x80000000; // 190000 (2, 9) = 1
SBOX[3][1703936] = 0x80400000; // 1a0000 (2, 10) = 3
SBOX[3][1769472] = 0x401040; // 1b0000 (2, 11) = 14
SBOX[3][1835008] = 0x80001000; // 1c0000 (2, 12) = 5
SBOX[3][1900544] = 0x400000; // 1d0000 (2, 13) = 2
SBOX[3][1966080] = 0x40; // 1e0000 (2, 14) = 8
SBOX[3][2031616] = 0x1000; // 1f0000 (2, 15) = 4
SBOX[3][1081344] = 0x80400000; // 108000 (3, 0) = 3
SBOX[3][1146880] = 0x80401040; // 118000 (3, 1) = 15
SBOX[3][1212416] = 0x0; // 128000 (3, 2) = 0
SBOX[3][1277952] = 0x401000; // 138000 (3, 3) = 6
SBOX[3][1343488] = 0x400040; // 148000 (3, 4) = 10
SBOX[3][1409024] = 0x80000000; // 158000 (3, 5) = 1
SBOX[3][1474560] = 0x80001040; // 168000 (3, 6) = 13
SBOX[3][1540096] = 0x40; // 178000 (3, 7) = 8
SBOX[3][1605632] = 0x80000040; // 188000 (3, 8) = 9
SBOX[3][1671168] = 0x1000; // 198000 (3, 9) = 4
SBOX[3][1736704] = 0x80001000; // 1a8000 (3, 10) = 5
SBOX[3][1802240] = 0x80400040; // 1b8000 (3, 11) = 11
SBOX[3][1867776] = 0x1040; // 1c8000 (3, 12) = 12
SBOX[3][1933312] = 0x80401000; // 1d8000 (3, 13) = 7
SBOX[3][1998848] = 0x400000; // 1e8000 (3, 14) = 2
SBOX[3][2064384] = 0x401040; // 1f8000 (3, 15) = 14
SBOX[4] = new Array();
SBOX[4][0] = 0x80; // 0 (0, 0) = 2
SBOX[4][4096] = 0x1040000; // 1000 (0, 1) = 12
SBOX[4][8192] = 0x40000; // 2000 (0, 2) = 4
SBOX[4][12288] = 0x20000000; // 3000 (0, 3) = 1
SBOX[4][16384] = 0x20040080; // 4000 (0, 4) = 7
SBOX[4][20480] = 0x1000080; // 5000 (0, 5) = 10
SBOX[4][24576] = 0x21000080; // 6000 (0, 6) = 11
SBOX[4][28672] = 0x40080; // 7000 (0, 7) = 6
SBOX[4][32768] = 0x1000000; // 8000 (0, 8) = 8
SBOX[4][36864] = 0x20040000; // 9000 (0, 9) = 5
SBOX[4][40960] = 0x20000080; // a000 (0, 10) = 3
SBOX[4][45056] = 0x21040080; // b000 (0, 11) = 15
SBOX[4][49152] = 0x21040000; // c000 (0, 12) = 13
SBOX[4][53248] = 0x0; // d000 (0, 13) = 0
SBOX[4][57344] = 0x1040080; // e000 (0, 14) = 14
SBOX[4][61440] = 0x21000000; // f000 (0, 15) = 9
SBOX[4][2048] = 0x1040080; // 800 (1, 0) = 14
SBOX[4][6144] = 0x21000080; // 1800 (1, 1) = 11
SBOX[4][10240] = 0x80; // 2800 (1, 2) = 2
SBOX[4][14336] = 0x1040000; // 3800 (1, 3) = 12
SBOX[4][18432] = 0x40000; // 4800 (1, 4) = 4
SBOX[4][22528] = 0x20040080; // 5800 (1, 5) = 7
SBOX[4][26624] = 0x21040000; // 6800 (1, 6) = 13
SBOX[4][30720] = 0x20000000; // 7800 (1, 7) = 1
SBOX[4][34816] = 0x20040000; // 8800 (1, 8) = 5
SBOX[4][38912] = 0x0; // 9800 (1, 9) = 0
SBOX[4][43008] = 0x21040080; // a800 (1, 10) = 15
SBOX[4][47104] = 0x1000080; // b800 (1, 11) = 10
SBOX[4][51200] = 0x20000080; // c800 (1, 12) = 3
SBOX[4][55296] = 0x21000000; // d800 (1, 13) = 9
SBOX[4][59392] = 0x1000000; // e800 (1, 14) = 8
SBOX[4][63488] = 0x40080; // f800 (1, 15) = 6
SBOX[4][65536] = 0x40000; // 10000 (2, 0) = 4
SBOX[4][69632] = 0x80; // 11000 (2, 1) = 2
SBOX[4][73728] = 0x20000000; // 12000 (2, 2) = 1
SBOX[4][77824] = 0x21000080; // 13000 (2, 3) = 11
SBOX[4][81920] = 0x1000080; // 14000 (2, 4) = 10
SBOX[4][86016] = 0x21040000; // 15000 (2, 5) = 13
SBOX[4][90112] = 0x20040080; // 16000 (2, 6) = 7
SBOX[4][94208] = 0x1000000; // 17000 (2, 7) = 8
SBOX[4][98304] = 0x21040080; // 18000 (2, 8) = 15
SBOX[4][102400] = 0x21000000; // 19000 (2, 9) = 9
SBOX[4][106496] = 0x1040000; // 1a000 (2, 10) = 12
SBOX[4][110592] = 0x20040000; // 1b000 (2, 11) = 5
SBOX[4][114688] = 0x40080; // 1c000 (2, 12) = 6
SBOX[4][118784] = 0x20000080; // 1d000 (2, 13) = 3
SBOX[4][122880] = 0x0; // 1e000 (2, 14) = 0
SBOX[4][126976] = 0x1040080; // 1f000 (2, 15) = 14
SBOX[4][67584] = 0x21000080; // 10800 (3, 0) = 11
SBOX[4][71680] = 0x1000000; // 11800 (3, 1) = 8
SBOX[4][75776] = 0x1040000; // 12800 (3, 2) = 12
SBOX[4][79872] = 0x20040080; // 13800 (3, 3) = 7
SBOX[4][83968] = 0x20000000; // 14800 (3, 4) = 1
SBOX[4][88064] = 0x1040080; // 15800 (3, 5) = 14
SBOX[4][92160] = 0x80; // 16800 (3, 6) = 2
SBOX[4][96256] = 0x21040000; // 17800 (3, 7) = 13
SBOX[4][100352] = 0x40080; // 18800 (3, 8) = 6
SBOX[4][104448] = 0x21040080; // 19800 (3, 9) = 15
SBOX[4][108544] = 0x0; // 1a800 (3, 10) = 0
SBOX[4][112640] = 0x21000000; // 1b800 (3, 11) = 9
SBOX[4][116736] = 0x1000080; // 1c800 (3, 12) = 10
SBOX[4][120832] = 0x40000; // 1d800 (3, 13) = 4
SBOX[4][124928] = 0x20040000; // 1e800 (3, 14) = 5
SBOX[4][129024] = 0x20000080; // 1f800 (3, 15) = 3
SBOX[5] = new Array();
SBOX[5][0] = 0x10000008; // 0 (0, 0) = 12
SBOX[5][256] = 0x2000; // 100 (0, 1) = 1
SBOX[5][512] = 0x10200000; // 200 (0, 2) = 10
SBOX[5][768] = 0x10202008; // 300 (0, 3) = 15
SBOX[5][1024] = 0x10002000; // 400 (0, 4) = 9
SBOX[5][1280] = 0x200000; // 500 (0, 5) = 2
SBOX[5][1536] = 0x200008; // 600 (0, 6) = 6
SBOX[5][1792] = 0x10000000; // 700 (0, 7) = 8
SBOX[5][2048] = 0x0; // 800 (0, 8) = 0
SBOX[5][2304] = 0x10002008; // 900 (0, 9) = 13
SBOX[5][2560] = 0x202000; // a00 (0, 10) = 3
SBOX[5][2816] = 0x8; // b00 (0, 11) = 4
SBOX[5][3072] = 0x10200008; // c00 (0, 12) = 14
SBOX[5][3328] = 0x202008; // d00 (0, 13) = 7
SBOX[5][3584] = 0x2008; // e00 (0, 14) = 5
SBOX[5][3840] = 0x10202000; // f00 (0, 15) = 11
SBOX[5][128] = 0x10200000; // 80 (1, 0) = 10
SBOX[5][384] = 0x10202008; // 180 (1, 1) = 15
SBOX[5][640] = 0x8; // 280 (1, 2) = 4
SBOX[5][896] = 0x200000; // 380 (1, 3) = 2
SBOX[5][1152] = 0x202008; // 480 (1, 4) = 7
SBOX[5][1408] = 0x10000008; // 580 (1, 5) = 12
SBOX[5][1664] = 0x10002000; // 680 (1, 6) = 9
SBOX[5][1920] = 0x2008; // 780 (1, 7) = 5
SBOX[5][2176] = 0x200008; // 880 (1, 8) = 6
SBOX[5][2432] = 0x2000; // 980 (1, 9) = 1
SBOX[5][2688] = 0x10002008; // a80 (1, 10) = 13
SBOX[5][2944] = 0x10200008; // b80 (1, 11) = 14
SBOX[5][3200] = 0x0; // c80 (1, 12) = 0
SBOX[5][3456] = 0x10202000; // d80 (1, 13) = 11
SBOX[5][3712] = 0x202000; // e80 (1, 14) = 3
SBOX[5][3968] = 0x10000000; // f80 (1, 15) = 8
SBOX[5][4096] = 0x10002000; // 1000 (2, 0) = 9
SBOX[5][4352] = 0x10200008; // 1100 (2, 1) = 14
SBOX[5][4608] = 0x10202008; // 1200 (2, 2) = 15
SBOX[5][4864] = 0x2008; // 1300 (2, 3) = 5
SBOX[5][5120] = 0x200000; // 1400 (2, 4) = 2
SBOX[5][5376] = 0x10000000; // 1500 (2, 5) = 8
SBOX[5][5632] = 0x10000008; // 1600 (2, 6) = 12
SBOX[5][5888] = 0x202000; // 1700 (2, 7) = 3
SBOX[5][6144] = 0x202008; // 1800 (2, 8) = 7
SBOX[5][6400] = 0x0; // 1900 (2, 9) = 0
SBOX[5][6656] = 0x8; // 1a00 (2, 10) = 4
SBOX[5][6912] = 0x10200000; // 1b00 (2, 11) = 10
SBOX[5][7168] = 0x2000; // 1c00 (2, 12) = 1
SBOX[5][7424] = 0x10002008; // 1d00 (2, 13) = 13
SBOX[5][7680] = 0x10202000; // 1e00 (2, 14) = 11
SBOX[5][7936] = 0x200008; // 1f00 (2, 15) = 6
SBOX[5][4224] = 0x8; // 1080 (3, 0) = 4
SBOX[5][4480] = 0x202000; // 1180 (3, 1) = 3
SBOX[5][4736] = 0x200000; // 1280 (3, 2) = 2
SBOX[5][4992] = 0x10000008; // 1380 (3, 3) = 12
SBOX[5][5248] = 0x10002000; // 1480 (3, 4) = 9
SBOX[5][5504] = 0x2008; // 1580 (3, 5) = 5
SBOX[5][5760] = 0x10202008; // 1680 (3, 6) = 15
SBOX[5][6016] = 0x10200000; // 1780 (3, 7) = 10
SBOX[5][6272] = 0x10202000; // 1880 (3, 8) = 11
SBOX[5][6528] = 0x10200008; // 1980 (3, 9) = 14
SBOX[5][6784] = 0x2000; // 1a80 (3, 10) = 1
SBOX[5][7040] = 0x202008; // 1b80 (3, 11) = 7
SBOX[5][7296] = 0x200008; // 1c80 (3, 12) = 6
SBOX[5][7552] = 0x0; // 1d80 (3, 13) = 0
SBOX[5][7808] = 0x10000000; // 1e80 (3, 14) = 8
SBOX[5][8064] = 0x10002008; // 1f80 (3, 15) = 13
SBOX[6] = new Array();
SBOX[6][0] = 0x100000; // 0 (0, 0) = 4
SBOX[6][16] = 0x2000401; // 10 (0, 1) = 11
SBOX[6][32] = 0x400; // 20 (0, 2) = 2
SBOX[6][48] = 0x100401; // 30 (0, 3) = 14
SBOX[6][64] = 0x2100401; // 40 (0, 4) = 15
SBOX[6][80] = 0x0; // 50 (0, 5) = 0
SBOX[6][96] = 0x1; // 60 (0, 6) = 8
SBOX[6][112] = 0x2100001; // 70 (0, 7) = 13
SBOX[6][128] = 0x2000400; // 80 (0, 8) = 3
SBOX[6][144] = 0x100001; // 90 (0, 9) = 12
SBOX[6][160] = 0x2000001; // a0 (0, 10) = 9
SBOX[6][176] = 0x2100400; // b0 (0, 11) = 7
SBOX[6][192] = 0x2100000; // c0 (0, 12) = 5
SBOX[6][208] = 0x401; // d0 (0, 13) = 10
SBOX[6][224] = 0x100400; // e0 (0, 14) = 6
SBOX[6][240] = 0x2000000; // f0 (0, 15) = 1
SBOX[6][8] = 0x2100001; // 8 (1, 0) = 13
SBOX[6][24] = 0x0; // 18 (1, 1) = 0
SBOX[6][40] = 0x2000401; // 28 (1, 2) = 11
SBOX[6][56] = 0x2100400; // 38 (1, 3) = 7
SBOX[6][72] = 0x100000; // 48 (1, 4) = 4
SBOX[6][88] = 0x2000001; // 58 (1, 5) = 9
SBOX[6][104] = 0x2000000; // 68 (1, 6) = 1
SBOX[6][120] = 0x401; // 78 (1, 7) = 10
SBOX[6][136] = 0x100401; // 88 (1, 8) = 14
SBOX[6][152] = 0x2000400; // 98 (1, 9) = 3
SBOX[6][168] = 0x2100000; // a8 (1, 10) = 5
SBOX[6][184] = 0x100001; // b8 (1, 11) = 12
SBOX[6][200] = 0x400; // c8 (1, 12) = 2
SBOX[6][216] = 0x2100401; // d8 (1, 13) = 15
SBOX[6][232] = 0x1; // e8 (1, 14) = 8
SBOX[6][248] = 0x100400; // f8 (1, 15) = 6
SBOX[6][256] = 0x2000000; // 100 (2, 0) = 1
SBOX[6][272] = 0x100000; // 110 (2, 1) = 4
SBOX[6][288] = 0x2000401; // 120 (2, 2) = 11
SBOX[6][304] = 0x2100001; // 130 (2, 3) = 13
SBOX[6][320] = 0x100001; // 140 (2, 4) = 12
SBOX[6][336] = 0x2000400; // 150 (2, 5) = 3
SBOX[6][352] = 0x2100400; // 160 (2, 6) = 7
SBOX[6][368] = 0x100401; // 170 (2, 7) = 14
SBOX[6][384] = 0x401; // 180 (2, 8) = 10
SBOX[6][400] = 0x2100401; // 190 (2, 9) = 15
SBOX[6][416] = 0x100400; // 1a0 (2, 10) = 6
SBOX[6][432] = 0x1; // 1b0 (2, 11) = 8
SBOX[6][448] = 0x0; // 1c0 (2, 12) = 0
SBOX[6][464] = 0x2100000; // 1d0 (2, 13) = 5
SBOX[6][480] = 0x2000001; // 1e0 (2, 14) = 9
SBOX[6][496] = 0x400; // 1f0 (2, 15) = 2
SBOX[6][264] = 0x100400; // 108 (3, 0) = 6
SBOX[6][280] = 0x2000401; // 118 (3, 1) = 11
SBOX[6][296] = 0x2100001; // 128 (3, 2) = 13
SBOX[6][312] = 0x1; // 138 (3, 3) = 8
SBOX[6][328] = 0x2000000; // 148 (3, 4) = 1
SBOX[6][344] = 0x100000; // 158 (3, 5) = 4
SBOX[6][360] = 0x401; // 168 (3, 6) = 10
SBOX[6][376] = 0x2100400; // 178 (3, 7) = 7
SBOX[6][392] = 0x2000001; // 188 (3, 8) = 9
SBOX[6][408] = 0x2100000; // 198 (3, 9) = 5
SBOX[6][424] = 0x0; // 1a8 (3, 10) = 0
SBOX[6][440] = 0x2100401; // 1b8 (3, 11) = 15
SBOX[6][456] = 0x100401; // 1c8 (3, 12) = 14
SBOX[6][472] = 0x400; // 1d8 (3, 13) = 2
SBOX[6][488] = 0x2000400; // 1e8 (3, 14) = 3
SBOX[6][504] = 0x100001; // 1f8 (3, 15) = 12
SBOX[7] = new Array();
SBOX[7][0] = 0x8000820; // 0 (0, 0) = 13
SBOX[7][1] = 0x20000; // 1 (0, 1) = 2
SBOX[7][2] = 0x8000000; // 2 (0, 2) = 8
SBOX[7][3] = 0x20; // 3 (0, 3) = 4
SBOX[7][4] = 0x20020; // 4 (0, 4) = 6
SBOX[7][5] = 0x8020820; // 5 (0, 5) = 15
SBOX[7][6] = 0x8020800; // 6 (0, 6) = 11
SBOX[7][7] = 0x800; // 7 (0, 7) = 1
SBOX[7][8] = 0x8020000; // 8 (0, 8) = 10
SBOX[7][9] = 0x8000800; // 9 (0, 9) = 9
SBOX[7][10] = 0x20800; // a (0, 10) = 3
SBOX[7][11] = 0x8020020; // b (0, 11) = 14
SBOX[7][12] = 0x820; // c (0, 12) = 5
SBOX[7][13] = 0x0; // d (0, 13) = 0
SBOX[7][14] = 0x8000020; // e (0, 14) = 12
SBOX[7][15] = 0x20820; // f (0, 15) = 7
SBOX[7][-2147483648] = 0x800; // 80000000 (1, 0) = 1
SBOX[7][-2147483647] = 0x8020820; // 80000001 (1, 1) = 15
SBOX[7][-2147483646] = 0x8000820; // 80000002 (1, 2) = 13
SBOX[7][-2147483645] = 0x8000000; // 80000003 (1, 3) = 8
SBOX[7][-2147483644] = 0x8020000; // 80000004 (1, 4) = 10
SBOX[7][-2147483643] = 0x20800; // 80000005 (1, 5) = 3
SBOX[7][-2147483642] = 0x20820; // 80000006 (1, 6) = 7
SBOX[7][-2147483641] = 0x20; // 80000007 (1, 7) = 4
SBOX[7][-2147483640] = 0x8000020; // 80000008 (1, 8) = 12
SBOX[7][-2147483639] = 0x820; // 80000009 (1, 9) = 5
SBOX[7][-2147483638] = 0x20020; // 8000000a (1, 10) = 6
SBOX[7][-2147483637] = 0x8020800; // 8000000b (1, 11) = 11
SBOX[7][-2147483636] = 0x0; // 8000000c (1, 12) = 0
SBOX[7][-2147483635] = 0x8020020; // 8000000d (1, 13) = 14
SBOX[7][-2147483634] = 0x8000800; // 8000000e (1, 14) = 9
SBOX[7][-2147483633] = 0x20000; // 8000000f (1, 15) = 2
SBOX[7][16] = 0x20820; // 10 (2, 0) = 7
SBOX[7][17] = 0x8020800; // 11 (2, 1) = 11
SBOX[7][18] = 0x20; // 12 (2, 2) = 4
SBOX[7][19] = 0x800; // 13 (2, 3) = 1
SBOX[7][20] = 0x8000800; // 14 (2, 4) = 9
SBOX[7][21] = 0x8000020; // 15 (2, 5) = 12
SBOX[7][22] = 0x8020020; // 16 (2, 6) = 14
SBOX[7][23] = 0x20000; // 17 (2, 7) = 2
SBOX[7][24] = 0x0; // 18 (2, 8) = 0
SBOX[7][25] = 0x20020; // 19 (2, 9) = 6
SBOX[7][26] = 0x8020000; // 1a (2, 10) = 10
SBOX[7][27] = 0x8000820; // 1b (2, 11) = 13
SBOX[7][28] = 0x8020820; // 1c (2, 12) = 15
SBOX[7][29] = 0x20800; // 1d (2, 13) = 3
SBOX[7][30] = 0x820; // 1e (2, 14) = 5
SBOX[7][31] = 0x8000000; // 1f (2, 15) = 8
SBOX[7][-2147483632] = 0x20000; // 80000010 (3, 0) = 2
SBOX[7][-2147483631] = 0x800; // 80000011 (3, 1) = 1
SBOX[7][-2147483630] = 0x8020020; // 80000012 (3, 2) = 14
SBOX[7][-2147483629] = 0x20820; // 80000013 (3, 3) = 7
SBOX[7][-2147483628] = 0x20; // 80000014 (3, 4) = 4
SBOX[7][-2147483627] = 0x8020000; // 80000015 (3, 5) = 10
SBOX[7][-2147483626] = 0x8000000; // 80000016 (3, 6) = 8
SBOX[7][-2147483625] = 0x8000820; // 80000017 (3, 7) = 13
SBOX[7][-2147483624] = 0x8020820; // 80000018 (3, 8) = 15
SBOX[7][-2147483623] = 0x8000020; // 80000019 (3, 9) = 12
SBOX[7][-2147483622] = 0x8000800; // 8000001a (3, 10) = 9
SBOX[7][-2147483621] = 0x0; // 8000001b (3, 11) = 0
SBOX[7][-2147483620] = 0x20800; // 8000001c (3, 12) = 3
SBOX[7][-2147483619] = 0x820; // 8000001d (3, 13) = 5
SBOX[7][-2147483618] = 0x20020; // 8000001e (3, 14) = 6
SBOX[7][-2147483617] = 0x8020800; // 8000001f (3, 15) = 11
State.prototype._exchangeLR = function(v, m) {
var t = ((this.lhs >> v) ^ this.rhs) & m;
this.rhs ^= t;
this.lhs ^= (t << v);
};
State.prototype._exchangeRL = function(v, m) {
var t = ((this.rhs >> v) ^ this.lhs) & m;
this.lhs ^= t;
this.rhs ^= (t << v);
};
/**
* Perform the initial permutation of the input to create the starting state
* of the algorithm. The initial permutation maps each consecutive bit of
* the input into a different byte of the state.
*
* <pre>
* The initial permutation is defined to be:
*
* 58 50 42 34 26 18 10 2
* 60 52 44 36 28 20 12 4
* 62 54 46 38 30 22 14 6
* 64 56 48 40 32 24 16 8
* 57 49 41 33 25 17 9 1
* 59 51 43 35 27 19 11 3
* 61 53 45 37 29 21 13 5
* 63 55 47 39 31 23 15 7
* </pre>
*
*
* @param message
* The message as an array of unsigned bytes.
* @param offset
* The offset into the message that the current 64-bit block
* begins.
* @returns the initial engine state
*/
State.prototype.initialPerm = function(message, offset) {
var input = message.slice(offset, offset + 8);
this.lhs = (input[0] << 24) + (input[1] << 16) + (input[2] << 8)
+ input[3];
this.rhs = (input[4] << 24) + (input[5] << 16) + (input[6] << 8)
+ input[7];
this._exchangeLR(4, 0x0f0f0f0f);
this._exchangeLR(16, 0x0000ffff);
this._exchangeRL(2, 0x33333333);
this._exchangeRL(8, 0x00ff00ff);
this._exchangeLR(1, 0x55555555);
};
/**
* Perform one round of the DES algorithm using the given key. A round is
* defined as:
*
* <pre>
* L&amp;rsquo = R
* R&amp;rsquo = L &circ; f(R, k)
* </pre>
*
* where f consists of expanding, XORing with the key and contracting back
* with the SBOXes.
*
* Note that the final round is defined slightly differently as:
*
* <pre>
* L&amp;rsquo = L &circ; f(R, k)
* R&amp;rsquo = R
* </pre>
*
* Therefore in the final round this function produces LHS and RHS the wrong
* way around.
*
* @param k
* the key
*/
State.prototype.round = function(k) {
var r = this.rhs, l = this.lhs;
var f = 0;
for ( var i = 0; i < 8; i++) {
var v = (r ^ k[i]) & State.SBOX_MASK[i];
f += State.SBOX[i][v];
}
this.lhs = r;
this.rhs = l ^ f;
};
/**
* Apply the inverse of the initial permutation.
*
* <pre>
* The inverse is defined to be:
*
* 40 8 48 16 56 24 64 32
* 39 7 47 15 55 23 63 31
* 38 6 46 14 54 22 62 30
* 37 5 45 13 53 21 61 29
* 36 4 44 12 52 20 60 28
* 35 3 43 11 51 19 59 27
* 34 2 42 10 50 18 58 26
* 33 1 41 9 49 17 57 25
* </pre>
*
* @param cipherText
* @param offset
*/
State.prototype.finalPerm = function(cipherText, offset) {
var t = this.lhs;
this.lhs = this.rhs;
this.rhs = t;
this._exchangeLR(1, 0x55555555);
this._exchangeRL(8, 0x00ff00ff);
this._exchangeRL(2, 0x33333333);
this._exchangeLR(16, 0x0000ffff);
this._exchangeLR(4, 0x0f0f0f0f);
cipherText[offset] = (this.lhs >> 24) & 0xff;
cipherText[offset + 1] = (this.lhs >> 16) & 0xff;
cipherText[offset + 2] = (this.lhs >> 8) & 0xff;
cipherText[offset + 3] = (this.lhs) & 0xff;
cipherText[offset + 4] = (this.rhs >> 24) & 0xff;
cipherText[offset + 5] = (this.rhs >> 16) & 0xff;
cipherText[offset + 6] = (this.rhs >> 8) & 0xff;
cipherText[offset + 7] = (this.rhs) & 0xff;
};
/**
* DES cipher
*/
var DES = C.DES = {
_blocksize : 2,
_keyschedule : null,
_state : new State(),
_init : function(k) {
this._keyschedule = new KeySchedule(k);
},
encrypt : function(message, password, options) {
options = options || {};
// Determine mode
var mode = options.mode || new C.mode.OFB;
// Allow mode to override options
if (mode.fixOptions)
mode.fixOptions(options);
var
// Convert to bytes if message is a string
m = (message.constructor == String ? UTF8.stringToBytes(message)
: message),
// Generate random IV
iv = options.iv || util.randomBytes(8),
// Generate key
k = (password.constructor == String ?
// Derive key from passphrase
C.PBKDF2(password, iv, 8, {
asBytes : true
}) :
// else, assume byte array representing cryptographic key
password);
// Create key schedule
this._keyschedule = new KeySchedule(k);
// Encrypt
mode.encrypt(DES, m, iv);
// Return ciphertext
m = options.iv ? m : iv.concat(m);
return (options && options.asBytes) ? m : util.bytesToBase64(m);
},
_encryptblock : function(message, offset) {
this._state.initialPerm(message, offset);
for ( var i = 0; i <= 15; i++) {
this._state.round(this._keyschedule.getKey(i));
}
this._state.finalPerm(message, offset);
},
decrypt : function(ciphertext, password, options) {
options = options || {};
// Determine mode
var mode = options.mode || new C.mode.OFB;
// Allow mode to override options
if (mode.fixOptions)
mode.fixOptions(options);
var
// Convert to bytes if ciphertext is a string
c = (ciphertext.constructor == String ? util
.base64ToBytes(ciphertext) : ciphertext),
// Separate IV and message
iv = options.iv || c.splice(0, 8),
// Generate key
k = (password.constructor == String ?
// Derive key from passphrase
C.PBKDF2(password, iv, 32, {
asBytes : true
}) :
// else, assume byte array representing cryptographic key
password);
// Create key schedule
this._keyschedule = new KeySchedule(k);
mode.decrypt(DES, c, iv);
// Return plaintext
return (options && options.asBytes) ? c : UTF8.bytesToString(c);
},
_decryptblock : function(message, offset) {
this._state.initialPerm(message, offset);
for ( var i = 15; i >= 0; i--) {
this._state.round(this._keyschedule.getKey(i));
}
this._state.finalPerm(message, offset);
}
};
})();
(function(){
var C = (typeof window === 'undefined') ? require('./Crypto').Crypto : window.Crypto;
// Shortcuts
var util = C.util,
charenc = C.charenc,
UTF8 = charenc.UTF8,
Binary = charenc.Binary;
C.HMAC = function (hasher, message, key, options) {
// Convert to byte arrays
if (message.constructor == String) message = UTF8.stringToBytes(message);
if (key.constructor == String) key = UTF8.stringToBytes(key);
/* else, assume byte arrays already */
// Allow arbitrary length keys
if (key.length > hasher._blocksize * 4)
key = hasher(key, { asBytes: true });
// XOR keys with pad constants
var okey = key.slice(0),
ikey = key.slice(0);
for (var i = 0; i < hasher._blocksize * 4; i++) {
okey[i] ^= 0x5C;
ikey[i] ^= 0x36;
}
var hmacbytes = hasher(okey.concat(hasher(ikey.concat(message), { asBytes: true })), { asBytes: true });
return options && options.asBytes ? hmacbytes :
options && options.asString ? Binary.bytesToString(hmacbytes) :
util.bytesToHex(hmacbytes);
};
})();
(function(){
var C = (typeof window === 'undefined') ? require('./Crypto').Crypto : window.Crypto;
// Shortcuts
var util = C.util,
charenc = C.charenc,
UTF8 = charenc.UTF8,
Binary = charenc.Binary;
var MARC4 = C.MARC4 = {
/**
* Public API
*/
encrypt: function (message, password) {
var
// Convert to bytes
m = UTF8.stringToBytes(message),
// Generate random IV
iv = util.randomBytes(16),
// Generate key
k = password.constructor == String ?
// Derive key from passphrase
C.PBKDF2(password, iv, 32, { asBytes: true }) :
// else, assume byte array representing cryptographic key
password;
// Encrypt
MARC4._marc4(m, k, 1536);
// Return ciphertext
return util.bytesToBase64(iv.concat(m));
},
decrypt: function (ciphertext, password) {
var
// Convert to bytes
c = util.base64ToBytes(ciphertext),
// Separate IV and message
iv = c.splice(0, 16),
// Generate key
k = password.constructor == String ?
// Derive key from passphrase
C.PBKDF2(password, iv, 32, { asBytes: true }) :
// else, assume byte array representing cryptographic key
password;
// Decrypt
MARC4._marc4(c, k, 1536);
// Return plaintext
return UTF8.bytesToString(c);
},
/**
* Internal methods
*/
// The core
_marc4: function (m, k, drop) {
// State variables
var i, j, s, temp;
// Key setup
for (i = 0, s = []; i < 256; i++) s[i] = i;
for (i = 0, j = 0; i < 256; i++) {
j = (j + s[i] + k[i % k.length]) % 256;
// Swap
temp = s[i];
s[i] = s[j];
s[j] = temp;
}
// Clear counters
i = j = 0;
// Encryption
for (var k = -drop; k < m.length; k++) {
i = (i + 1) % 256;
j = (j + s[i]) % 256;
// Swap
temp = s[i];
s[i] = s[j];
s[j] = temp;
// Stop here if we're still dropping keystream
if (k < 0) continue;
// Encrypt
m[k] ^= s[(s[i] + s[j]) % 256];
}
}
};
})();
(function(){
var C = (typeof window === 'undefined') ? require('./Crypto').Crypto : window.Crypto;
// Shortcuts
var util = C.util,
charenc = C.charenc,
UTF8 = charenc.UTF8,
Binary = charenc.Binary;
// Public API
var MD5 = C.MD5 = function (message, options) {
var digestbytes = util.wordsToBytes(MD5._md5(message));
return options && options.asBytes ? digestbytes :
options && options.asString ? Binary.bytesToString(digestbytes) :
util.bytesToHex(digestbytes);
};
// The core
MD5._md5 = function (message) {
// Convert to byte array
if (message.constructor == String) message = UTF8.stringToBytes(message);
/* else, assume byte array already */
var m = util.bytesToWords(message),
l = message.length * 8,
a = 1732584193,
b = -271733879,
c = -1732584194,
d = 271733878;
// Swap endian
for (var i = 0; i < m.length; i++) {
m[i] = ((m[i] << 8) | (m[i] >>> 24)) & 0x00FF00FF |
((m[i] << 24) | (m[i] >>> 8)) & 0xFF00FF00;
}
// Padding
m[l >>> 5] |= 0x80 << (l % 32);
m[(((l + 64) >>> 9) << 4) + 14] = l;
// Method shortcuts
var FF = MD5._ff,
GG = MD5._gg,
HH = MD5._hh,
II = MD5._ii;
for (var i = 0; i < m.length; i += 16) {
var aa = a,
bb = b,
cc = c,
dd = d;
a = FF(a, b, c, d, m[i+ 0], 7, -680876936);
d = FF(d, a, b, c, m[i+ 1], 12, -389564586);
c = FF(c, d, a, b, m[i+ 2], 17, 606105819);
b = FF(b, c, d, a, m[i+ 3], 22, -1044525330);
a = FF(a, b, c, d, m[i+ 4], 7, -176418897);
d = FF(d, a, b, c, m[i+ 5], 12, 1200080426);
c = FF(c, d, a, b, m[i+ 6], 17, -1473231341);
b = FF(b, c, d, a, m[i+ 7], 22, -45705983);
a = FF(a, b, c, d, m[i+ 8], 7, 1770035416);
d = FF(d, a, b, c, m[i+ 9], 12, -1958414417);
c = FF(c, d, a, b, m[i+10], 17, -42063);
b = FF(b, c, d, a, m[i+11], 22, -1990404162);
a = FF(a, b, c, d, m[i+12], 7, 1804603682);
d = FF(d, a, b, c, m[i+13], 12, -40341101);
c = FF(c, d, a, b, m[i+14], 17, -1502002290);
b = FF(b, c, d, a, m[i+15], 22, 1236535329);
a = GG(a, b, c, d, m[i+ 1], 5, -165796510);
d = GG(d, a, b, c, m[i+ 6], 9, -1069501632);
c = GG(c, d, a, b, m[i+11], 14, 643717713);
b = GG(b, c, d, a, m[i+ 0], 20, -373897302);
a = GG(a, b, c, d, m[i+ 5], 5, -701558691);
d = GG(d, a, b, c, m[i+10], 9, 38016083);
c = GG(c, d, a, b, m[i+15], 14, -660478335);
b = GG(b, c, d, a, m[i+ 4], 20, -405537848);
a = GG(a, b, c, d, m[i+ 9], 5, 568446438);
d = GG(d, a, b, c, m[i+14], 9, -1019803690);
c = GG(c, d, a, b, m[i+ 3], 14, -187363961);
b = GG(b, c, d, a, m[i+ 8], 20, 1163531501);
a = GG(a, b, c, d, m[i+13], 5, -1444681467);
d = GG(d, a, b, c, m[i+ 2], 9, -51403784);
c = GG(c, d, a, b, m[i+ 7], 14, 1735328473);
b = GG(b, c, d, a, m[i+12], 20, -1926607734);
a = HH(a, b, c, d, m[i+ 5], 4, -378558);
d = HH(d, a, b, c, m[i+ 8], 11, -2022574463);
c = HH(c, d, a, b, m[i+11], 16, 1839030562);
b = HH(b, c, d, a, m[i+14], 23, -35309556);
a = HH(a, b, c, d, m[i+ 1], 4, -1530992060);
d = HH(d, a, b, c, m[i+ 4], 11, 1272893353);
c = HH(c, d, a, b, m[i+ 7], 16, -155497632);
b = HH(b, c, d, a, m[i+10], 23, -1094730640);
a = HH(a, b, c, d, m[i+13], 4, 681279174);
d = HH(d, a, b, c, m[i+ 0], 11, -358537222);
c = HH(c, d, a, b, m[i+ 3], 16, -722521979);
b = HH(b, c, d, a, m[i+ 6], 23, 76029189);
a = HH(a, b, c, d, m[i+ 9], 4, -640364487);
d = HH(d, a, b, c, m[i+12], 11, -421815835);
c = HH(c, d, a, b, m[i+15], 16, 530742520);
b = HH(b, c, d, a, m[i+ 2], 23, -995338651);
a = II(a, b, c, d, m[i+ 0], 6, -198630844);
d = II(d, a, b, c, m[i+ 7], 10, 1126891415);
c = II(c, d, a, b, m[i+14], 15, -1416354905);
b = II(b, c, d, a, m[i+ 5], 21, -57434055);
a = II(a, b, c, d, m[i+12], 6, 1700485571);
d = II(d, a, b, c, m[i+ 3], 10, -1894986606);
c = II(c, d, a, b, m[i+10], 15, -1051523);
b = II(b, c, d, a, m[i+ 1], 21, -2054922799);
a = II(a, b, c, d, m[i+ 8], 6, 1873313359);
d = II(d, a, b, c, m[i+15], 10, -30611744);
c = II(c, d, a, b, m[i+ 6], 15, -1560198380);
b = II(b, c, d, a, m[i+13], 21, 1309151649);
a = II(a, b, c, d, m[i+ 4], 6, -145523070);
d = II(d, a, b, c, m[i+11], 10, -1120210379);
c = II(c, d, a, b, m[i+ 2], 15, 718787259);
b = II(b, c, d, a, m[i+ 9], 21, -343485551);
a = (a + aa) >>> 0;
b = (b + bb) >>> 0;
c = (c + cc) >>> 0;
d = (d + dd) >>> 0;
}
return util.endian([a, b, c, d]);
};
// Auxiliary functions
MD5._ff = function (a, b, c, d, x, s, t) {
var n = a + (b & c | ~b & d) + (x >>> 0) + t;
return ((n << s) | (n >>> (32 - s))) + b;
};
MD5._gg = function (a, b, c, d, x, s, t) {
var n = a + (b & d | c & ~d) + (x >>> 0) + t;
return ((n << s) | (n >>> (32 - s))) + b;
};
MD5._hh = function (a, b, c, d, x, s, t) {
var n = a + (b ^ c ^ d) + (x >>> 0) + t;
return ((n << s) | (n >>> (32 - s))) + b;
};
MD5._ii = function (a, b, c, d, x, s, t) {
var n = a + (c ^ (b | ~d)) + (x >>> 0) + t;
return ((n << s) | (n >>> (32 - s))) + b;
};
// Package private blocksize
MD5._blocksize = 16;
MD5._digestsize = 16;
})();
(function(){
var C = (typeof window === 'undefined') ? require('./Crypto').Crypto : window.Crypto;
// Shortcuts
var util = C.util,
charenc = C.charenc,
UTF8 = charenc.UTF8,
Binary = charenc.Binary;
C.PBKDF2 = function (password, salt, keylen, options) {
// Convert to byte arrays
if (password.constructor == String) password = UTF8.stringToBytes(password);
if (salt.constructor == String) salt = UTF8.stringToBytes(salt);
/* else, assume byte arrays already */
// Defaults
var hasher = options && options.hasher || C.SHA1,
iterations = options && options.iterations || 1;
// Pseudo-random function
function PRF(password, salt) {
return C.HMAC(hasher, salt, password, { asBytes: true });
}
// Generate key
var derivedKeyBytes = [],
blockindex = 1;
while (derivedKeyBytes.length < keylen) {
var block = PRF(password, salt.concat(util.wordsToBytes([blockindex])));
for (var u = block, i = 1; i < iterations; i++) {
u = PRF(password, u);
for (var j = 0; j < block.length; j++) block[j] ^= u[j];
}
derivedKeyBytes = derivedKeyBytes.concat(block);
blockindex++;
}
// Truncate excess bytes
derivedKeyBytes.length = keylen;
return options && options.asBytes ? derivedKeyBytes :
options && options.asString ? Binary.bytesToString(derivedKeyBytes) :
util.bytesToHex(derivedKeyBytes);
};
})();
(function(){
var C = (typeof window === 'undefined') ? require('./Crypto').Crypto : window.Crypto;
// Shortcuts
var util = C.util,
charenc = C.charenc,
UTF8 = charenc.UTF8,
Binary = charenc.Binary;
if (!C.nextTick) {
// node.js has setTime out but prefer process.nextTick
if (typeof process != 'undefined' && typeof process.nextTick !== 'undefined') {
C.nextTick = process.nextTick;
} else if (typeof setTimeout !== 'undefined') {
C.nextTick = function (callback) {
setTimeout(callback, 0);
};
}
}
C.PBKDF2Async = function (password, salt, keylen, callback, options) {
// Convert to byte arrays
if (password.constructor == String) password = UTF8.stringToBytes(password);
if (salt.constructor == String) salt = UTF8.stringToBytes(salt);
/* else, assume byte arrays already */
// Defaults
var hasher = options && options.hasher || C.SHA1,
iterations = options && options.iterations || 1;
// Progress callback option
var progressChangeHandler = options && options.onProgressChange;
var totalIterations = Math.ceil(keylen / hasher._digestsize) * iterations;
function fireProgressChange(currentIteration) {
if (progressChangeHandler) {
var iterationsSoFar = derivedKeyBytes.length / hasher._digestsize * iterations + currentIteration;
setTimeout(function () {
progressChangeHandler(Math.round(iterationsSoFar / totalIterations * 100));
}, 0);
}
}
// Pseudo-random function
function PRF(password, salt) {
return C.HMAC(hasher, salt, password, { asBytes: true });
}
var nextTick = C.nextTick;
// Generate key
var derivedKeyBytes = [],
blockindex = 1;
var outer, inner;
nextTick(outer = function () {
if (derivedKeyBytes.length < keylen) {
var block = PRF(password, salt.concat(util.wordsToBytes([blockindex])));
fireProgressChange(1);
var u = block, i = 1;
nextTick(inner = function () {
if (i < iterations) {
u = PRF(password, u);
for (var j = 0; j < block.length; j++) block[j] ^= u[j];
i++;
fireProgressChange(i);
nextTick(inner);
} else {
derivedKeyBytes = derivedKeyBytes.concat(block);
blockindex++;
nextTick(outer);
}
});
} else {
// Truncate excess bytes
derivedKeyBytes.length = keylen;
callback(
options && options.asBytes ? derivedKeyBytes :
options && options.asString ? Binary.bytesToString(derivedKeyBytes) :
util.bytesToHex(derivedKeyBytes));
}
});
};
})();
(function(){
var C = (typeof window === 'undefined') ? require('./Crypto').Crypto : window.Crypto;
// Shortcuts
var util = C.util,
charenc = C.charenc,
UTF8 = charenc.UTF8,
Binary = charenc.Binary;
// Inner state
var x = [],
c = [],
b;
var Rabbit = C.Rabbit = {
/**
* Public API
*/
encrypt: function (message, password) {
var
// Convert to bytes
m = UTF8.stringToBytes(message),
// Generate random IV
iv = util.randomBytes(8),
// Generate key
k = password.constructor == String ?
// Derive key from passphrase
C.PBKDF2(password, iv, 32, { asBytes: true }) :
// else, assume byte array representing cryptographic key
password;
// Encrypt
Rabbit._rabbit(m, k, util.bytesToWords(iv));
// Return ciphertext
return util.bytesToBase64(iv.concat(m));
},
decrypt: function (ciphertext, password) {
var
// Convert to bytes
c = util.base64ToBytes(ciphertext),
// Separate IV and message
iv = c.splice(0, 8),
// Generate key
k = password.constructor == String ?
// Derive key from passphrase
C.PBKDF2(password, iv, 32, { asBytes: true }) :
// else, assume byte array representing cryptographic key
password;
// Decrypt
Rabbit._rabbit(c, k, util.bytesToWords(iv));
// Return plaintext
return UTF8.bytesToString(c);
},
/**
* Internal methods
*/
// Encryption/decryption scheme
_rabbit: function (m, k, iv) {
Rabbit._keysetup(k);
if (iv) Rabbit._ivsetup(iv);
for (var s = [], i = 0; i < m.length; i++) {
if (i % 16 == 0) {
// Iterate the system
Rabbit._nextstate();
// Generate 16 bytes of pseudo-random data
s[0] = x[0] ^ (x[5] >>> 16) ^ (x[3] << 16);
s[1] = x[2] ^ (x[7] >>> 16) ^ (x[5] << 16);
s[2] = x[4] ^ (x[1] >>> 16) ^ (x[7] << 16);
s[3] = x[6] ^ (x[3] >>> 16) ^ (x[1] << 16);
// Swap endian
for (var j = 0; j < 4; j++) {
s[j] = ((s[j] << 8) | (s[j] >>> 24)) & 0x00FF00FF |
((s[j] << 24) | (s[j] >>> 8)) & 0xFF00FF00;
}
// Convert words to bytes
for (var b = 120; b >= 0; b -= 8)
s[b / 8] = (s[b >>> 5] >>> (24 - b % 32)) & 0xFF;
}
m[i] ^= s[i % 16];
}
},
// Key setup scheme
_keysetup: function (k) {
// Generate initial state values
x[0] = k[0];
x[2] = k[1];
x[4] = k[2];
x[6] = k[3];
x[1] = (k[3] << 16) | (k[2] >>> 16);
x[3] = (k[0] << 16) | (k[3] >>> 16);
x[5] = (k[1] << 16) | (k[0] >>> 16);
x[7] = (k[2] << 16) | (k[1] >>> 16);
// Generate initial counter values
c[0] = util.rotl(k[2], 16);
c[2] = util.rotl(k[3], 16);
c[4] = util.rotl(k[0], 16);
c[6] = util.rotl(k[1], 16);
c[1] = (k[0] & 0xFFFF0000) | (k[1] & 0xFFFF);
c[3] = (k[1] & 0xFFFF0000) | (k[2] & 0xFFFF);
c[5] = (k[2] & 0xFFFF0000) | (k[3] & 0xFFFF);
c[7] = (k[3] & 0xFFFF0000) | (k[0] & 0xFFFF);
// Clear carry bit
b = 0;
// Iterate the system four times
for (var i = 0; i < 4; i++) Rabbit._nextstate();
// Modify the counters
for (var i = 0; i < 8; i++) c[i] ^= x[(i + 4) & 7];
},
// IV setup scheme
_ivsetup: function (iv) {
// Generate four subvectors
var i0 = util.endian(iv[0]),
i2 = util.endian(iv[1]),
i1 = (i0 >>> 16) | (i2 & 0xFFFF0000),
i3 = (i2 << 16) | (i0 & 0x0000FFFF);
// Modify counter values
c[0] ^= i0;
c[1] ^= i1;
c[2] ^= i2;
c[3] ^= i3;
c[4] ^= i0;
c[5] ^= i1;
c[6] ^= i2;
c[7] ^= i3;
// Iterate the system four times
for (var i = 0; i < 4; i++) Rabbit._nextstate();
},
// Next-state function
_nextstate: function () {
// Save old counter values
for (var c_old = [], i = 0; i < 8; i++) c_old[i] = c[i];
// Calculate new counter values
c[0] = (c[0] + 0x4D34D34D + b) >>> 0;
c[1] = (c[1] + 0xD34D34D3 + ((c[0] >>> 0) < (c_old[0] >>> 0) ? 1 : 0)) >>> 0;
c[2] = (c[2] + 0x34D34D34 + ((c[1] >>> 0) < (c_old[1] >>> 0) ? 1 : 0)) >>> 0;
c[3] = (c[3] + 0x4D34D34D + ((c[2] >>> 0) < (c_old[2] >>> 0) ? 1 : 0)) >>> 0;
c[4] = (c[4] + 0xD34D34D3 + ((c[3] >>> 0) < (c_old[3] >>> 0) ? 1 : 0)) >>> 0;
c[5] = (c[5] + 0x34D34D34 + ((c[4] >>> 0) < (c_old[4] >>> 0) ? 1 : 0)) >>> 0;
c[6] = (c[6] + 0x4D34D34D + ((c[5] >>> 0) < (c_old[5] >>> 0) ? 1 : 0)) >>> 0;
c[7] = (c[7] + 0xD34D34D3 + ((c[6] >>> 0) < (c_old[6] >>> 0) ? 1 : 0)) >>> 0;
b = (c[7] >>> 0) < (c_old[7] >>> 0) ? 1 : 0;
// Calculate the g-values
for (var g = [], i = 0; i < 8; i++) {
var gx = (x[i] + c[i]) >>> 0;
// Construct high and low argument for squaring
var ga = gx & 0xFFFF,
gb = gx >>> 16;
// Calculate high and low result of squaring
var gh = ((((ga * ga) >>> 17) + ga * gb) >>> 15) + gb * gb,
gl = (((gx & 0xFFFF0000) * gx) >>> 0) + (((gx & 0x0000FFFF) * gx) >>> 0) >>> 0;
// High XOR low
g[i] = gh ^ gl;
}
// Calculate new state values
x[0] = g[0] + ((g[7] << 16) | (g[7] >>> 16)) + ((g[6] << 16) | (g[6] >>> 16));
x[1] = g[1] + ((g[0] << 8) | (g[0] >>> 24)) + g[7];
x[2] = g[2] + ((g[1] << 16) | (g[1] >>> 16)) + ((g[0] << 16) | (g[0] >>> 16));
x[3] = g[3] + ((g[2] << 8) | (g[2] >>> 24)) + g[1];
x[4] = g[4] + ((g[3] << 16) | (g[3] >>> 16)) + ((g[2] << 16) | (g[2] >>> 16));
x[5] = g[5] + ((g[4] << 8) | (g[4] >>> 24)) + g[3];
x[6] = g[6] + ((g[5] << 16) | (g[5] >>> 16)) + ((g[4] << 16) | (g[4] >>> 16));
x[7] = g[7] + ((g[6] << 8) | (g[6] >>> 24)) + g[5];
}
};
})();
(function(){
var C = (typeof window === 'undefined') ? require('./Crypto').Crypto : window.Crypto;
// Shortcuts
var util = C.util,
charenc = C.charenc,
UTF8 = charenc.UTF8,
Binary = charenc.Binary;
// Public API
var SHA1 = C.SHA1 = function (message, options) {
var digestbytes = util.wordsToBytes(SHA1._sha1(message));
return options && options.asBytes ? digestbytes :
options && options.asString ? Binary.bytesToString(digestbytes) :
util.bytesToHex(digestbytes);
};
// The core
SHA1._sha1 = function (message) {
// Convert to byte array
if (message.constructor == String) message = UTF8.stringToBytes(message);
/* else, assume byte array already */
var m = util.bytesToWords(message),
l = message.length * 8,
w = [],
H0 = 1732584193,
H1 = -271733879,
H2 = -1732584194,
H3 = 271733878,
H4 = -1009589776;
// Padding
m[l >> 5] |= 0x80 << (24 - l % 32);
m[((l + 64 >>> 9) << 4) + 15] = l;
for (var i = 0; i < m.length; i += 16) {
var a = H0,
b = H1,
c = H2,
d = H3,
e = H4;
for (var j = 0; j < 80; j++) {
if (j < 16) w[j] = m[i + j];
else {
var n = w[j-3] ^ w[j-8] ^ w[j-14] ^ w[j-16];
w[j] = (n << 1) | (n >>> 31);
}
var t = ((H0 << 5) | (H0 >>> 27)) + H4 + (w[j] >>> 0) + (
j < 20 ? (H1 & H2 | ~H1 & H3) + 1518500249 :
j < 40 ? (H1 ^ H2 ^ H3) + 1859775393 :
j < 60 ? (H1 & H2 | H1 & H3 | H2 & H3) - 1894007588 :
(H1 ^ H2 ^ H3) - 899497514);
H4 = H3;
H3 = H2;
H2 = (H1 << 30) | (H1 >>> 2);
H1 = H0;
H0 = t;
}
H0 += a;
H1 += b;
H2 += c;
H3 += d;
H4 += e;
}
return [H0, H1, H2, H3, H4];
};
// Package private blocksize
SHA1._blocksize = 16;
SHA1._digestsize = 20;
})();
(function(){
var C = (typeof window === 'undefined') ? require('./Crypto').Crypto : window.Crypto;
// Shortcuts
var util = C.util,
charenc = C.charenc,
UTF8 = charenc.UTF8,
Binary = charenc.Binary;
// Constants
var K = [ 0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5,
0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5,
0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3,
0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174,
0xE49B69C1, 0xEFBE4786, 0x0FC19DC6, 0x240CA1CC,
0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA,
0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7,
0xC6E00BF3, 0xD5A79147, 0x06CA6351, 0x14292967,
0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13,
0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85,
0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3,
0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070,
0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5,
0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3,
0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208,
0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2 ];
// Public API
var SHA256 = C.SHA256 = function (message, options) {
var digestbytes = util.wordsToBytes(SHA256._sha256(message));
return options && options.asBytes ? digestbytes :
options && options.asString ? Binary.bytesToString(digestbytes) :
util.bytesToHex(digestbytes);
};
// The core
SHA256._sha256 = function (message) {
// Convert to byte array
if (message.constructor == String) message = UTF8.stringToBytes(message);
/* else, assume byte array already */
var m = util.bytesToWords(message),
l = message.length * 8,
H = [ 0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A,
0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19 ],
w = [],
a, b, c, d, e, f, g, h, i, j,
t1, t2;
// Padding
m[l >> 5] |= 0x80 << (24 - l % 32);
m[((l + 64 >> 9) << 4) + 15] = l;
for (var i = 0; i < m.length; i += 16) {
a = H[0];
b = H[1];
c = H[2];
d = H[3];
e = H[4];
f = H[5];
g = H[6];
h = H[7];
for (var j = 0; j < 64; j++) {
if (j < 16) w[j] = m[j + i];
else {
var gamma0x = w[j - 15],
gamma1x = w[j - 2],
gamma0 = ((gamma0x << 25) | (gamma0x >>> 7)) ^
((gamma0x << 14) | (gamma0x >>> 18)) ^
(gamma0x >>> 3),
gamma1 = ((gamma1x << 15) | (gamma1x >>> 17)) ^
((gamma1x << 13) | (gamma1x >>> 19)) ^
(gamma1x >>> 10);
w[j] = gamma0 + (w[j - 7] >>> 0) +
gamma1 + (w[j - 16] >>> 0);
}
var ch = e & f ^ ~e & g,
maj = a & b ^ a & c ^ b & c,
sigma0 = ((a << 30) | (a >>> 2)) ^
((a << 19) | (a >>> 13)) ^
((a << 10) | (a >>> 22)),
sigma1 = ((e << 26) | (e >>> 6)) ^
((e << 21) | (e >>> 11)) ^
((e << 7) | (e >>> 25));
t1 = (h >>> 0) + sigma1 + ch + (K[j]) + (w[j] >>> 0);
t2 = sigma0 + maj;
h = g;
g = f;
f = e;
e = (d + t1) >>> 0;
d = c;
c = b;
b = a;
a = (t1 + t2) >>> 0;
}
H[0] += a;
H[1] += b;
H[2] += c;
H[3] += d;
H[4] += e;
H[5] += f;
H[6] += g;
H[7] += h;
}
return H;
};
// Package private blocksize
SHA256._blocksize = 16;
SHA256._digestsize = 32;
})();
/*
* A JavaScript implementation of the RSA Data Security, Inc. MD5 Message
* Digest Algorithm, as defined in RFC 1321.
* Version 1.1 Copyright (C) Paul Johnston 1999 - 2002.
* Code also contributed by Greg Holt
* See http://pajhome.org.uk/site/legal.html for details.
*/
/*
* Add integers, wrapping at 2^32. This uses 16-bit operations internally
* to work around bugs in some JS interpreters.
*/
function safe_add(x, y)
{
var lsw = (x & 0xFFFF) + (y & 0xFFFF)
var msw = (x >> 16) + (y >> 16) + (lsw >> 16)
return (msw << 16) | (lsw & 0xFFFF)
}
/*
* Bitwise rotate a 32-bit number to the left.
*/
function rol(num, cnt)
{
return (num << cnt) | (num >>> (32 - cnt))
}
/*
* These functions implement the four basic operations the algorithm uses.
*/
function cmn(q, a, b, x, s, t)
{
return safe_add(rol(safe_add(safe_add(a, q), safe_add(x, t)), s), b)
}
function ff(a, b, c, d, x, s, t)
{
return cmn((b & c) | ((~b) & d), a, b, x, s, t)
}
function gg(a, b, c, d, x, s, t)
{
return cmn((b & d) | (c & (~d)), a, b, x, s, t)
}
function hh(a, b, c, d, x, s, t)
{
return cmn(b ^ c ^ d, a, b, x, s, t)
}
function ii(a, b, c, d, x, s, t)
{
return cmn(c ^ (b | (~d)), a, b, x, s, t)
}
/*
* Calculate the MD5 of an array of little-endian words, producing an array
* of little-endian words.
*/
function coreMD5(x)
{
var a = 1732584193
var b = -271733879
var c = -1732584194
var d = 271733878
for(var i = 0; i < x.length; i += 16)
{
var olda = a
var oldb = b
var oldc = c
var oldd = d
a = ff(a, b, c, d, x[i+ 0], 7 , -680876936)
d = ff(d, a, b, c, x[i+ 1], 12, -389564586)
c = ff(c, d, a, b, x[i+ 2], 17, 606105819)
b = ff(b, c, d, a, x[i+ 3], 22, -1044525330)
a = ff(a, b, c, d, x[i+ 4], 7 , -176418897)
d = ff(d, a, b, c, x[i+ 5], 12, 1200080426)
c = ff(c, d, a, b, x[i+ 6], 17, -1473231341)
b = ff(b, c, d, a, x[i+ 7], 22, -45705983)
a = ff(a, b, c, d, x[i+ 8], 7 , 1770035416)
d = ff(d, a, b, c, x[i+ 9], 12, -1958414417)
c = ff(c, d, a, b, x[i+10], 17, -42063)
b = ff(b, c, d, a, x[i+11], 22, -1990404162)
a = ff(a, b, c, d, x[i+12], 7 , 1804603682)
d = ff(d, a, b, c, x[i+13], 12, -40341101)
c = ff(c, d, a, b, x[i+14], 17, -1502002290)
b = ff(b, c, d, a, x[i+15], 22, 1236535329)
a = gg(a, b, c, d, x[i+ 1], 5 , -165796510)
d = gg(d, a, b, c, x[i+ 6], 9 , -1069501632)
c = gg(c, d, a, b, x[i+11], 14, 643717713)
b = gg(b, c, d, a, x[i+ 0], 20, -373897302)
a = gg(a, b, c, d, x[i+ 5], 5 , -701558691)
d = gg(d, a, b, c, x[i+10], 9 , 38016083)
c = gg(c, d, a, b, x[i+15], 14, -660478335)
b = gg(b, c, d, a, x[i+ 4], 20, -405537848)
a = gg(a, b, c, d, x[i+ 9], 5 , 568446438)
d = gg(d, a, b, c, x[i+14], 9 , -1019803690)
c = gg(c, d, a, b, x[i+ 3], 14, -187363961)
b = gg(b, c, d, a, x[i+ 8], 20, 1163531501)
a = gg(a, b, c, d, x[i+13], 5 , -1444681467)
d = gg(d, a, b, c, x[i+ 2], 9 , -51403784)
c = gg(c, d, a, b, x[i+ 7], 14, 1735328473)
b = gg(b, c, d, a, x[i+12], 20, -1926607734)
a = hh(a, b, c, d, x[i+ 5], 4 , -378558)
d = hh(d, a, b, c, x[i+ 8], 11, -2022574463)
c = hh(c, d, a, b, x[i+11], 16, 1839030562)
b = hh(b, c, d, a, x[i+14], 23, -35309556)
a = hh(a, b, c, d, x[i+ 1], 4 , -1530992060)
d = hh(d, a, b, c, x[i+ 4], 11, 1272893353)
c = hh(c, d, a, b, x[i+ 7], 16, -155497632)
b = hh(b, c, d, a, x[i+10], 23, -1094730640)
a = hh(a, b, c, d, x[i+13], 4 , 681279174)
d = hh(d, a, b, c, x[i+ 0], 11, -358537222)
c = hh(c, d, a, b, x[i+ 3], 16, -722521979)
b = hh(b, c, d, a, x[i+ 6], 23, 76029189)
a = hh(a, b, c, d, x[i+ 9], 4 , -640364487)
d = hh(d, a, b, c, x[i+12], 11, -421815835)
c = hh(c, d, a, b, x[i+15], 16, 530742520)
b = hh(b, c, d, a, x[i+ 2], 23, -995338651)
a = ii(a, b, c, d, x[i+ 0], 6 , -198630844)
d = ii(d, a, b, c, x[i+ 7], 10, 1126891415)
c = ii(c, d, a, b, x[i+14], 15, -1416354905)
b = ii(b, c, d, a, x[i+ 5], 21, -57434055)
a = ii(a, b, c, d, x[i+12], 6 , 1700485571)
d = ii(d, a, b, c, x[i+ 3], 10, -1894986606)
c = ii(c, d, a, b, x[i+10], 15, -1051523)
b = ii(b, c, d, a, x[i+ 1], 21, -2054922799)
a = ii(a, b, c, d, x[i+ 8], 6 , 1873313359)
d = ii(d, a, b, c, x[i+15], 10, -30611744)
c = ii(c, d, a, b, x[i+ 6], 15, -1560198380)
b = ii(b, c, d, a, x[i+13], 21, 1309151649)
a = ii(a, b, c, d, x[i+ 4], 6 , -145523070)
d = ii(d, a, b, c, x[i+11], 10, -1120210379)
c = ii(c, d, a, b, x[i+ 2], 15, 718787259)
b = ii(b, c, d, a, x[i+ 9], 21, -343485551)
a = safe_add(a, olda)
b = safe_add(b, oldb)
c = safe_add(c, oldc)
d = safe_add(d, oldd)
}
return [a, b, c, d]
}
/*
* Convert an array of little-endian words to a hex string.
*/
function binl2hex(binarray)
{
var hex_tab = "0123456789abcdef"
var str = ""
for(var i = 0; i < binarray.length * 4; i++)
{
str += hex_tab.charAt((binarray[i>>2] >> ((i%4)*8+4)) & 0xF) +
hex_tab.charAt((binarray[i>>2] >> ((i%4)*8)) & 0xF)
}
return str
}
/*
* Convert an array of little-endian words to a base64 encoded string.
*/
function binl2b64(binarray)
{
var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
var str = ""
for(var i = 0; i < binarray.length * 32; i += 6)
{
str += tab.charAt(((binarray[i>>5] << (i%32)) & 0x3F) |
((binarray[i>>5+1] >> (32-i%32)) & 0x3F))
}
return str
}
/*
* Convert an 8-bit character string to a sequence of 16-word blocks, stored
* as an array, and append appropriate padding for MD4/5 calculation.
* If any of the characters are >255, the high byte is silently ignored.
*/
function str2binl(str)
{
var nblk = ((str.length + 8) >> 6) + 1 // number of 16-word blocks
var blks = new Array(nblk * 16)
for(var i = 0; i < nblk * 16; i++) blks[i] = 0
for(var i = 0; i < str.length; i++)
blks[i>>2] |= (str.charCodeAt(i) & 0xFF) << ((i%4) * 8)
blks[i>>2] |= 0x80 << ((i%4) * 8)
blks[nblk*16-2] = str.length * 8
return blks
}
/*
* Convert a wide-character string to a sequence of 16-word blocks, stored as
* an array, and append appropriate padding for MD4/5 calculation.
*/
function strw2binl(str)
{
var nblk = ((str.length + 4) >> 5) + 1 // number of 16-word blocks
var blks = new Array(nblk * 16)
for(var i = 0; i < nblk * 16; i++) blks[i] = 0
for(var i = 0; i < str.length; i++)
blks[i>>1] |= str.charCodeAt(i) << ((i%2) * 16)
blks[i>>1] |= 0x80 << ((i%2) * 16)
blks[nblk*16-2] = str.length * 16
return blks
}
/*
* External interface
*/
function hexMD5 (str) { return binl2hex(coreMD5( str2binl(str))) }
function hexMD5w(str) { return binl2hex(coreMD5(strw2binl(str))) }
function b64MD5 (str) { return binl2b64(coreMD5( str2binl(str))) }
function b64MD5w(str) { return binl2b64(coreMD5(strw2binl(str))) }
/* Backward compatibility */
function calcMD5(str) { return binl2hex(coreMD5( str2binl(str))) }
module.exports = {
hexMD5: hexMD5
}
\ No newline at end of file
const formatTime = date => {
const year = date.getFullYear()
const month = date.getMonth() + 1
const day = date.getDate()
const hour = date.getHours()
const minute = date.getMinutes()
const second = date.getSeconds()
return [year, month, day].map(formatNumber).join('/') + ' ' + [hour, minute, second].map(formatNumber).join(':')
}
const formatNumber = n => {
n = n.toString()
return n[1] ? n : '0' + n
}
function encodeUTF8(s) {
var i, r = [], c, x;
for (i = 0; i < s.length; i++)
if ((c = s.charCodeAt(i)) < 0x80) r.push(c);
else if (c < 0x800) r.push(0xC0 + (c >> 6 & 0x1F), 0x80 + (c & 0x3F));
else {
if ((x = c ^ 0xD800) >> 10 == 0) //对四字节UTF-16转换为Unicode
c = (x << 10) + (s.charCodeAt(++i) ^ 0xDC00) + 0x10000,
r.push(0xF0 + (c >> 18 & 0x7), 0x80 + (c >> 12 & 0x3F));
else r.push(0xE0 + (c >> 12 & 0xF));
r.push(0x80 + (c >> 6 & 0x3F), 0x80 + (c & 0x3F));
};
return r;
};
// 字符串加密成 hex 字符串
function sha1(s) {
var data = new Uint8Array(encodeUTF8(s))
var i, j, t;
var l = ((data.length + 8) >>> 6 << 4) + 16, s = new Uint8Array(l << 2);
s.set(new Uint8Array(data.buffer)), s = new Uint32Array(s.buffer);
for (t = new DataView(s.buffer), i = 0; i < l; i++)s[i] = t.getUint32(i << 2);
s[data.length >> 2] |= 0x80 << (24 - (data.length & 3) * 8);
s[l - 1] = data.length << 3;
var w = [], f = [
function () { return m[1] & m[2] | ~m[1] & m[3]; },
function () { return m[1] ^ m[2] ^ m[3]; },
function () { return m[1] & m[2] | m[1] & m[3] | m[2] & m[3]; },
function () { return m[1] ^ m[2] ^ m[3]; }
], rol = function (n, c) { return n << c | n >>> (32 - c); },
k = [1518500249, 1859775393, -1894007588, -899497514],
m = [1732584193, -271733879, null, null, -1009589776];
m[2] = ~m[0], m[3] = ~m[1];
for (i = 0; i < s.length; i += 16) {
var o = m.slice(0);
for (j = 0; j < 80; j++)
w[j] = j < 16 ? s[i + j] : rol(w[j - 3] ^ w[j - 8] ^ w[j - 14] ^ w[j - 16], 1),
t = rol(m[0], 5) + f[j / 20 | 0]() + m[4] + w[j] + k[j / 20 | 0] | 0,
m[1] = rol(m[1], 30), m.pop(), m.unshift(t);
for (j = 0; j < 5; j++)m[j] = m[j] + o[j] | 0;
};
t = new DataView(new Uint32Array(m).buffer);
for (var i = 0; i < 5; i++)m[i] = t.getUint32(i << 2);
var hex = Array.prototype.map.call(new Uint8Array(new Uint32Array(m).buffer), function (e) {
return (e < 16 ? "0" : "") + e.toString(16);
}).join("");
return hex;
};
module.exports = {
formatTime: formatTime,
sha1:sha1
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment