备注
:本文是在使用PageMenu实现顶部滑动菜单栏的基础上进行封装优化,实现顶部滑动菜单栏PageMenu的复用
1. 界面展示
我的界面.png如上图所示,点击“我的账单”和“分期列表”分别进入两个PageMenu界面
我的账单有3个界面相同的分页.png
分期列表有2个界面相同的分页.png
2. 界面设计
界面设计.png备注
:考虑视图BillViewController的作用
3.具体实现
(1) UserTableViewController.swift
//
// UserTableViewController.swift
// JackUChat
//
// Created by 徐云 on 2019/1/12.
// Copyright © 2019 Liy. All rights reserved.
//
import UIKit
import Alamofire
import SwiftyJSON
import Kingfisher
class UserTableViewController: UITableViewController {
@IBOutlet weak var accountViewCell: UITableViewCell!
@IBOutlet weak var instalmentViewCell: UITableViewCell!
override func viewDidLoad() {
super.viewDidLoad()
// Uncomment the following line to preserve selection between presentations
// self.clearsSelectionOnViewWillAppear = false
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
// self.navigationItem.rightBarButtonItem = self.editButtonItem
}
// MARK: - Table view data source
//静态单元格不需要下面两段代码,否则会导致界面显示不全
// override func numberOfSections(in tableView: UITableView) -> Int {
// // #warning Incomplete implementation, return the number of sections
// return 0
// }
//
// override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// // #warning Incomplete implementation, return the number of rows
// return 0
// }
/*
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
//只有第二个分区是动态的,其它默认
//let cell = tableView.dequeueReusableCell(withIdentifier: "reuseIdentifier", for: indexPath)
// Configure the cell...
return cell
}*/
/*
// Override to support conditional editing of the table view.
override func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
// Return false if you do not want the specified item to be editable.
return true
}
*/
/*
// Override to support editing the table view.
override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == .delete {
// Delete the row from the data source
tableView.deleteRows(at: [indexPath], with: .fade)
} else if editingStyle == .insert {
// Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
}
}
*/
/*
// Override to support rearranging the table view.
override func tableView(_ tableView: UITableView, moveRowAt fromIndexPath: IndexPath, to: IndexPath) {
}
*/
/*
// Override to support conditional rearranging of the table view.
override func tableView(_ tableView: UITableView, canMoveRowAt indexPath: IndexPath) -> Bool {
// Return false if you do not want the item to be re-orderable.
return true
}
*/
// MARK: - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
// Get the new view controller using segue.destination.
// Pass the selected object to the new view controller.
//账单和分期重用顶部滑动菜单时的菜单列表和内部控制器的区分
let defaults = UserDefaults.standard
if(accountViewCell.isSelected){
defaults.set("account", forKey: "selectMoneyDetail")
}else if(instalmentViewCell.isSelected){
defaults.set("instalment", forKey: "selectMoneyDetail")
}
}
}
(2)共用BillPageMenuViewController.swift
//
// BillPageMenuViewController.swift
// JackUChat
//
// Created by 徐云 on 2019/1/15.
// Copyright © 2019 Liy. All rights reserved.
//
import UIKit
import PageMenu
class BillPageMenuViewController: UIViewController,CAPSPageMenuDelegate {
var pageMenu : CAPSPageMenu?
let statisticsMenuArray = ["按日统计","按月统计","按年统计"]
let instalmentMenuArray = ["分期机器","近期还款"]
var controllerArray : [UIViewController] = []
let defaults = UserDefaults.standard
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
defaults.set(0, forKey: "menu_title_index")
showMenu()
}
func showMenu() {
//设置菜单控制器
setPageMenu()
//设置菜单样式和位置
setPageMenuStyleAndLocation()
//添加到当前控制器的视图上
self.view.addSubview(self.pageMenu!.view)
//代理设置
pageMenu!.delegate = self
}
// MARK: - 设置菜单控制器
func setPageMenu() {
let defaults = UserDefaults.standard
let selectMoneyDetail = defaults.string(forKey: "selectMoneyDetail")!
if (selectMoneyDetail == "account") {//设置账单界面控制器
for category in statisticsMenuArray {
//let vc = self.storyboard?.instantiateViewController(withIdentifier: "BILL_TVC_ID") as! BillTableViewController
let vc = self.storyboard?.instantiateViewController(withIdentifier: "BILL_VC_ID") as! BillViewController
//print(category)
vc.title = category//传值:设置控制器的title值
self.controllerArray.append(vc)
}
}else if (selectMoneyDetail == "instalment") {//设置分期界面控制器
for category in instalmentMenuArray {
let vc = self.storyboard?.instantiateViewController(withIdentifier: "INSTALMENT_TVC_ID") as! InstalmentTableViewController
//print(category)
vc.title = category//传值:设置控制器的title值
self.controllerArray.append(vc)
}
}
}
// MARK: - 设置菜单样式和位置
func setPageMenuStyleAndLocation() {
//设置菜单样式
let parameters: [CAPSPageMenuOption] = [
.menuItemSeparatorWidth(4.3),
.scrollMenuBackgroundColor(UIColor.white),
.viewBackgroundColor(UIColor.orange),
.bottomMenuHairlineColor(UIColor.gray),
.selectionIndicatorColor(UIColor.jackColor),
.menuMargin(20.0),
.menuHeight(40.0),
.selectedMenuItemLabelColor(UIColor.jackColor),
.unselectedMenuItemLabelColor(UIColor.gray),
.menuItemFont(UIFont(name: "HelveticaNeue-Medium", size: 14.0)!),
.useMenuLikeSegmentedControl(true),
.menuItemSeparatorRoundEdges(true),
.selectionIndicatorHeight(2.0),
.menuItemSeparatorPercentageHeight(0.1)
]
//设置菜单位置
let frame = CGRect(x: 0, y: 100, width: self.view.frame.width, height: self.view.frame.height)
pageMenu = CAPSPageMenu(viewControllers: self.controllerArray, frame: frame, pageMenuOptions: parameters)
//print(self.view.frame.height)
}
// MARK: - 代理方法
func didMoveToPage(_ controller: UIViewController, index: Int) {
print("PageView页面顶部滑动菜单索引值:" + index.description)
// if (index == 0) {
// defaults.set(0, forKey: "menu_title_index")
// }else if (index == 1) {
// defaults.set(1, forKey: "menu_title_index")
// }else if (index == 2) {
// defaults.set(3, forKey: "menu_title_index")
// }
}
/*
// MARK: - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
// Get the new view controller using segue.destination.
// Pass the selected object to the new view controller.
}
*/
}
备注
:"BILL_TVC_ID"为视图BillTableViewController的StroyBoard ID;"BILL_VC_ID"为视图BillViewController的StroyBoard ID;"INSTALMENT_TVC_ID"为视图InstalmentTableViewController的StroyBoard ID。
注意
:若指定“我的账单”的界面控制器为let vc = self.storyboard?.instantiateViewController(withIdentifier: "BILL_TVC_ID") as! BillTableViewController
,则“我的账单”界面底部会显示不全,故新增了一个BillViewController视图(包含一个UIView高度占0.75),并指定“我的账单”的界面控制器为let vc = self.storyboard?.instantiateViewController(withIdentifier: "BILL_VC_ID") as! BillViewController
3.1 第一个界面包含三个菜单项
(1)BillViewController.swift
//
// BillViewController.swift
// JackUChat
//
// Created by 徐云 on 2019/1/16.
// Copyright © 2019 Liy. All rights reserved.
//
import UIKit
import Alamofire
import SwiftyJSON
class BillViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
print("BillViewController***viewDidLoad***PageView页面传递到BillViewController的title值:" + title!)
}
// MARK: - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
// Get the new view controller using segue.destination.
// Pass the selected object to the new view controller.
print("BillViewController***prepare***ageView页面传递到BillViewController的title值:" + title!)
let defaults = UserDefaults.standard
defaults.set(title, forKey: "page_menu_title")
}
}
(2) BillTableViewController.swift
//
// BillTableViewController.swift
// JackUChat
//
// Created by 徐云 on 2019/1/15.
// Copyright © 2019 Liy. All rights reserved.
//
import UIKit
import Alamofire
import SwiftyJSON
import Charts
class BillTableViewController: UITableViewController {
@IBOutlet weak var bgTimeLabel: UIButton!
@IBOutlet weak var edTimeLabel: UIButton!
@IBOutlet weak var pieChartView: PieChartView!
var pageMenuTitle = ""
var moneys:[String] = []
var percents:[Double] = []
var devices:[Device] = []
override func viewDidLoad() {
super.viewDidLoad()
// Uncomment the following line to preserve selection between presentations
// self.clearsSelectionOnViewWillAppear = false
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
// self.navigationItem.rightBarButtonItem = self.editButtonItem
let defaults = UserDefaults.standard
pageMenuTitle = defaults.string(forKey: "page_menu_title")!
print("BillTableViewController******PageView页面顶部滑动菜单:" + pageMenuTitle)
getListByAlomafire(pageMenuTitle: pageMenuTitle)
}
// MARK: - Table view data source
// override func numberOfSections(in tableView: UITableView) -> Int {
// // #warning Incomplete implementation, return the number of sections
// return 0
// }
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete implementation, return the number of rows
return devices.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
//let cell = tableView.dequeueReusableCell(withIdentifier: "reuseIdentifier", for: indexPath)
// Configure the cell...
let cellId = String(describing: OrderCell.self)
let cell = tableView.dequeueReusableCell(withIdentifier: cellId, for: indexPath) as! OrderCell
let device = devices[indexPath.row]
cell.deviceNameLabel.text = device.deviceName
cell.deviceNoLabel.text = device.deviceId
cell.countLabel.text = "¥" + device.deviceCount
return cell
}
/*
// Override to support conditional editing of the table view.
override func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
// Return false if you do not want the specified item to be editable.
return true
}
*/
/*
// Override to support editing the table view.
override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == .delete {
// Delete the row from the data source
tableView.deleteRows(at: [indexPath], with: .fade)
} else if editingStyle == .insert {
// Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
}
}
*/
/*
// Override to support rearranging the table view.
override func tableView(_ tableView: UITableView, moveRowAt fromIndexPath: IndexPath, to: IndexPath) {
}
*/
/*
// Override to support conditional rearranging of the table view.
override func tableView(_ tableView: UITableView, canMoveRowAt indexPath: IndexPath) -> Bool {
// Return false if you do not want the item to be re-orderable.
return true
}
*/
func getListByAlomafire(pageMenuTitle:String) {
if (pageMenuTitle == "") {
return
}
var tab = ""
let data = Date()
let timeFormatter = DateFormatter()
if (pageMenuTitle == "按日统计") {
tab = "day"
timeFormatter.dateFormat = "yyyy-MM-dd"
}else if (pageMenuTitle == "按月统计") {
tab = "month"
timeFormatter.dateFormat = "yyyy-MM"
}else if (pageMenuTitle == "按年统计") {
tab = "year"
timeFormatter.dateFormat = "yyyy"
}
let currentTime = timeFormatter.string(from: data)
let params:Parameters = ["tab":tab,"bg_time":currentTime,"dend_time":currentTime]
AlamofireHelper.shareInstance.requestData(.post, url: "account/index", parameters: params) { (result) in
let jsonDictory = JSON(result as Any)
let code = jsonDictory["code"].string
let msg = jsonDictory["msg"].string
if(code == "0"){
print("成功:"+code!+","+msg!)
let nameList = jsonDictory["data"]["orderList"]["name"]
let snList = jsonDictory["data"]["orderList"]["sn"]
let dataList = jsonDictory["data"]["orderList"]["data"]
for index in 0...dataList.count - 1{
let money = "\(dataList[index])"
self.moneys.append(money)
self.percents.append(dataList[index].double!)
}
if (nameList.count == snList.count && nameList.count == dataList.count){
for index in 0...nameList.count - 1{
//重用了OrderCell,为了不新增金额字段,此接口将接收到的金额存储在deviceCount字段中
let device = Device(deviceId: snList[index].string ?? "", deviceName: nameList[index].string ?? "", deviceStatus: "", deviceCount: "\(dataList[index])" , deviceImage: "", date: "")
self.devices.append(device)
}
}
dump(self.devices)//打印
//异步获取数据,需在主线程中更新
OperationQueue.main.addOperation {
self.setChart(dataPoints: self.moneys, values: self.percents)
self.tableView.reloadData()
self.tableView.refreshControl?.endRefreshing()//加载完数据后停止下拉刷新动画
}
}else{
print("失败")
}
}
}
func setChart(dataPoints:[String],values:[Double]) {
var dataEntries:[PieChartDataEntry] = []
for i in 0..<dataPoints.count {
let dataEntry = PieChartDataEntry(value: values[i], label: moneys[i])
dataEntries.append(dataEntry)
}
let chartDataSet = PieChartDataSet(values: dataEntries, label: "Units Sold")
let chartData = PieChartData(dataSet: chartDataSet)
pieChartView.data = chartData
}
/*
// MARK: - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
// Get the new view controller using segue.destination.
// Pass the selected object to the new view controller.
}
*/
}
获取网络数据示例
{
"code": "0",
"msg": "success",
"data": {
"orderList": [
{
"sn": "MCD201793",
"name": "门襟卷缝机(一楼测试2)",
"number": "2个"
},
{
"sn": "Qtest",
"name": "问题测试 ",
"number": "0个"
},
{
"sn": "agentrelay",
"name": "经销商测试工厂中继",
"number": "0件"
},
{
"sn": "10052017679",
"name": "折叠压烫机",
"number": "0个"
},
{
"sn": "0109",
"name": "迈卡袖衩机",
"number": "0个"
},
{
"sn": "LHCS04",
"name": "老化测试04",
"number": "0个"
}
]
}
}
3.2 第二个界面包含两个菜单项
说明
:菜单项对应的界面不一样可参考PageMenu菜单子界面不同的实现
(1) InstalmentViewController.swift
//
// InstalmentViewController.swift
// JackUChat
//
// Created by 徐云 on 2019/1/18.
// Copyright © 2019 Liy. All rights reserved.
//
import UIKit
class InstalmentViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
print("InstalmentViewController******PageView页面传递到InstalmentViewController的title值:" + title!)
}
// MARK: - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
// Get the new view controller using segue.destination.
// Pass the selected object to the new view controller.
print("InstalmentViewController***prepare***PageView页面传递到InstalmentViewController的title值:" + title!)
let defaults = UserDefaults.standard
defaults.set(title, forKey: "page_menu_title")
}
}
(2) InstalmentTableViewController.swift
//
// InstalmentTableViewController.swift
// JackUChat
//
// Created by 徐云 on 2019/1/18.
// Copyright © 2019 Liy. All rights reserved.
//
import UIKit
import Alamofire
import SwiftyJSON
class InstalmentTableViewController: UITableViewController {
@IBOutlet weak var timeLabel: UIButton!
@IBOutlet weak var searchBtn: UIButton!
var pageMenuTitle = ""
var devices:[Device] = []
override func viewDidLoad() {
super.viewDidLoad()
// Uncomment the following line to preserve selection between presentations
// self.clearsSelectionOnViewWillAppear = false
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
// self.navigationItem.rightBarButtonItem = self.editButtonItem
let defaults = UserDefaults.standard
pageMenuTitle = defaults.string(forKey: "page_menu_title")!
print("TableViewController******PageView页面顶部滑动菜单:" + pageMenuTitle)
getListByAlomafire(menuTitleIndex: pageMenuTitle)
}
// MARK: - Table view data source
// override func numberOfSections(in tableView: UITableView) -> Int {
// // #warning Incomplete implementation, return the number of sections
// return 0
// }
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete implementation, return the number of rows
return devices.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
//let cell = tableView.dequeueReusableCell(withIdentifier: "reuseIdentifier", for: indexPath)
// Configure the cell...
let cellId = String(describing: OrderCell.self)
let cell = tableView.dequeueReusableCell(withIdentifier: cellId, for: indexPath) as! OrderCell
let device = devices[indexPath.row]
if(pageMenuTitle == "分期机器"){
cell.deviceNameLabel.text = device.deviceName
cell.deviceNoLabel.text = device.deviceCount + "期,共" + device.deviceId + "元"
if device.deviceStatus == "0" {
cell.countLabel.text = "已完成"
cell.countLabel.textColor = UIColor.gray
}else if device.deviceStatus == "1" {
cell.countLabel.text = "逾期"
cell.countLabel.textColor = UIColor.red
}
}else if(self.pageMenuTitle == "近期还款"){
cell.deviceNameLabel.text = "机器名称:" + device.deviceName
cell.deviceNoLabel.text = device.date
if device.deviceStatus == "-1" {
cell.countLabel.text = "逾期"
cell.countLabel.textColor = UIColor.red
}else if device.deviceStatus == "0" {
cell.countLabel.text = "已完成"
cell.countLabel.textColor = UIColor.gray
}else if device.deviceStatus == "1" {
cell.countLabel.text = "未完成"
cell.countLabel.textColor = UIColor.yellow
}
}
return cell
}
/*
// Override to support conditional editing of the table view.
override func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
// Return false if you do not want the specified item to be editable.
return true
}
*/
/*
// Override to support editing the table view.
override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == .delete {
// Delete the row from the data source
tableView.deleteRows(at: [indexPath], with: .fade)
} else if editingStyle == .insert {
// Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
}
}
*/
/*
// Override to support rearranging the table view.
override func tableView(_ tableView: UITableView, moveRowAt fromIndexPath: IndexPath, to: IndexPath) {
}
*/
/*
// Override to support conditional rearranging of the table view.
override func tableView(_ tableView: UITableView, canMoveRowAt indexPath: IndexPath) -> Bool {
// Return false if you do not want the item to be re-orderable.
return true
}
*/
func getListByAlomafire(menuTitleIndex:String) {
if (pageMenuTitle == "") {
return
}
var tab = ""
if (pageMenuTitle == "分期机器") {
tab = "machine"
}else if (pageMenuTitle == "近期还款") {
tab = "time"
}
let data = Date()
let timeFormatter1 = DateFormatter()
timeFormatter1.dateFormat = "yyyy"
let currentYear = timeFormatter1.string(from: data)
let timeFormatter2 = DateFormatter()
timeFormatter2.dateFormat = "MM"
let currentMonth = timeFormatter2.string(from: data)
let params:Parameters = ["t":tab,"year":currentYear,"month":currentMonth,"page":"1"]
AlamofireHelper.shareInstance.requestData(.post, url: "staging/index", parameters: params) { (result) in
let jsonDictory = JSON(result as Any)
let code = jsonDictory["code"].string
let msg = jsonDictory["msg"].string
if(code == "0"){
print("成功:"+code!+","+msg!)
let list = jsonDictory["data"]["list"].array
if(self.pageMenuTitle == "分期机器"){
for ele in list!{
let device = Device(deviceId: ele["order_total"].string ?? "", deviceName: ele["machine"]["name"].string ?? "", deviceStatus: ele["is_overdue"].string ?? "", deviceCount: ele["count"].string ?? "", deviceImage: "", date: "")
self.devices.append(device)
}
}else if(self.pageMenuTitle == "近期还款"){
for ele in list!{
let device = Device("", deviceName: ele["machine"]["name"].string ?? "", deviceStatus: ele["order_status"].string ?? "", deviceCount: "", deviceImage: "", date: ele["repay_time"].string ?? "")
self.devices.append(device)
}
}
dump(self.devices)//打印
//异步获取数据,需在主线程中更新
OperationQueue.main.addOperation {
self.tableView.reloadData()
self.tableView.refreshControl?.endRefreshing()//加载完数据后停止下拉刷新动画
}
}else{
print("失败")
}
}
}
// MARK: - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
// Get the new view controller using segue.destination.
// Pass the selected object to the new view controller.
}
}
获取网络数据示例
分期机器
{
"code": "0",
"msg": "success",
"data": {
"list": [
{
"company_id": "50",
"cm_id": "415",
"order_status": "0",
"del_time": "0",
"machine": {
"name": "老化测试04",
"sn": "LHCS04",
"machine_id": "29",
"cate": "2",
"cate2": "0",
"channel": "1",
"price": "0.000",
"description": null,
"image": "http://s.uchat.com.cn/public/images/nopic300.png",
"tags": null,
"protocol": null,
"location": "",
"device_id": "39464240",
"imsi": "460040148224171",
"ProductKey": null,
"DeviceName": null,
"DeviceSecret": null,
"IotId": null,
"lac": "26475",
"ci": "12266",
"csq": "0",
"rssi": null,
"lat": "",
"lng": "",
"software": null,
"build_time": "0",
"hardware": null,
"ota_time": "0",
"add_time": "1534829481",
"rent_out": "1",
"status": "0",
"status_time": "1546007261",
"login_type": "7",
"maintain_time": "0",
"last_time": "0",
"params": null,
"param_time": "0",
"parameter": null,
"params_set": null,
"devctrl": "1",
"sale_type": "2",
"is_del": "0"
},
"company": {
"company": "经销商测试专用工厂"
},
"i": 1,
"machine_id": "29",
"cate": "0",
"cust_group": "0",
"is_rent": "0",
"price": "0.000",
"is_min": "0",
"min_num": "0",
"order_total": "0.03",
"order_money": "0.00",
"order_num": "3",
"is_overdue": "0",
"bg_time": "1547704807",
"end_time": "1547711047",
"is_lock": "0",
"force_lock": "0",
"status": "1",
"add_time": "1547704807",
"is_online": "0",
"con_type": "0",
"sale_type": "2",
"parent_id": "0",
"origin": null,
"order": [],
"count": "3",
"use_time": 0
},
{
"cm_id": "414",
"company_id": "50",
"machine_id": "33",
"cate": "0",
"cust_group": "0",
"is_rent": "0",
"price": "0.000",
"is_min": "0",
"min_num": "0",
"order_total": "3.00",
"order_money": "0.00",
"order_num": "3",
"order_status": "0",
"is_overdue": "0",
"bg_time": "1547704807",
"end_time": "1547712892",
"del_time": "0",
"is_lock": "0",
"force_lock": "0",
"status": "1",
"add_time": "1547704807",
"is_online": "0",
"con_type": "0",
"sale_type": "2",
"parent_id": "0",
"origin": null,
"machine": {
"machine_id": "33",
"cate": "2",
"cate2": "0",
"name": "迈卡袖衩机",
"sn": "0109",
"channel": "1",
"price": "0.300",
"description": null,
"image": "http://s.uchat.com.cn/public/images/nopic300.png",
"tags": null,
"protocol": null,
"location": "",
"device_id": "39597199",
"imsi": null,
"ProductKey": null,
"DeviceName": null,
"DeviceSecret": null,
"IotId": null,
"lac": "0",
"ci": "0",
"csq": "0",
"rssi": null,
"lat": "",
"lng": "",
"software": null,
"build_time": "0",
"hardware": null,
"ota_time": "0",
"add_time": "1534917235",
"rent_out": "1",
"status": "0",
"status_time": null,
"login_type": "7",
"maintain_time": "0",
"last_time": "0",
"params": null,
"param_time": "0",
"parameter": null,
"params_set": "{\"\":null}",
"devctrl": "1",
"sale_type": "2",
"is_del": "0"
},
"company": {
"company": "经销商测试专用工厂"
},
"order": [],
"count": "3",
"use_time": 0,
"i": 2
},
{
"cm_id": "346",
"company_id": "50",
"machine_id": "13",
"cate": {
"cate_id": "104",
"sort": "0",
"parent_id": "2",
"cate_name": "1005折叠压烫机",
"image": "/upload/image/2018/09/ff168158835c5fa6fbd4cdd484578c8e.jpg",
"machine_num": "0",
"unit": "个",
"time_unit": "秒",
"is_jtj": "0",
"tiered_num": "0",
"tiered_discount": "0.00"
},
"cust_group": "0",
"is_rent": "0",
"price": "0.000",
"is_min": "0",
"min_num": "0",
"order_total": "900.00",
"order_money": "0.00",
"order_num": "3",
"order_status": "0",
"is_overdue": "0",
"bg_time": "1546940005",
"end_time": "1547544805",
"del_time": "0",
"is_lock": "0",
"force_lock": "0",
"status": "1",
"add_time": "1546940005",
"is_online": "0",
"con_type": "1",
"sale_type": "2",
"parent_id": "343",
"origin": null,
"machine": {
"machine_id": "13",
"cate": "2",
"cate2": "104",
"name": "折叠压烫机",
"sn": "10052017679",
"channel": "1",
"price": "0.000",
"description": null,
"image": "http://s.uchat.com.cn/upload/image/2018/09/ff168158835c5fa6fbd4cdd484578c8e_150x150.jpg",
"tags": null,
"protocol": null,
"location": "",
"device_id": "36488007",
"imsi": null,
"ProductKey": null,
"DeviceName": null,
"DeviceSecret": null,
"IotId": null,
"lac": "0",
"ci": "0",
"csq": "0",
"rssi": null,
"lat": "",
"lng": "",
"software": null,
"build_time": "0",
"hardware": null,
"ota_time": "0",
"add_time": "1532401924",
"rent_out": "1",
"status": "0",
"status_time": "1544075712",
"login_type": "7",
"maintain_time": "0",
"last_time": "0",
"params": null,
"param_time": "0",
"parameter": null,
"params_set": null,
"devctrl": "1",
"sale_type": "2",
"is_del": "0"
},
"company": {
"company": "经销商测试专用工厂"
},
"order": [],
"count": "3",
"use_time": 0,
"i": 3
},
{
"cm_id": "343",
"company_id": "50",
"machine_id": "234",
"cate": "0",
"cust_group": "0",
"is_rent": "0",
"price": "0.000",
"is_min": "0",
"min_num": "0",
"order_total": "1.00",
"order_money": "1.00",
"order_num": "1",
"order_status": "1",
"is_overdue": "1",
"bg_time": "1546876800",
"end_time": "1578412800",
"del_time": "0",
"is_lock": "0",
"force_lock": "0",
"status": "1",
"add_time": "1546937955",
"is_online": "0",
"con_type": "0",
"sale_type": "2",
"parent_id": "0",
"origin": null,
"machine": {
"machine_id": "234",
"cate": "60",
"cate2": "0",
"name": "经销商测试工厂中继",
"sn": "agentrelay",
"channel": "1",
"price": "0.000",
"description": null,
"image": "http://s.uchat.com.cn/public/images/nopic300.png",
"tags": null,
"protocol": null,
"location": "",
"device_id": "514180722",
"imsi": null,
"ProductKey": null,
"DeviceName": null,
"DeviceSecret": null,
"IotId": null,
"lac": "0",
"ci": "0",
"csq": "0",
"rssi": null,
"lat": "",
"lng": "",
"software": null,
"build_time": "0",
"hardware": null,
"ota_time": "0",
"add_time": "1546871622",
"rent_out": "1",
"status": "0",
"status_time": null,
"login_type": "7",
"maintain_time": "1000",
"last_time": "0",
"params": null,
"param_time": "0",
"parameter": null,
"params_set": null,
"devctrl": "1",
"sale_type": "2",
"is_del": "0"
},
"company": {
"company": "经销商测试专用工厂"
},
"order": [
{
"order_id": "8",
"app": "agent",
"sort": "1",
"user_id": "130",
"agent_user_id": "151",
"company_id": "50",
"cm_id": "343",
"order_no": null,
"amount": "1.00",
"total": "1.00",
"order_status": "-1",
"del_time": "1547631708",
"repay_time": "2019-01-08",
"ip": "183.129.132.34",
"ip_addr": "中国 浙江 杭州 ",
"remark": "{\"pay_amount\":\"1\",\"repay\":[{\"money\":\"1.00\",\"order_id\":\"8\"}]}",
"pay_type": "1",
"pay_way": "cash",
"pay_id": null,
"pay_status": "0",
"create_time": "2019-01-08 16:59:15",
"machine": {
"name": "经销商测试工厂中继",
"sn": "agentrelay",
"machine_id": "234"
},
"company": {
"company": "经销商测试专用工厂"
},
"i": 1
}
],
"count": "1",
"machineNum": "1",
"use_time": 0,
"i": 4
}
]
}
}
近期还款
{
"code": "0",
"msg": "success",
"data": {
"list": [
{
"order_id": "8",
"app": "agent",
"sort": "1",
"user_id": "130",
"agent_user_id": "151",
"company_id": "50",
"cm_id": "343",
"order_no": null,
"amount": "1.00",
"total": "1.00",
"order_status": "-1",
"del_time": "1547631708",
"repay_time": "2019-01-08",
"ip": "183.129.132.34",
"ip_addr": "中国 浙江 杭州 ",
"remark": "{\"pay_amount\":\"1\",\"repay\":[{\"money\":\"1.00\",\"order_id\":\"8\"}]}",
"pay_type": "1",
"pay_way": "cash",
"pay_id": null,
"pay_status": "0",
"create_time": "2019-01-08 16:59:15",
"machine": {
"name": "经销商测试工厂中继",
"sn": "agentrelay",
"machine_id": "234"
},
"company": {
"company": "经销商测试专用工厂"
},
"i": 1
}
]
}
}
网友评论