Commit 1980c2e1 authored by 曹云霄's avatar 曹云霄

工单、子单界面搭建,登录接口调试

parent 50f5614f
This diff is collapsed.
......@@ -15,7 +15,6 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
AppManager.shareInstance.openLoginVc();
return true
}
......
......@@ -10,6 +10,5 @@ import UIKit
import HandyJSON
class BaseModel:HandyJSON {
public required init() {}
}
......@@ -14,8 +14,7 @@ class BaseTableViewController: UITableViewController {
super.viewDidLoad()
if #available(iOS 11.0, *) {
tableView.contentInsetAdjustmentBehavior = .never
} else {
automaticallyAdjustsScrollViewInsets = false
}
automaticallyAdjustsScrollViewInsets = false
}
}
......@@ -8,3 +8,6 @@
import Foundation
//本地存储用户信息
public let accountPath: String = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first! + "/userAccount.plist"
......@@ -45,6 +45,35 @@ public enum REPAIR_ORDER_SECTION: Int {
}
/// 工单详情界面分区
///
/// - STATE: 工单状态
/// - SOURCE: 工单来源
/// - SUBORDER: 子工单
/// - COMPLETED: 完成情况
public enum REPAIR_ORDER_DETAIL_SECTION: Int {
case STATE = 0
case SOURCE
case SUBORDER
case COMPLETED
}
/// 子工单编辑界面分区
///
/// - BASIC: 基本信息
/// - COST: 费用与设备信息
/// - DESCRIBE: 描述
/// - AFTERATTACHMENT: 维修前照片
/// - BEFORATTACHMENT: 维修后照片
public enum CHILD_BILL_EDIT_SECTION: Int {
case BASIC = 0
case COST
case DESCRIBE
case AFTERATTACHMENT
case BEFORATTACHMENT
}
......
......@@ -25,6 +25,7 @@ public let kTabBarHeight: CGFloat = 49
public let kROWS: Int = 15
public let kONE: Int = 1
public let kZERO: Int = 0
public let kSectionZero: CGFloat = 0.01
public let kEmptyHeight: CGFloat = 108
public let kWidth: CGFloat = UIScreen.main.bounds.size.width
public let kHeight: CGFloat = UIScreen.main.bounds.size.height
......
......@@ -9,3 +9,9 @@
import Foundation
/// BaseUrl
//public let BaseUrl: String = "http://192.168.1.176:9030/ifs-server/rest"
public let BaseUrl: String = "http://dev.gomoretech.com/ifs-server/rest"
/// 登录
public let loginUrl: String = "/user/login/%@"
......@@ -12,94 +12,81 @@ import YXAlertController
struct Network {
// // 请求头
// static let publicParamEndpointClosure = { (target: Service) -> Endpoint<Service> in
// let url = target.baseURL.appendingPathComponent(target.path).absoluteString
// let endpoint = Endpoint<Service>(url: url, sampleResponseClosure: { .networkResponse(200, target.sampleData) }, method: target.method, task: target.task, httpHeaderFields: target.headers)
//// if let access_token = AppManager.shareInstance.user_Token {
//// return endpoint.adding(newHTTPHeaderFields: ["access_token" : access_token, "x-interface-version" : "1.0"])
//// }else {
// return endpoint
//// }
// }
//
// // 设置超时时间
// static let myRequestClosure = {(endpoint: Endpoint<Service>, closure: MoyaProvider<Service>.RequestResultClosure) -> Void in
// do {
// var urlRequest = try endpoint.urlRequest()
// urlRequest.timeoutInterval = 30
// closure(.success(urlRequest))
// } catch {
// closure(.failure(MoyaError.requestMapping(endpoint.url)))
// }
// }
//
// // 监听请求状态
// static let myNetworkActivityPlugin = NetworkActivityPlugin { (type,target) in
// switch type {
// case .began:
// ShowLoadingView(kWindow)
// UIApplication.shared.isNetworkActivityIndicatorVisible = true
// case .ended:
// HideLoadingView(kWindow)
// UIApplication.shared.isNetworkActivityIndicatorVisible = false
// }
// }
//
// // 公告请求对象
// static let provider = MoyaProvider<Service>(endpointClosure: publicParamEndpointClosure,requestClosure: myRequestClosure,plugins: [myNetworkActivityPlugin])
//
// // MARK: -取消所有请求
// static func cancelAllRequest() {
// provider.manager.session.invalidateAndCancel()
// }
//
// /// 公共请求方法
// ///
// /// - Parameters:
// /// - target: 请求方法
// /// - success: 请求成功
// /// - error: 请求失败
// static func request(target: Service, success: @escaping (JSON) -> Void, failure: @escaping (MoyaError) -> Void) {
// provider.request(target) { result in
// switch result {
// /// 请求成功后先通过json解析数据,如果解析失败使用jsonString重试一次
// case let .success(response):
// do {
// //请求失败
// guard response.statusCode != 404 else {
// failure(MoyaError.statusCode(response))
// return
// }
// //需要重新登录
// guard response.statusCode != 401 else {
// ShowAlertView("提示", "身份凭证已过期,需要重新登录!", ["我知道了"], .alert, { (index) in
//// AppManager.shareInstance.deleteToken();
//// AppManager.shareInstance.openLoginVc();
// })
// return
// }
// let json = try response.mapJSON()
// success(JSON(json))
// } catch {
// switch (error) {
// case MoyaError.jsonMapping(response):
// do {
// let jsonString = try response.mapString()
// success(JSON(jsonString))
// }catch {
// failure(error as! MoyaError)
// }
// default:
// failure(error as! MoyaError)
// break
// }
// }
// break
// case let .failure(error):
// failure(error)
// break
// }
// }
// }
// 请求头
static let publicParamEndpointClosure = { (target: Service) -> Endpoint<Service> in
let url = target.baseURL.appendingPathComponent(target.path).absoluteString
let endpoint = Endpoint<Service>(url: url, sampleResponseClosure: { .networkResponse(200, target.sampleData) }, method: target.method, task: target.task, httpHeaderFields: target.headers)
return endpoint.adding(newHTTPHeaderFields: ["Content-Type" : "application/json;charset=utf-8"])
}
// 设置超时时间
static let myRequestClosure = {(endpoint: Endpoint<Service>, closure: MoyaProvider<Service>.RequestResultClosure) -> Void in
do {
var urlRequest = try endpoint.urlRequest()
urlRequest.timeoutInterval = 30
closure(.success(urlRequest))
} catch {
closure(.failure(MoyaError.requestMapping(endpoint.url)))
}
}
// 监听请求状态
static let myNetworkActivityPlugin = NetworkActivityPlugin { (type,target) in
switch type {
case .began:
ShowLoadingView(kWindow)
UIApplication.shared.isNetworkActivityIndicatorVisible = true
case .ended:
HideLoadingView(kWindow)
UIApplication.shared.isNetworkActivityIndicatorVisible = false
}
}
// 公告请求对象
static let provider = MoyaProvider<Service>(endpointClosure: publicParamEndpointClosure,requestClosure: myRequestClosure,plugins: [myNetworkActivityPlugin])
// MARK: -取消所有请求
static func cancelAllRequest() {
provider.manager.session.invalidateAndCancel()
}
/// 公共请求方法
///
/// - Parameters:
/// - target: 请求方法
/// - success: 请求成功
/// - error: 请求失败
static func request(target: Service, success: @escaping (JSON) -> Void, failure: @escaping (MoyaError) -> Void) {
provider.request(target) { result in
switch result {
/// 请求成功后先通过json解析数据,如果解析失败使用jsonString重试一次
case let .success(response):
do {
guard response.statusCode == 200 else {
failure(MoyaError.statusCode(response))
return
}
let json = try response.mapJSON()
success(JSON(json))
} catch {
switch (error) {
case MoyaError.jsonMapping(response):
do {
let jsonString = try response.mapString()
success(JSON(jsonString))
}catch {
failure(error as! MoyaError)
}
default:
failure(error as! MoyaError)
break
}
}
break
case let .failure(error):
failure(error)
break
}
}
}
}
......@@ -7,10 +7,50 @@
//
import Foundation
import Moya
import Alamofire
public enum Service {
// MARK: - 登录
case Login(String,String)
}
extension Service: TargetType {
public var baseURL: URL {
return URL(string: BaseUrl)!
}
public var path: String {
switch self {
case .Login(let name, _):
return String(format: loginUrl, name)
}
}
public var method: Moya.Method {
switch self {
case .Login(_, _):
return .post
}
}
public var sampleData: Data {
return "Create post successfully".data(using: String.Encoding.utf8)!
}
public var task: Task {
switch self {
case .Login(_, let password):
return .requestParameters(parameters: ["password": password,
"authenticode": "211534962"],
encoding: JSONEncoding.default)
}
}
public var headers: [String : String]? {
return ["device" : UIDevice.current.name]
}
}
......
......@@ -13,8 +13,9 @@ import Async
/// 更新高度后回调
protocol PhotoAttachmentDelegate {
func updatePhotoAttachment(_ height: CGFloat)
func updatePhotoAttachment(_ height: CGFloat, _ key: String?)
}
class PhotoAttachmentViewController: BaseViewController {
......@@ -28,6 +29,8 @@ class PhotoAttachmentViewController: BaseViewController {
return attachmentViewModel
}()
/// key
var key: String?
/// 间隔
let SPACE: Int = 5
/// 每行个数
......@@ -61,7 +64,8 @@ class PhotoAttachmentViewController: BaseViewController {
}
// MARK: - 计算图片附件所需高度
open func attachmentHeight(_ count: Int) ->CGFloat {
open func attachmentHeight(_ count: Int, _ key: String?) ->CGFloat {
self.key = key
let rows = (count + COUNT - kONE) / COUNT
return CGFloat(rows) * imageHeight + CGFloat((rows - kONE) * SPACE)
}
......@@ -129,10 +133,10 @@ extension PhotoAttachmentViewController: ImagePickerDelegate {
attachmentViewModel.photoAttachments.insert(PhotoAttachmentModel(image, .ATTACHMENT_LOCAL), at: kZERO)
dismiss(animated: true, completion: {[weak self] ()->() in
let count = self?.attachmentViewModel.photoAttachments.count
let height = self?.attachmentHeight(count!)
let height = self?.attachmentHeight(count!,self?.key)
DispatchQueue.main.async(execute: {
self?.photoAttachmentCollectionView.reloadData()
self?.delegate?.updatePhotoAttachment(height!)
self?.delegate?.updatePhotoAttachment(height!,self?.key)
})
})
}
......@@ -148,10 +152,10 @@ extension PhotoAttachmentViewController: DeleteAttachmentDelegate {
func deleteAttachment(_ indexPath: IndexPath) {
attachmentViewModel.photoAttachments.remove(at: indexPath.item)
let count = attachmentViewModel.photoAttachments.count
let height = attachmentHeight(count)
let height = attachmentHeight(count,key)
DispatchQueue.main.async(execute: {
self.photoAttachmentCollectionView.reloadData()
self.delegate?.updatePhotoAttachment(height)
self.delegate?.updatePhotoAttachment(height,self.key)
})
}
}
......
......@@ -72,7 +72,7 @@ class RepairOrderAddTableViewController: BaseTableViewController {
fileprivate func setupPhotoAttachmentVc(){
addChildViewController(attachmentVc)
attachmentVc.attachmentViewModel.photoAttachments.append(PhotoAttachmentModel("add_photo", .ATTACHMENT_ADD))
attachmentHeight = attachmentVc.attachmentHeight(kONE)
attachmentHeight = attachmentVc.attachmentHeight(kONE,nil)
}
// MARK: - 绑定RxSwift事件
......@@ -117,13 +117,13 @@ class RepairOrderAddTableViewController: BaseTableViewController {
if facilitiesSwitch.isOn {
return sectionHeight
}
return CGFloat(0.01)
return kSectionZero
}
return 10
}
override func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
return CGFloat(0.01)
return kSectionZero
}
override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
......@@ -135,7 +135,7 @@ class RepairOrderAddTableViewController: BaseTableViewController {
}
extension RepairOrderAddTableViewController: PhotoAttachmentDelegate {
func updatePhotoAttachment(_ height: CGFloat) {
func updatePhotoAttachment(_ height: CGFloat, _ key: String?) {
attachmentHeight = height
tableView.reloadData()
}
......
//
// RepairOrderChildBillDetailViewController.swift
// IFS
//
// Created by 曹云霄 on 2018/1/8.
// Copyright © 2018年 上海勾芒信息科技有限公司. All rights reserved.
//
import UIKit
class RepairOrderChildBillDetailViewController: BaseTableViewController {
override func viewDidLoad() {
super.viewDidLoad()
}
}
//
// RepairOrderDetailViewController.swift
// IFS
//
// Created by 曹云霄 on 2018/1/8.
// Copyright © 2018年 上海勾芒信息科技有限公司. All rights reserved.
//
import UIKit
import RxCocoa
import RxSwift
class RepairOrderDetailViewController: BaseTableViewController {
/// RxSwift自动释放
let disposeBag = DisposeBag()
/// 悬浮View
lazy final var suspendView: RepairOrderDetailSuspendView = {
var suspendView = RepairOrderDetailSuspendView.instantiateFromNib() as! RepairOrderDetailSuspendView
suspendView.frame = CGRect(x: 15, y: kHeight - kNavHeight - 80, width: kWidth - 30, height: 60)
suspendView.operationOrderBtn.rx.controlEvent(UIControlEvents.touchUpInside).subscribe(onNext: {[weak self] (event) in
self?.gotoEditingSonOrderVc()
}).disposed(by: disposeBag)
return suspendView;
}()
/// 底部(转交、完成)View
lazy final var bottomView: RepairOrderDetailBottomView = {
var bottomView = RepairOrderDetailBottomView.instantiateFromNib()
bottomView.frame = CGRect(x: 0, y: getTableViewHeight(), width: kWidth, height: 70)
return bottomView as! RepairOrderDetailBottomView;
}()
override func viewDidLoad() {
super.viewDidLoad()
setupTableView()
}
// MARK: - 设置TableView
fileprivate func setupTableView() {
tableView.register(UINib(nibName: RepairOrderDetailSectionView.name(), bundle: nil), forHeaderFooterViewReuseIdentifier: RepairOrderDetailSectionView.name())
tableView.register(UINib(nibName: RepairOrderSubOrderTableViewCell.name(), bundle: nil), forCellReuseIdentifier: RepairOrderSubOrderTableViewCell.name())
tableView.tableFooterView = bottomView
view.addSubview(suspendView)
}
// MARK: - 获取tableView显示内容高度
fileprivate func getTableViewHeight() ->CGFloat {
view.layoutIfNeeded()
return tableView.contentSize.height
}
// MARK: - 前往子工单完成界面
fileprivate func gotoEditingSonOrderVc() {
self.performSegue(withIdentifier: RepairOrderEditSonOrderViewController.name(), sender: nil)
}
// MARK: - UITableViewDelegate,UITableViewDataSource
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if indexPath.section == REPAIR_ORDER_DETAIL_SECTION.SUBORDER.rawValue {
let subOrderCell = tableView.dequeueReusableCell(withIdentifier: RepairOrderSubOrderTableViewCell.name(), for: indexPath)
return subOrderCell
}
return super.tableView(tableView, cellForRowAt: indexPath)
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if section == REPAIR_ORDER_DETAIL_SECTION.SUBORDER.rawValue {
return 5
}
return super.tableView(tableView, numberOfRowsInSection: section)
}
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
if indexPath.section == REPAIR_ORDER_DETAIL_SECTION.SUBORDER.rawValue {
return 70
}
return super.tableView(tableView, heightForRowAt: indexPath)
}
override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
if section == REPAIR_ORDER_DETAIL_SECTION.STATE.rawValue {
return UIView()
}
let sectionView = tableView.dequeueReusableHeaderFooterView(withIdentifier: RepairOrderDetailSectionView.name())
return sectionView
}
//cell的缩进级别,动态静态cell必须重写,否则会造成崩溃
override func tableView(_ tableView: UITableView, indentationLevelForRowAt indexPath: IndexPath) -> Int {
if indexPath.section == REPAIR_ORDER_DETAIL_SECTION.SUBORDER.rawValue {
return super.tableView(tableView, indentationLevelForRowAt: IndexPath(row: 0, section: REPAIR_ORDER_DETAIL_SECTION.SUBORDER.rawValue))
}
return super.tableView(tableView, indentationLevelForRowAt: indexPath)
}
override func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
if section == REPAIR_ORDER_DETAIL_SECTION.STATE.rawValue {
return kSectionZero
}
return 35
}
override func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
if section == REPAIR_ORDER_DETAIL_SECTION.SUBORDER.rawValue {
return 10.0
}
return kSectionZero
}
// MARK: - 监听滑动改变悬浮View透明度
override func scrollViewDidScroll(_ scrollView: UIScrollView) {
let yoffset = scrollView.contentOffset.y
if yoffset >= 0 {
suspendView.alpha = 1 - abs(yoffset) * kSectionZero
}
}
}
//
// RepairOrderEditSonOrderViewController.swift
// IFS
//
// Created by 曹云霄 on 2018/1/8.
// Copyright © 2018年 上海勾芒信息科技有限公司. All rights reserved.
//
import UIKit
import RxSwift
import RxCocoa
class RepairOrderEditSonOrderViewController: BaseTableViewController {
/// RxSwift自动释放
let disposeBag = DisposeBag()
/// 默认section高度
let sectionHeight: CGFloat! = 30
/// 维修前图片附件高度
var beforAttachmentHeight: CGFloat! = 0
/// 维修后图片附件高度
var afterAttachmentHeight: CGFloat! = 0
/// key
let after: String = "after"
let befor: String = "befor"
/// 维修前图片附件
lazy final var beforAttachmentVc: PhotoAttachmentViewController = {
var attachmentVc = PhotoAttachmentViewController.instantiateViewController(.Function) as! PhotoAttachmentViewController
attachmentVc.delegate = self
return attachmentVc
}()
/// 维修后图片附件
lazy final var afterAttachmentVc: PhotoAttachmentViewController = {
var attachmentVc = PhotoAttachmentViewController.instantiateViewController(.Function) as! PhotoAttachmentViewController
attachmentVc.delegate = self
return attachmentVc
}()
override func viewDidLoad() {
super.viewDidLoad()
setupTableView()
setupPhotoAttachmentVc()
}
// MARK: - 设置附件VC
fileprivate func setupPhotoAttachmentVc(){
addChildViewController(afterAttachmentVc)
addChildViewController(beforAttachmentVc)
beforAttachmentVc.attachmentViewModel.photoAttachments.append(PhotoAttachmentModel("add_photo", .ATTACHMENT_ADD))
afterAttachmentVc.attachmentViewModel.photoAttachments.append(PhotoAttachmentModel("add_photo", .ATTACHMENT_ADD))
afterAttachmentHeight = afterAttachmentVc.attachmentHeight(kONE,after)
beforAttachmentHeight = beforAttachmentVc.attachmentHeight(kONE,befor)
}
// MARK: - TableView
fileprivate func setupTableView() {
tableView.register(RepairAfterAttachmentTableViewCell.classForCoder(), forCellReuseIdentifier: RepairAfterAttachmentTableViewCell.name())
tableView.register(RepairBeforAttachmentTableViewCell.classForCoder(), forCellReuseIdentifier: RepairBeforAttachmentTableViewCell.name())
let completeView = RepairOrderEditSonOrderCompleteView.instantiateFromNib() as! RepairOrderEditSonOrderCompleteView
completeView.completeBtn.rx.controlEvent(UIControlEvents.touchUpInside).subscribe(onNext: {[weak self] (event) in
self?.gotoChildBillDetailVc()
}).disposed(by: disposeBag)
tableView.tableFooterView = completeView
}
// MARK: - 跳转子工单详情
fileprivate func gotoChildBillDetailVc() {
self.performSegue(withIdentifier: RepairOrderChildBillDetailViewController.name(), sender: nil)
}
// MARK: - UITableViewDelegate,UITableViewDataSource
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if indexPath.section == CHILD_BILL_EDIT_SECTION.BEFORATTACHMENT.rawValue {
let beforCell = tableView.dequeueReusableCell(withIdentifier: RepairBeforAttachmentTableViewCell.name(), for: indexPath)
beforAttachmentVc.view.frame = CGRect(x: 15, y: 8, width: kWidth - 30, height: beforAttachmentHeight)
beforCell.contentView.addSubview(beforAttachmentVc.view)
return beforCell
}
if indexPath.section == CHILD_BILL_EDIT_SECTION.AFTERATTACHMENT.rawValue {
let afterCell = tableView.dequeueReusableCell(withIdentifier: RepairAfterAttachmentTableViewCell.name(), for: indexPath)
afterAttachmentVc.view.frame = CGRect(x: 15, y: 8, width: kWidth - 30, height: afterAttachmentHeight)
afterCell.contentView.addSubview(afterAttachmentVc.view)
return afterCell
}
return super.tableView(tableView, cellForRowAt: indexPath)
}
override func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
return kSectionZero
}
override func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
if section == CHILD_BILL_EDIT_SECTION.DESCRIBE.rawValue {
return 10
}
return sectionHeight
}
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
if indexPath.section == CHILD_BILL_EDIT_SECTION.BEFORATTACHMENT.rawValue {
return beforAttachmentHeight + 20
}
if indexPath.section == CHILD_BILL_EDIT_SECTION.AFTERATTACHMENT.rawValue {
return afterAttachmentHeight + 20
}
return super.tableView(tableView, heightForRowAt: indexPath)
}
}
extension RepairOrderEditSonOrderViewController: PhotoAttachmentDelegate {
func updatePhotoAttachment(_ height: CGFloat, _ key: String?) {
switch key! {
case befor:
beforAttachmentHeight = height
break
case after:
afterAttachmentHeight = height
break
default:
break
}
tableView.reloadData()
}
}
......@@ -114,5 +114,23 @@ class RepairOrderViewController: BaseTableViewPullController {
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 135
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
self.performSegue(withIdentifier: RepairOrderDetailViewController.name(), sender: nil)
}
}
//
// RepairAfterAttachmentTableViewCell.swift
// IFS
//
// Created by 曹云霄 on 2018/1/8.
// Copyright © 2018年 上海勾芒信息科技有限公司. All rights reserved.
//
import UIKit
class RepairAfterAttachmentTableViewCell: UITableViewCell {
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
}
//
// RepairBeforAttachmentTableViewCell.swift
// IFS
//
// Created by 曹云霄 on 2018/1/8.
// Copyright © 2018年 上海勾芒信息科技有限公司. All rights reserved.
//
import UIKit
class RepairBeforAttachmentTableViewCell: UITableViewCell {
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
}
//
// RepairOrderDetailBottomView.swift
// IFS
//
// Created by 曹云霄 on 2018/1/8.
// Copyright © 2018年 上海勾芒信息科技有限公司. All rights reserved.
//
import UIKit
class RepairOrderDetailBottomView: UIView {
/// 转交
@IBOutlet weak var transferButton: UIButton!
/// 完成
@IBOutlet weak var completeButton: UIButton!
}
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="13771" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
<device id="retina4_7" orientation="portrait">
<adaptation id="fullscreen"/>
</device>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="13772"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<view contentMode="scaleToFill" id="iN0-l3-epB" customClass="RepairOrderDetailBottomView" customModule="IFS" customModuleProvider="target">
<rect key="frame" x="0.0" y="0.0" width="375" height="70"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="1mh-aC-JRq">
<rect key="frame" x="0.0" y="21" width="187.5" height="49"/>
<constraints>
<constraint firstAttribute="height" constant="49" id="Yza-1q-CFi"/>
</constraints>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<state key="normal" title="转交"/>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="OGh-UT-VCv">
<rect key="frame" x="187.5" y="21" width="187.5" height="49"/>
<color key="backgroundColor" red="0.21755459899999999" green="0.53306800129999998" blue="0.99824184179999997" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<state key="normal" title="完成">
<color key="titleColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
</state>
</button>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="DWW-Eq-xjB">
<rect key="frame" x="0.0" y="20" width="375" height="1"/>
<color key="backgroundColor" red="0.94901960780000005" green="0.94901960780000005" blue="0.94901960780000005" alpha="1" colorSpace="calibratedRGB"/>
<constraints>
<constraint firstAttribute="height" constant="1" id="y4N-Dd-1UD"/>
</constraints>
</view>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Aqz-jC-Q2t">
<rect key="frame" x="0.0" y="69" width="375" height="1"/>
<color key="backgroundColor" red="0.94901960780000005" green="0.94901960780000005" blue="0.94901960780000005" alpha="1" colorSpace="calibratedRGB"/>
<constraints>
<constraint firstAttribute="height" constant="1" id="yfP-6J-aYK"/>
</constraints>
</view>
</subviews>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<constraints>
<constraint firstAttribute="bottom" secondItem="1mh-aC-JRq" secondAttribute="bottom" id="36x-7m-r3b"/>
<constraint firstItem="OGh-UT-VCv" firstAttribute="leading" secondItem="1mh-aC-JRq" secondAttribute="trailing" id="3o0-od-HLJ"/>
<constraint firstItem="Aqz-jC-Q2t" firstAttribute="trailing" secondItem="vUN-kp-3ea" secondAttribute="trailing" id="8fA-X7-kX2"/>
<constraint firstAttribute="bottom" secondItem="OGh-UT-VCv" secondAttribute="bottom" id="G0O-pu-dCE"/>
<constraint firstItem="1mh-aC-JRq" firstAttribute="top" secondItem="DWW-Eq-xjB" secondAttribute="bottom" id="Z1M-y1-9yS"/>
<constraint firstItem="OGh-UT-VCv" firstAttribute="width" secondItem="1mh-aC-JRq" secondAttribute="width" id="ZtD-ny-5Rc"/>
<constraint firstAttribute="trailing" secondItem="DWW-Eq-xjB" secondAttribute="trailing" id="bNC-PD-AEV"/>
<constraint firstItem="OGh-UT-VCv" firstAttribute="trailing" secondItem="vUN-kp-3ea" secondAttribute="trailing" id="dM9-er-Dd0"/>
<constraint firstItem="vUN-kp-3ea" firstAttribute="bottom" secondItem="Aqz-jC-Q2t" secondAttribute="bottom" id="jd2-Ct-hvz"/>
<constraint firstItem="DWW-Eq-xjB" firstAttribute="leading" secondItem="vUN-kp-3ea" secondAttribute="leading" id="jmE-PH-fKI"/>
<constraint firstItem="1mh-aC-JRq" firstAttribute="leading" secondItem="vUN-kp-3ea" secondAttribute="leading" id="p6k-LW-ads"/>
<constraint firstItem="OGh-UT-VCv" firstAttribute="height" secondItem="1mh-aC-JRq" secondAttribute="height" id="rxI-cN-5oE"/>
<constraint firstItem="Aqz-jC-Q2t" firstAttribute="leading" secondItem="vUN-kp-3ea" secondAttribute="leading" id="wvI-jq-ap2"/>
</constraints>
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
<viewLayoutGuide key="safeArea" id="vUN-kp-3ea"/>
<connections>
<outlet property="completeButton" destination="OGh-UT-VCv" id="vk6-oA-yP7"/>
<outlet property="transferButton" destination="1mh-aC-JRq" id="P0y-jq-TXN"/>
</connections>
<point key="canvasLocation" x="-100.5" y="-210"/>
</view>
</objects>
</document>
//
// RepairOrderDetailSectionView.swift
// IFS
//
// Created by 曹云霄 on 2018/1/8.
// Copyright © 2018年 上海勾芒信息科技有限公司. All rights reserved.
//
import UIKit
class RepairOrderDetailSectionView: UITableViewHeaderFooterView {
/// 分区标题
@IBOutlet weak var sectionStateLabel: UILabel!
/// 状态时间
@IBOutlet weak var stateTimeLabel: UILabel!
}
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="13771" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
<device id="retina4_7" orientation="portrait">
<adaptation id="fullscreen"/>
</device>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="13772"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<view contentMode="scaleToFill" id="iN0-l3-epB" customClass="RepairOrderDetailSectionView" customModule="IFS" customModuleProvider="target">
<rect key="frame" x="0.0" y="0.0" width="375" height="35"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="r9G-Tf-b6p">
<rect key="frame" x="0.0" y="0.0" width="375" height="35"/>
<color key="backgroundColor" red="0.94901960780000005" green="0.94901960780000005" blue="0.94901960780000005" alpha="1" colorSpace="calibratedRGB"/>
</view>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="创建" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="V1c-PP-K0F">
<rect key="frame" x="15" y="10" width="27" height="16"/>
<fontDescription key="fontDescription" type="system" pointSize="13"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="2018-01-08 10:50:32" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Yca-g4-cKt">
<rect key="frame" x="230" y="10" width="130" height="16"/>
<fontDescription key="fontDescription" type="system" pointSize="13"/>
<nil key="highlightedColor"/>
</label>
</subviews>
<constraints>
<constraint firstItem="V1c-PP-K0F" firstAttribute="centerY" secondItem="iN0-l3-epB" secondAttribute="centerY" id="B6L-hb-eA7"/>
<constraint firstItem="r9G-Tf-b6p" firstAttribute="bottom" secondItem="vUN-kp-3ea" secondAttribute="bottom" id="GIB-hb-rqc"/>
<constraint firstItem="vUN-kp-3ea" firstAttribute="trailing" secondItem="Yca-g4-cKt" secondAttribute="trailing" constant="15" id="Kkx-xf-fYA"/>
<constraint firstItem="Yca-g4-cKt" firstAttribute="centerY" secondItem="V1c-PP-K0F" secondAttribute="centerY" id="aok-Zb-yGX"/>
<constraint firstItem="r9G-Tf-b6p" firstAttribute="trailing" secondItem="vUN-kp-3ea" secondAttribute="trailing" id="dRA-Gb-lvj"/>
<constraint firstItem="r9G-Tf-b6p" firstAttribute="leading" secondItem="vUN-kp-3ea" secondAttribute="leading" id="eKW-mz-Imy"/>
<constraint firstItem="V1c-PP-K0F" firstAttribute="leading" secondItem="vUN-kp-3ea" secondAttribute="leading" constant="15" id="loY-Ew-Xkx"/>
<constraint firstItem="r9G-Tf-b6p" firstAttribute="top" secondItem="vUN-kp-3ea" secondAttribute="top" id="xgR-ie-FLs"/>
</constraints>
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
<viewLayoutGuide key="safeArea" id="vUN-kp-3ea"/>
<connections>
<outlet property="sectionStateLabel" destination="V1c-PP-K0F" id="99j-1M-e1P"/>
<outlet property="stateTimeLabel" destination="Yca-g4-cKt" id="qEz-fH-6O3"/>
</connections>
<point key="canvasLocation" x="16.5" y="-77.5"/>
</view>
</objects>
</document>
//
// RepairOrderDetailSuspendView.swift
// IFS
//
// Created by 曹云霄 on 2018/1/8.
// Copyright © 2018年 上海勾芒信息科技有限公司. All rights reserved.
//
import UIKit
class RepairOrderDetailSuspendView: UIView {
/// 内容背景
@IBOutlet weak var contentBgView: UIView!
/// 操作工单(领单、完成)
@IBOutlet weak var operationOrderBtn: UIButton!
/// 工单状态
@IBOutlet weak var orderStateLab: UILabel!
/// 部门
@IBOutlet weak var departmentLab: UILabel!
/// 转交时间
@IBOutlet weak var operationTimeLab: UIView!
override func awakeFromNib() {
super.awakeFromNib()
uiConfigAction()
}
// MARK: - UI
fileprivate func uiConfigAction() {
addShadow(UIColor.black)
contentBgView.addAngle(5.0)
}
}
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="13771" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
<device id="retina4_7" orientation="portrait">
<adaptation id="fullscreen"/>
</device>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="13772"/>
<capability name="Constraints with non-1.0 multipliers" minToolsVersion="5.1"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<view contentMode="scaleToFill" id="iN0-l3-epB" customClass="RepairOrderDetailSuspendView" customModule="IFS" customModuleProvider="target">
<rect key="frame" x="0.0" y="0.0" width="375" height="60"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Mq2-FF-B2L">
<rect key="frame" x="0.0" y="0.0" width="375" height="60"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="工程部" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="9hT-Fx-col">
<rect key="frame" x="15" y="9.5" width="43" height="17"/>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="转交时间:" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="stD-aL-v0r">
<rect key="frame" x="15" y="35" width="62" height="14.5"/>
<fontDescription key="fontDescription" type="system" pointSize="12"/>
<color key="textColor" white="0.33333333333333331" alpha="1" colorSpace="calibratedWhite"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="未开始" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Ozr-71-Z31">
<rect key="frame" x="263" y="11" width="37" height="14.5"/>
<fontDescription key="fontDescription" type="system" pointSize="12"/>
<color key="textColor" white="0.66666666666666663" alpha="1" colorSpace="calibratedWhite"/>
<nil key="highlightedColor"/>
</label>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="4Ae-kJ-XQN">
<rect key="frame" x="315" y="0.0" width="60" height="60"/>
<color key="backgroundColor" red="0.0" green="0.47843137250000001" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<constraints>
<constraint firstAttribute="width" constant="60" id="hwM-34-dPe"/>
</constraints>
<state key="normal" title="领单">
<color key="titleColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
</state>
</button>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="2018-01-08 10:37:59" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="kFy-ui-f5T">
<rect key="frame" x="77" y="35" width="121" height="14.5"/>
<fontDescription key="fontDescription" type="system" pointSize="12"/>
<color key="textColor" white="0.33333333333333331" alpha="1" colorSpace="calibratedWhite"/>
<nil key="highlightedColor"/>
</label>
</subviews>
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
<constraints>
<constraint firstItem="4Ae-kJ-XQN" firstAttribute="leading" secondItem="Ozr-71-Z31" secondAttribute="trailing" constant="15" id="98g-Sh-8Y5"/>
<constraint firstItem="kFy-ui-f5T" firstAttribute="leading" secondItem="stD-aL-v0r" secondAttribute="trailing" id="Bks-hx-Xkx"/>
<constraint firstItem="Ozr-71-Z31" firstAttribute="centerY" secondItem="9hT-Fx-col" secondAttribute="centerY" id="C3T-ZS-CZF"/>
<constraint firstItem="9hT-Fx-col" firstAttribute="centerY" secondItem="Mq2-FF-B2L" secondAttribute="centerY" multiplier="0.6" id="GxZ-UF-YHL"/>
<constraint firstAttribute="trailing" secondItem="4Ae-kJ-XQN" secondAttribute="trailing" id="M9B-tX-ICY"/>
<constraint firstItem="kFy-ui-f5T" firstAttribute="centerY" secondItem="stD-aL-v0r" secondAttribute="centerY" id="SvC-DQ-rCR"/>
<constraint firstItem="9hT-Fx-col" firstAttribute="leading" secondItem="Mq2-FF-B2L" secondAttribute="leading" constant="15" id="hdw-1M-dy0"/>
<constraint firstAttribute="bottom" secondItem="4Ae-kJ-XQN" secondAttribute="bottom" id="o2L-CA-Dt4"/>
<constraint firstItem="stD-aL-v0r" firstAttribute="leading" secondItem="9hT-Fx-col" secondAttribute="leading" id="q6B-SN-jvs"/>
<constraint firstItem="4Ae-kJ-XQN" firstAttribute="top" secondItem="Mq2-FF-B2L" secondAttribute="top" id="ubj-aK-v2m"/>
<constraint firstItem="stD-aL-v0r" firstAttribute="centerY" secondItem="Mq2-FF-B2L" secondAttribute="centerY" multiplier="1.4" id="wCJ-0c-N9x"/>
</constraints>
</view>
</subviews>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
<constraints>
<constraint firstItem="Mq2-FF-B2L" firstAttribute="leading" secondItem="vUN-kp-3ea" secondAttribute="leading" id="NdF-Vf-Y2X"/>
<constraint firstItem="Mq2-FF-B2L" firstAttribute="bottom" secondItem="vUN-kp-3ea" secondAttribute="bottom" id="UeU-Yf-bLL"/>
<constraint firstItem="Mq2-FF-B2L" firstAttribute="trailing" secondItem="vUN-kp-3ea" secondAttribute="trailing" id="jEq-QZ-Tx9"/>
<constraint firstItem="Mq2-FF-B2L" firstAttribute="top" secondItem="vUN-kp-3ea" secondAttribute="top" id="tMv-DD-jOT"/>
</constraints>
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
<viewLayoutGuide key="safeArea" id="vUN-kp-3ea"/>
<connections>
<outlet property="contentBgView" destination="Mq2-FF-B2L" id="4Ue-ir-jtf"/>
<outlet property="departmentLab" destination="9hT-Fx-col" id="MzW-Dg-7Kj"/>
<outlet property="operationOrderBtn" destination="4Ae-kJ-XQN" id="vln-FL-YrN"/>
<outlet property="operationTimeLab" destination="Mq2-FF-B2L" id="Chc-GC-zj8"/>
<outlet property="orderStateLab" destination="Ozr-71-Z31" id="9SP-Yx-cRB"/>
</connections>
<point key="canvasLocation" x="33.5" y="231"/>
</view>
</objects>
</document>
//
// RepairOrderEditSonOrderCompleteView.swift
// IFS
//
// Created by 曹云霄 on 2018/1/8.
// Copyright © 2018年 上海勾芒信息科技有限公司. All rights reserved.
//
import UIKit
class RepairOrderEditSonOrderCompleteView: UIView {
/// 完成
@IBOutlet weak var completeBtn: UIButton!
}
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="13771" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
<device id="retina4_7" orientation="portrait">
<adaptation id="fullscreen"/>
</device>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="13772"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<view contentMode="scaleToFill" id="iN0-l3-epB" customClass="RepairOrderEditSonOrderCompleteView" customModule="IFS" customModuleProvider="target">
<rect key="frame" x="0.0" y="0.0" width="375" height="49"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="yB3-AZ-0Kg">
<rect key="frame" x="0.0" y="0.0" width="375" height="49"/>
<color key="backgroundColor" red="0.99215686274509807" green="0.61568627450980395" blue="0.30980392156862746" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<fontDescription key="fontDescription" type="system" weight="medium" pointSize="15"/>
<state key="normal" title="完成">
<color key="titleColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
</state>
</button>
</subviews>
<constraints>
<constraint firstItem="vUN-kp-3ea" firstAttribute="bottom" secondItem="yB3-AZ-0Kg" secondAttribute="bottom" id="5gT-TG-5ai"/>
<constraint firstItem="vUN-kp-3ea" firstAttribute="trailing" secondItem="yB3-AZ-0Kg" secondAttribute="trailing" id="9YU-E1-guY"/>
<constraint firstItem="yB3-AZ-0Kg" firstAttribute="leading" secondItem="vUN-kp-3ea" secondAttribute="leading" id="UHH-vJ-aTE"/>
<constraint firstItem="yB3-AZ-0Kg" firstAttribute="top" secondItem="vUN-kp-3ea" secondAttribute="top" id="iyi-DZ-cv2"/>
</constraints>
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
<viewLayoutGuide key="safeArea" id="vUN-kp-3ea"/>
<connections>
<outlet property="completeBtn" destination="yB3-AZ-0Kg" id="nv7-F5-dxv"/>
</connections>
<point key="canvasLocation" x="122.5" y="347"/>
</view>
</objects>
</document>
//
// RepairOrderSubOrderTableViewCell.swift
// IFS
//
// Created by 曹云霄 on 2018/1/8.
// Copyright © 2018年 上海勾芒信息科技有限公司. All rights reserved.
//
import UIKit
class RepairOrderSubOrderTableViewCell: UITableViewCell {
/// 部门
@IBOutlet weak var departmentName: UILabel!
/// 转交时间
@IBOutlet weak var transferTimeLabel: UILabel!
/// 工单状态
@IBOutlet weak var subOrderState: UILabel!
/// 内容背景
@IBOutlet weak var contentBgView: UIView!
override func awakeFromNib() {
super.awakeFromNib()
uiConfigAction()
}
// MARK: - UI
fileprivate func uiConfigAction() {
contentBgView.addAngle(10.0)
contentBgView.addBorder(1.0, kGaryColor)
}
}
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="13771" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
<device id="retina4_7" orientation="portrait">
<adaptation id="fullscreen"/>
</device>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="13772"/>
<capability name="Constraints with non-1.0 multipliers" minToolsVersion="5.1"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<tableViewCell contentMode="scaleToFill" selectionStyle="none" indentationWidth="10" id="KGk-i7-Jjw" customClass="RepairOrderSubOrderTableViewCell" customModule="IFS" customModuleProvider="target">
<rect key="frame" x="0.0" y="0.0" width="375" height="70"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="KGk-i7-Jjw" id="H2p-sc-9uM">
<rect key="frame" x="0.0" y="0.0" width="375" height="69.5"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="iXK-9n-8CZ">
<rect key="frame" x="15" y="10" width="345" height="59.5"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="工程部" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="jv3-76-R1p">
<rect key="frame" x="15" y="9.5" width="43" height="17"/>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="转交时间:" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="JPd-pD-Y4s">
<rect key="frame" x="15" y="34.5" width="61.5" height="14.5"/>
<fontDescription key="fontDescription" type="system" pointSize="12"/>
<color key="textColor" white="0.33333333333333331" alpha="1" colorSpace="calibratedWhite"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="2018-01-08 10:37:59" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="2Os-EU-PFL">
<rect key="frame" x="76.5" y="34.5" width="121" height="14.5"/>
<fontDescription key="fontDescription" type="system" pointSize="12"/>
<color key="textColor" white="0.33333333333333331" alpha="1" colorSpace="calibratedWhite"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="已完成" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="WXJ-0x-D52">
<rect key="frame" x="290" y="10" width="40" height="16"/>
<fontDescription key="fontDescription" type="system" pointSize="13"/>
<color key="textColor" red="0.21755459899999999" green="0.53306800129999998" blue="0.99824184179999997" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
</subviews>
<constraints>
<constraint firstAttribute="trailing" secondItem="WXJ-0x-D52" secondAttribute="trailing" constant="15" id="E7i-7V-QDq"/>
<constraint firstItem="jv3-76-R1p" firstAttribute="centerY" secondItem="iXK-9n-8CZ" secondAttribute="centerY" multiplier="0.6" id="OoP-za-6WD"/>
<constraint firstItem="2Os-EU-PFL" firstAttribute="centerY" secondItem="JPd-pD-Y4s" secondAttribute="centerY" id="SAb-QY-DX7"/>
<constraint firstItem="WXJ-0x-D52" firstAttribute="centerY" secondItem="jv3-76-R1p" secondAttribute="centerY" id="dQC-3e-fCi"/>
<constraint firstItem="2Os-EU-PFL" firstAttribute="leading" secondItem="JPd-pD-Y4s" secondAttribute="trailing" id="mSs-YQ-aFD"/>
<constraint firstItem="JPd-pD-Y4s" firstAttribute="leading" secondItem="jv3-76-R1p" secondAttribute="leading" id="rxu-ch-tCX"/>
<constraint firstItem="jv3-76-R1p" firstAttribute="leading" secondItem="iXK-9n-8CZ" secondAttribute="leading" constant="15" id="tjM-uI-HuO"/>
<constraint firstItem="JPd-pD-Y4s" firstAttribute="centerY" secondItem="iXK-9n-8CZ" secondAttribute="centerY" multiplier="1.4" id="uec-70-WCN"/>
</constraints>
</view>
</subviews>
<constraints>
<constraint firstAttribute="trailing" secondItem="iXK-9n-8CZ" secondAttribute="trailing" constant="15" id="4Ki-3e-u2u"/>
<constraint firstItem="iXK-9n-8CZ" firstAttribute="top" secondItem="H2p-sc-9uM" secondAttribute="top" constant="10" id="6m3-VS-Pp5"/>
<constraint firstAttribute="bottom" secondItem="iXK-9n-8CZ" secondAttribute="bottom" id="EJ3-vT-i23"/>
<constraint firstItem="iXK-9n-8CZ" firstAttribute="leading" secondItem="H2p-sc-9uM" secondAttribute="leading" constant="15" id="hdP-Ty-wso"/>
</constraints>
</tableViewCellContentView>
<viewLayoutGuide key="safeArea" id="njF-e1-oar"/>
<connections>
<outlet property="contentBgView" destination="iXK-9n-8CZ" id="fiE-6x-Xdz"/>
<outlet property="departmentName" destination="jv3-76-R1p" id="dV7-He-WGw"/>
<outlet property="subOrderState" destination="WXJ-0x-D52" id="y8p-mW-3fg"/>
<outlet property="transferTimeLabel" destination="2Os-EU-PFL" id="P7n-gm-JxE"/>
</connections>
<point key="canvasLocation" x="-85" y="-21"/>
</tableViewCell>
</objects>
</document>
//
// ReparirChildBillViewModel.swift
// IFS
//
// Created by 曹云霄 on 2018/1/8.
// Copyright © 2018年 上海勾芒信息科技有限公司. All rights reserved.
//
import UIKit
class ReparirChildBillViewModel: BaseViewModel {
}
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -32,6 +32,9 @@
<state key="normal" title="登录">
<color key="titleColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
</state>
<connections>
<action selector="loginButtonClickAction:" destination="q7c-Qo-6S4" eventType="touchUpInside" id="KhF-O2-ilk"/>
</connections>
</button>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="HmM-ZF-dEf">
<rect key="frame" x="0.0" y="240" width="414" height="372"/>
......
......@@ -11,46 +11,41 @@ import Hero
class AppManager: NSObject {
// /// 登录用户信息
// open var userModel: UserModel!
// /// 用户token
// open var user_Token: String! {
// didSet {
// //本地存储
// UserDefaults.standard.set(user_Token, forKey: kUserToken)
// UserDefaults.standard.synchronize()
// }
// }
//
/// 登录用户信息
open var userModel: UserModel!
/// 单例模式
static var shareInstance: AppManager = {
let instance = AppManager();
AppStyle.setupAppStyle()
return instance;
}();
//
// MARK: - 打开主页
func openMainVc() {
let tabBarVc: TabBarViewController = TabBarViewController()
kWindow.rootViewController = tabBarVc
setRootVc(tabBarVc, .transitionCrossDissolve)
}
//
// // MARK: - 广告页
// func openAdvertising() {
// let startPageVc: AdvertisingViewController = AdvertisingViewController()
// kWindow.rootViewController = startPageVc
// }
//
// // MARK: - 清除本地token,重新登录
// func deleteToken() {
// UserDefaults.standard.removeObject(forKey: kUserToken)
// }
// MARK: - 打开登录页
func openLoginVc() {
LoginViewModel.unarchiveAccountInformation()
guard AppManager.shareInstance.userModel == nil else {
openMainVc()
return
}
let loginVc = LoginViewController.instantiateViewController(.Main)
kWindow.rootViewController = loginVc
setRootVc(loginVc, .transitionCrossDissolve)
}
// MARK: - 动画切换根视图控制器
fileprivate func setRootVc(_ controller: UIViewController,_ options: UIViewAnimationOptions) {
UIView.transition(with: kWindow, duration: 0.5, options: options, animations: {
let oldState = UIView.areAnimationsEnabled
UIView.setAnimationsEnabled(false)
kWindow.rootViewController = controller
UIView.setAnimationsEnabled(oldState)
}, completion: nil)
}
}
......
......@@ -23,27 +23,32 @@ class LoginViewController: UIViewController {
@IBOutlet weak var passwordTextField: UITextField!
@IBOutlet weak var passwordLineView: UIView!
/// 登录ViewModel
lazy final var loginViewModel: LoginViewModel = {
var loginViewModel = LoginViewModel()
return loginViewModel
}()
// MARK: - 隐藏状态栏
override var prefersStatusBarHidden: Bool {
return true
}
override func viewDidLoad() {
super.viewDidLoad()
uiConfigAction()
addBtnClickAction()
bindingRxAction()
}
// MARK: - 隐藏状态栏
override var prefersStatusBarHidden: Bool {
return true
}
// MARK: - UI
fileprivate func uiConfigAction() {
loginButton.addAngle(25.0)
}
// MARK: - 登录
fileprivate func addBtnClickAction() {
loginButton.rx.controlEvent(.touchUpInside).subscribe(onNext: { (event) in
@IBAction func loginButtonClickAction(_ sender: UIButton) {
loginViewModel.loginRequest(userNameTextField.text!, passwordTextField.text!).subscribe(onNext: { (event) in
AppManager.shareInstance.openMainVc()
}).disposed(by: disposeBag)
}
......@@ -58,7 +63,6 @@ class LoginViewController: UIViewController {
}.subscribe(onNext: {[weak self] (boolValue) in
self?.userNameLineView.backgroundColor = boolValue ? kBlueColor : kGaryColor
}).disposed(by: disposeBag)
passwordTextField.rx.text.map { (text) -> Bool in
if (text?.isEmpty)! {
return false
......@@ -67,7 +71,6 @@ class LoginViewController: UIViewController {
}.subscribe(onNext: {[weak self] (boolValue) in
self?.passwordLineView.backgroundColor = boolValue ? kBlueColor : kGaryColor
}).disposed(by: disposeBag)
Observable.combineLatest(userNameTextField.rx.text.orEmpty,passwordTextField.rx.text.orEmpty).map { (arg) -> Bool in
let (userName, passowrd) = arg
return userName.count > 0 && passowrd.count > 0
......
//
// LoginResultModel.swift
//
// Create by 云霄 曹 on 8/1/2018
// Copyright © 2018. All rights reserved.
import Foundation
import SwiftyJSON
class LoginResultModel : NSObject, NSCoding{
var data : UserModel!
var message : String!
var success : Bool!
/**
* Instantiate the instance using the passed json values to set the properties values
*/
init(fromJson json: JSON!){
if json.isEmpty{
return
}
let dataJson = json["data"]
if !dataJson.isEmpty{
data = UserModel(fromJson: dataJson)
}
message = json["message"].stringValue
success = json["success"].boolValue
}
/**
* Returns all the available property values in the form of [String:Any] object where the key is the approperiate json key and the value is the value of the corresponding property
*/
func toDictionary() -> [String:Any]
{
var dictionary = [String:Any]()
if data != nil{
dictionary["data"] = data.toDictionary()
}
if message != nil{
dictionary["message"] = message
}
if success != nil{
dictionary["success"] = success
}
return dictionary
}
/**
* NSCoding required initializer.
* Fills the data from the passed decoder
*/
@objc required init(coder aDecoder: NSCoder)
{
data = aDecoder.decodeObject(forKey: "data") as? UserModel
message = aDecoder.decodeObject(forKey: "message") as? String
success = aDecoder.decodeObject(forKey: "success") as? Bool
}
/**
* NSCoding required method.
* Encodes mode properties into the decoder
*/
func encode(with aCoder: NSCoder)
{
if data != nil{
aCoder.encode(data, forKey: "data")
}
if message != nil{
aCoder.encode(message, forKey: "message")
}
if success != nil{
aCoder.encode(success, forKey: "success")
}
}
}
//
// LoginViewModel.swift
// IFS
//
// Created by 曹云霄 on 2018/1/8.
// Copyright © 2018年 上海勾芒信息科技有限公司. All rights reserved.
//
import UIKit
import RxSwift
import Moya
class LoginViewModel: BaseViewModel {
/// 登录
///
/// - Parameters:
/// - login: 用户名
/// - password: 密码
func loginRequest(_ login: String, _ password: String) ->Observable<String> {
return Observable.create({(observer) -> Disposable in
Network.request(target: .Login(login, password.md5()), success: {(json) in
let model = LoginResultModel(fromJson: json)
if model.success {
AppManager.shareInstance.userModel = model.data
LoginViewModel.archiveAccountInformation()
observer.onNext(json.description)
}else {
ShowMessage(model.message)
}
}) { (error) in
ShowMessage(error.localizedDescription)
}
return Disposables.create()
})
}
// MARK: - 归档用户信息
open class func archiveAccountInformation() {
let bool = NSKeyedArchiver.archiveRootObject(AppManager.shareInstance.userModel, toFile: accountPath)
if bool {
print("归档成功")
}else {
print("归档失败")
}
}
// MARK: - 解档用户信息
open class func unarchiveAccountInformation() {
let account = NSKeyedUnarchiver.unarchiveObject(withFile: accountPath) as? UserModel
AppManager.shareInstance.userModel = account
}
}
//
// UserModel.swift
// UserModel.swift
//
// Create by 云霄 曹 on 7/12/2017
// Copyright © 2017. All rights reserved.
// Create by 云霄 曹 on 8/1/2018
// Copyright © 2018. All rights reserved.
// Model file generated using JSONExport: https://github.com/Ahmed-Ali/JSONExport
import Foundation
import Foundation
import SwiftyJSON
class UserModel: BaseModel {
var location: String! = "---"
var hireable: String!
var public_gists: Int = 0
var url: String!
var following_url: String!
var events_url: String!
var received_events_url: String!
var company: String! = "---"
var updated_at: String!
var bio: String!
var avatar_url: String!
var name: String!
var type: String!
var subscriptions_url: String!
var gists_url: String!
var id: Int = 0
var starred_url: String!
var organizations_url: String!
var repos_url: String!
var site_admin: Bool = false
var email: String! = "---"
var login: String!
var blog: String! = "---"
var public_repos: Int = 0
var followers: Int = 0
var following: Int = 0
var created_at: String!
var gravatar_id: String!
var followers_url: String!
var html_url: String!
class UserModel : NSObject, NSCoding{
var authenticode : String!
var belongOrgIsLeaf : Bool!
var belongOrgPath : String!
var enterpriseCode : String!
var enterpriseName : String!
var enterpriseUuid : String!
var orgCode : String!
var orgName : String!
var orgUuid : String!
var permissions : [String]!
var position : AnyObject!
var userCode : String!
var userName : String!
var userUuid : String!
/**
* Instantiate the instance using the passed json values to set the properties values
*/
init(fromJson json: JSON!){
if json.isEmpty{
return
}
authenticode = json["authenticode"].stringValue
belongOrgIsLeaf = json["belongOrgIsLeaf"].boolValue
belongOrgPath = json["belongOrgPath"].stringValue
enterpriseCode = json["enterprise_code"].stringValue
enterpriseName = json["enterprise_name"].stringValue
enterpriseUuid = json["enterprise_uuid"].stringValue
orgCode = json["org_code"].stringValue
orgName = json["org_name"].stringValue
orgUuid = json["org_uuid"].stringValue
permissions = [String]()
let permissionsArray = json["permissions"].arrayValue
for permissionsJson in permissionsArray{
permissions.append(permissionsJson.stringValue)
}
position = json["position"].stringValue as AnyObject
userCode = json["user_code"].stringValue
userName = json["user_name"].stringValue
userUuid = json["user_uuid"].stringValue
}
/**
* Returns all the available property values in the form of [String:Any] object where the key is the approperiate json key and the value is the value of the corresponding property
*/
func toDictionary() -> [String:Any]
{
var dictionary = [String:Any]()
if authenticode != nil{
dictionary["authenticode"] = authenticode
}
if belongOrgIsLeaf != nil{
dictionary["belongOrgIsLeaf"] = belongOrgIsLeaf
}
if belongOrgPath != nil{
dictionary["belongOrgPath"] = belongOrgPath
}
if enterpriseCode != nil{
dictionary["enterprise_code"] = enterpriseCode
}
if enterpriseName != nil{
dictionary["enterprise_name"] = enterpriseName
}
if enterpriseUuid != nil{
dictionary["enterprise_uuid"] = enterpriseUuid
}
if orgCode != nil{
dictionary["org_code"] = orgCode
}
if orgName != nil{
dictionary["org_name"] = orgName
}
if orgUuid != nil{
dictionary["org_uuid"] = orgUuid
}
if permissions != nil{
dictionary["permissions"] = permissions
}
if position != nil{
dictionary["position"] = position
}
if userCode != nil{
dictionary["user_code"] = userCode
}
if userName != nil{
dictionary["user_name"] = userName
}
if userUuid != nil{
dictionary["user_uuid"] = userUuid
}
return dictionary
}
/**
* NSCoding required initializer.
* Fills the data from the passed decoder
*/
@objc required init(coder aDecoder: NSCoder)
{
authenticode = aDecoder.decodeObject(forKey: "authenticode") as? String
belongOrgIsLeaf = aDecoder.decodeObject(forKey: "belongOrgIsLeaf") as? Bool
belongOrgPath = aDecoder.decodeObject(forKey: "belongOrgPath") as? String
enterpriseCode = aDecoder.decodeObject(forKey: "enterprise_code") as? String
enterpriseName = aDecoder.decodeObject(forKey: "enterprise_name") as? String
enterpriseUuid = aDecoder.decodeObject(forKey: "enterprise_uuid") as? String
orgCode = aDecoder.decodeObject(forKey: "org_code") as? String
orgName = aDecoder.decodeObject(forKey: "org_name") as? String
orgUuid = aDecoder.decodeObject(forKey: "org_uuid") as? String
permissions = aDecoder.decodeObject(forKey: "permissions") as? [String]
position = aDecoder.decodeObject(forKey: "position") as AnyObject
userCode = aDecoder.decodeObject(forKey: "user_code") as? String
userName = aDecoder.decodeObject(forKey: "user_name") as? String
userUuid = aDecoder.decodeObject(forKey: "user_uuid") as? String
}
/**
* NSCoding required method.
* Encodes mode properties into the decoder
*/
func encode(with aCoder: NSCoder)
{
if authenticode != nil{
aCoder.encode(authenticode, forKey: "authenticode")
}
if belongOrgIsLeaf != nil{
aCoder.encode(belongOrgIsLeaf, forKey: "belongOrgIsLeaf")
}
if belongOrgPath != nil{
aCoder.encode(belongOrgPath, forKey: "belongOrgPath")
}
if enterpriseCode != nil{
aCoder.encode(enterpriseCode, forKey: "enterprise_code")
}
if enterpriseName != nil{
aCoder.encode(enterpriseName, forKey: "enterprise_name")
}
if enterpriseUuid != nil{
aCoder.encode(enterpriseUuid, forKey: "enterprise_uuid")
}
if orgCode != nil{
aCoder.encode(orgCode, forKey: "org_code")
}
if orgName != nil{
aCoder.encode(orgName, forKey: "org_name")
}
if orgUuid != nil{
aCoder.encode(orgUuid, forKey: "org_uuid")
}
if permissions != nil{
aCoder.encode(permissions, forKey: "permissions")
}
if position != nil{
aCoder.encode(position, forKey: "position")
}
if userCode != nil{
aCoder.encode(userCode, forKey: "user_code")
}
if userName != nil{
aCoder.encode(userName, forKey: "user_name")
}
if userUuid != nil{
aCoder.encode(userUuid, forKey: "user_uuid")
}
}
}
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"filename" : "state_default@2x.png",
"scale" : "2x"
},
{
"idiom" : "universal",
"filename" : "state_default@3x.png",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
\ No newline at end of file
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"filename" : "state_selected@2x.png",
"scale" : "2x"
},
{
"idiom" : "universal",
"filename" : "state_selected@3x.png",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
\ No newline at end of file
......@@ -2,6 +2,7 @@
"images" : [
{
"idiom" : "universal",
"filename" : "add_photo.png",
"scale" : "1x"
},
{
......@@ -11,7 +12,6 @@
},
{
"idiom" : "universal",
"filename" : "add_photo@3x.png",
"scale" : "3x"
}
],
......
......@@ -22,7 +22,7 @@ func BaseMBProgressView(_ view: UIView) -> MBProgressHUD {
func ShowMessage(_ message: String) {
let hud = BaseMBProgressView(kWindow)
hud.mode = MBProgressHUDMode.text
hud.label.text = "加载中"
hud.label.text = "提示"
hud.detailsLabel.text = message
hud.hide(animated: true, afterDelay: 3)
}
......
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