-public extension NavigationBarInOut where Self: UIViewController {
19
-    func navigationBarFadeIn() {
20
-        UIView.animate(withDuration: 0.5, delay: 0, usingSpringWithDamping: 1, initialSpringVelocity: 0, options: [], animations: {
21
-            self.navigationView.alpha = 0
22
-        }, completion: nil)
23
-    }
24
-    
25
-    func navigationBarFadeOut() {
26
-        UIView.animate(withDuration: 0.5, animations: {
27
-            self.navigationView.alpha = 1
28
-        }, completion: nil)
29
-    }
30
-    
31
-    func navigationBarFadeOutWithPercentage(_ percentage: CGFloat) {
32
-        self.navigationView.alpha = 1 * percentage
33
-    }
34
-}

+ 64 - 0
PaiAi/PaiaiUIKit/Reusable/UIKit/NavigationBar/NavigationBarInOutAnimator.swift

@@ -0,0 +1,64 @@
1
+//
2
+//  NavigationBarInOutAnimator.swift
3
+//  PaiaiUIKit
4
+//
5
+//  Created by ffib on 2019/1/15.
6
+//  Copyright © 2019 yb. All rights reserved.
7
+//
8
+
9
+import UIKit
10
+
11
+public protocol NavigationBarInOutAnimator: class {
12
+    var navigationView: UIView { get }
13
+    func navigationBarFadeIn()
14
+    func navigationBarFadeOut()
15
+    func navigationBarFadeAndMoveIn()
16
+    func navigationBarFadeAndMoveOut()
17
+    func navigationBarFadeOutWithPercentage(_ percentage: CGFloat)
18
+    func navigationBarFadeInWithPercentage(_ percentage: CGFloat)
19
+}
20
+
21
+public extension NavigationBarInOutAnimator where Self: UIViewController & NavigationBarPushAndPopDelegate {
22
+    func navigationBarFadeIn() {
23
+        UIView.animate(withDuration: 0.3, animations: {
24
+            self.navigationView.alpha = 1
25
+        }, completion: nil)
26
+    }
27
+    
28
+    func navigationBarFadeOut() {
29
+        UIView.animate(withDuration: 0.3, animations: {
30
+            self.navigationView.alpha = 0
31
+        }, completion: nil)
32
+    }
33
+    
34
+    func navigationBarFadeAndMoveIn() {
35
+        setNavigationBar()
36
+        navigationController?.navigationBar.layoutIfNeeded()
37
+        
38
+        let originX = navigationView.center.x
39
+        navigationView.center.x = UIScreen.main.bounds.width
40
+        
41
+        UIView.animate(withDuration: 0.3, animations: {
42
+            self.navigationView.alpha = 1
43
+            self.navigationView.center.x = originX
44
+        }, completion: nil)
45
+    }
46
+    
47
+    func navigationBarFadeAndMoveOut() {
48
+        UIView.animate(withDuration: 0.3, animations: {
49
+            self.navigationView.alpha = 0
50
+            self.navigationView.center.x = UIScreen.main.bounds.width
51
+        }, completion: { _ in
52
+            self.navigationView.removeFromSuperview()
53
+        })
54
+    }
55
+    
56
+    func navigationBarFadeOutWithPercentage(_ percentage: CGFloat) {
57
+        navigationView.alpha = 1 * (1 - 1.1 * percentage)
58
+        navigationView.center.x = UIScreen.main.bounds.width / 2  * (1 + 1.1 * percentage)
59
+    }
60
+    
61
+    func navigationBarFadeInWithPercentage(_ percentage: CGFloat) {
62
+        navigationView.alpha = 1 * percentage
63
+    }
64
+}

+ 31 - 12
PaiAi/PaiaiUIKit/Reusable/UIKit/NavigationBar/NavigationBarInteractivePopDeletegate.swift

@@ -12,8 +12,7 @@ public protocol NavigationBarInteractivePopDeletegate: class {
12 12
     func setupNavigationBarInteractivePopDelegate()
13 13
 }
14 14
 
15
-public extension NavigationBarInteractivePopDeletegate where Self: UIViewController & NavigationBarInOut {
16
-    
15
+public extension NavigationBarInteractivePopDeletegate where Self: UIViewController & NavigationBarInOutAnimator {
17 16
     func setupNavigationBarInteractivePopDelegate() {
18 17
         guard let nav = navigationController else { return }
19 18
         nav.interactivePopGestureRecognizer?.addTarget(self, action: #selector(interactivePopAnimation(gesture:)))
@@ -22,23 +21,43 @@ public extension NavigationBarInteractivePopDeletegate where Self: UIViewControl
22 21
 
23 22
 extension UIViewController {
24 23
     @objc func interactivePopAnimation(gesture: UIPanGestureRecognizer) {
24
+        guard let `self` =  self as? (NavigationBarInOutAnimator & UIViewController) else { return }
25 25
         let point = gesture.translation(in: view)
26 26
         let percentage = calculatePercentageOfOffsets(point: point)
27
-        (self as? NavigationBarInOut)?.navigationBarFadeOutWithPercentage(percentage)
28 27
         
29
-        switch gesture.state {
30
-        case .ended:
31
-            if percentage > 0.5 {
32
-                (self as? NavigationBarInOut)?.navigationBarFadeOut()
33
-            } else {
34
-                (self as? NavigationBarInOut)?.navigationBarFadeIn()
35
-            }
36
-        default:
28
+        /// naivgationController == nil  popped viewController
29
+        /// navigationController?.visibleViewController == self pop to viewController
30
+        
31
+        let percentageAnimation: ((CGFloat) -> Void)
32
+        let fadeInAnimation: (() -> Void)
33
+        let fadeOutAnimation: (() -> Void)
34
+        if navigationController == nil {
35
+            percentageAnimation = self.navigationBarFadeOutWithPercentage
36
+            fadeInAnimation = self.navigationBarFadeAndMoveIn
37
+            fadeOutAnimation = self.navigationBarFadeAndMoveOut
38
+        } else if navigationController?.visibleViewController == self {
39
+            percentageAnimation = self.navigationBarFadeInWithPercentage
40
+            fadeInAnimation = self.navigationBarFadeIn
41
+            fadeOutAnimation = self.navigationBarFadeOut
42
+        } else {
37 43
             return
38 44
         }
45
+        
46
+        percentageAnimation(percentage)
47
+        
48
+        guard gesture.state == .ended else { return }
49
+
50
+        for vc in navigationController?.viewControllers ?? [] { print(vc) }
51
+        if (percentage > 0.5 && navigationController == nil) ||
52
+            (percentage < 0.5 && navigationController?.visibleViewController == self) {
53
+            fadeOutAnimation()
54
+        } else if (percentage < 0.5 && navigationController == nil) ||
55
+            (percentage > 0.5 && navigationController?.visibleViewController == self) {
56
+            fadeInAnimation()
57
+        }
39 58
     }
40 59
     
41
-    func calculatePercentageOfOffsets(point: CGPoint) -> CGFloat {
60
+    private func calculatePercentageOfOffsets(point: CGPoint) -> CGFloat {
42 61
         return point.x / view.bounds.width
43 62
     }
44 63
 }

+ 1 - 1
PaiAi/PaiaiUIKit/Reusable/UIKit/NavigationBar/NavigationBarInteractiveViewController.swift

@@ -8,5 +8,5 @@
8 8
 
9 9
 import Foundation
10 10
 
11
-typealias NavigationBarInteractiveViewController = NavigationBarDelegate & NavigationBarInteractivePopDeletegate & NavigationBarPushAndPopDelegate & NavigationBarInOut & NavigationControllerDelegate
11
+public typealias NavigationBarInteractiveViewController = NavigationBarInteractivePopDeletegate & NavigationBarPushAndPopDelegate & NavigationBarInOutAnimator & NavigationControllerDelegate
12 12
 

+ 24 - 5
PaiAi/PaiaiUIKit/Reusable/UIKit/NavigationBar/NavigationBarPushAndPopDelegate.swift

@@ -10,21 +10,40 @@ import Foundation
10 10
 
11 11
 public protocol NavigationBarPushAndPopDelegate: class {
12 12
     func setupNavigationBarPushAndPopDelegate()
13
+    func setNavigationBar()
13 14
 }
14 15
 
15 16
 public extension NavigationBarPushAndPopDelegate where Self: UIViewController & NavigationControllerDelegate {
16 17
     func setupNavigationBarPushAndPopDelegate() {
17 18
         navigationController?.setDelegate(self)
18 19
     }
20
+    
21
+    func setNavigationBar() {}
19 22
 }
20 23
 
21
-public extension NavigationControllerDelegate where Self: UIViewController & NavigationBarInOut {
24
+public extension NavigationControllerDelegate where Self: UIViewController {
25
+    
22 26
     func navigationController(_ navigationController: UINavigationController,
23
-                              willShow viewController: UIViewController, animated: Bool) {
24
-        if viewController != self {
25
-            navigationBarFadeIn()
27
+                              animationControllerFor operation: UINavigationController.Operation,
28
+                              from fromVC: UIViewController,
29
+                              to toVC: UIViewController) -> UIViewControllerAnimatedTransitioning? {
30
+        
31
+        if operation == .push {
32
+            (toVC as? NavigationBarInOutAnimator)?.navigationBarFadeAndMoveIn()
33
+            (fromVC as? NavigationBarInOutAnimator)?.navigationBarFadeOut()
26 34
         } else {
27
-            navigationBarFadeOut()
35
+            (toVC as? NavigationBarInOutAnimator)?.navigationBarFadeIn()
36
+            (fromVC as? NavigationBarInOutAnimator)?.navigationBarFadeAndMoveOut()
28 37
         }
38
+        
39
+        return nil
40
+    }
41
+    
42
+    func navigationController(_ navigationController: UINavigationController,
43
+                              didShow viewController: UIViewController, animated: Bool) {
44
+        guard let recognizer = navigationController.interactivePopGestureRecognizer else { return }
45
+        recognizer.isEnabled = true
46
+        guard let vc = viewController as? GestureRecognizerDelegate else { return }
47
+        recognizer.setDelegate(vc)
29 48
     }
30 49
 }

+ 3 - 2
PaiAi/PaiaiUIKit/Reusable/UIKit/PageViewController/PageViewController.swift

@@ -72,7 +72,8 @@ open class PageViewController: UIViewController {
72 72
         constructViewHierarchy()
73 73
         activateConstraints()
74 74
         setMenuGestureRecognizer()
75
-        setupNavigationBarDelegate()
75
+        setupNavigationBarPushAndPopDelegate()
76
+        setupNavigationBarInteractivePopDelegate()
76 77
     }
77 78
     
78 79
     open override func viewDidLayoutSubviews() {
@@ -367,7 +368,7 @@ fileprivate extension PageViewController {
367 368
     }
368 369
 }
369 370
 
370
-extension PageViewController: NavigationBarInteractiveViewController {
371
+extension PageViewController: NavigationBarInteractiveViewController {    
371 372
     public var navigationView: UIView {
372 373
         return menuView
373 374
     }

+ 1 - 1
PaiAi/PaiaiUIKit/Reusable/UIKitDelegate/GestureRecognizerDelegate/GestureRecognizerProxy.swift

@@ -37,7 +37,7 @@ extension UIGestureRecognizer {
37 37
         set { objc_setAssociatedObject(self, &AssociatedKeys.proxyKey, newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC) }
38 38
     }
39 39
     
40
-    func setDelegate<T: GestureRecognizerDelegate>(_ target: T) {
40
+    func setDelegate(_ target: GestureRecognizerDelegate) {
41 41
         proxy = GestureRecognizerProxy(target: target)
42 42
         delegate = proxy
43 43
     }

+ 19 - 0
PaiAi/PaiaiUIKit/Reusable/UIKitDelegate/NavigationBarDelegate/NavigationBarDelegate.swift

@@ -0,0 +1,19 @@
1
+//
2
+//  NavigationBarDelegate.swift
3
+//  PaiaiUIKit
4
+//
5
+//  Created by ffib on 2019/1/30.
6
+//  Copyright © 2019 yb. All rights reserved.
7
+//
8
+
9
+import Foundation
10
+
11
+public protocol NavigationBarDelegate: class {
12
+    func navigationBar(_ navigationBar: UINavigationBar, shouldPush item: UINavigationItem) -> Bool
13
+}
14
+
15
+public extension NavigationBarDelegate {
16
+    func navigationBar(_ navigationBar: UINavigationBar, shouldPush item: UINavigationItem) -> Bool {
17
+         return true
18
+    }
19
+}

+ 38 - 0
PaiAi/PaiaiUIKit/Reusable/UIKitDelegate/NavigationBarDelegate/NavigationBarProxy.swift

@@ -0,0 +1,38 @@
1
+//
2
+//  NavigationBarProxy.swift
3
+//  PaiaiUIKit
4
+//
5
+//  Created by ffib on 2019/1/30.
6
+//  Copyright © 2019 yb. All rights reserved.
7
+//
8
+
9
+import UIKit
10
+
11
+class NavigationBarProxy: NSObject, UINavigationBarDelegate {
12
+    weak var delegate: NavigationBarDelegate?
13
+
14
+    init(target: NavigationBarDelegate) {
15
+        delegate = target
16
+    }
17
+    
18
+    func navigationBar(_ navigationBar: UINavigationBar, shouldPush item: UINavigationItem) -> Bool {
19
+        guard let d = delegate else { return true }
20
+        return d.navigationBar(navigationBar, shouldPush: item)
21
+    }
22
+}
23
+
24
+extension UINavigationBar {
25
+    private struct AssociatedKeys {
26
+        static var proxyKey = "NavigationBarProxyKey"
27
+    }
28
+    
29
+    private var proxy: NavigationBarProxy? {
30
+        get { return objc_getAssociatedObject(self, &AssociatedKeys.proxyKey) as? NavigationBarProxy }
31
+        set { objc_setAssociatedObject(self, &AssociatedKeys.proxyKey, newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC) }
32
+    }
33
+    
34
+    func setDelegate<T: NavigationBarDelegate>(_ target: T) {
35
+        proxy = NavigationBarProxy(target: target)
36
+        delegate = proxy
37
+    }
38
+}

+ 23 - 0
PaiAi/PaiaiUIKit/Reusable/UIKitDelegate/NavigationControllerDelegate/NavigationControllerDelegate.swift

@@ -11,4 +11,27 @@ import Foundation
11 11
 public protocol NavigationControllerDelegate: class {
12 12
     func navigationController(_ navigationController: UINavigationController,
13 13
                               willShow viewController: UIViewController, animated: Bool)
14
+    
15
+    func navigationController(_ navigationController: UINavigationController,
16
+                              didShow viewController: UIViewController, animated: Bool)
17
+    
18
+    func navigationController(_ navigationController: UINavigationController,
19
+                              animationControllerFor operation: UINavigationController.Operation,
20
+                              from fromVC: UIViewController,
21
+                              to toVC: UIViewController) -> UIViewControllerAnimatedTransitioning?
22
+}
23
+
24
+public extension NavigationControllerDelegate {
25
+    
26
+    func navigationController(_ navigationController: UINavigationController,
27
+                              willShow viewController: UIViewController, animated: Bool) {}
28
+    
29
+    func navigationController(_ navigationController: UINavigationController, didShow viewController: UIViewController, animated: Bool) {}
30
+    
31
+    func navigationController(_ navigationController: UINavigationController,
32
+                              animationControllerFor operation: UINavigationController.Operation,
33
+                              from fromVC: UIViewController,
34
+                              to toVC: UIViewController) -> UIViewControllerAnimatedTransitioning? {
35
+        return nil
36
+    }
14 37
 }

+ 14 - 2
PaiAi/PaiaiUIKit/Reusable/UIKitDelegate/NavigationControllerDelegate/NavigationControllerProxy.swift

@@ -15,9 +15,21 @@ class NavigationControllerProxy: NSObject, UINavigationControllerDelegate {
15 15
         delegate = target
16 16
     }
17 17
     
18
+    func navigationController(_ navigationController: UINavigationController, willShow viewController: UIViewController, animated: Bool) {
19
+        delegate?.navigationController(navigationController, willShow: viewController, animated: true)
20
+    }
21
+    
22
+    func navigationController(_ navigationController: UINavigationController, didShow viewController: UIViewController, animated: Bool) {
23
+        delegate?.navigationController(navigationController, didShow: viewController, animated: true)
24
+    }
25
+    
18 26
     func navigationController(_ navigationController: UINavigationController,
19
-                              willShow viewController: UIViewController, animated: Bool) {
20
-        delegate?.navigationController(navigationController, willShow: viewController, animated: animated)
27
+                              animationControllerFor operation: UINavigationController.Operation,
28
+                              from fromVC: UIViewController,
29
+                              to toVC: UIViewController) -> UIViewControllerAnimatedTransitioning? {
30
+        return delegate?.navigationController(navigationController,
31
+                                              animationControllerFor: operation,
32
+                                              from: fromVC, to: toVC)
21 33
     }
22 34
 }
23 35
 

+ 1 - 1
PaiAi/PaiaiUIKit/Reusable/UIKitDelegate/ViewControllerTransitioningDelegate/ViewControllerTransitioningDelegate.swift

@@ -8,7 +8,7 @@
8 8
 
9 9
 import Foundation
10 10
 
11
-public protocol ViewControllerTransitioningDelegate where Self: UIViewController {
11
+public protocol ViewControllerTransitioningDelegate: class {
12 12
     func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning?
13 13
     
14 14
     func animationController(forPresented presented: UIViewController,

+ 1 - 1
PaiAi/PaiaiUIKit/Reusable/UIKitDelegate/ViewControllerTransitioningDelegate/ViewControllerTransitioningProxy.swift

@@ -9,7 +9,7 @@
9 9
 import Foundation
10 10
 
11 11
 class ViewControllerTransitioningProxy: NSObject, UIViewControllerTransitioningDelegate {
12
-    var delegate: ViewControllerTransitioningDelegate?
12
+    weak var delegate: ViewControllerTransitioningDelegate?
13 13
     
14 14
     init(target: ViewControllerTransitioningDelegate) {
15 15
         delegate = target

+ 3 - 1
PaiAi/Paiai_iOS/App/AppCoordinator.swift

@@ -46,7 +46,9 @@ public final class AppCoordinator {
46 46
                                                       viewController: messageVC)]
47 47
         
48 48
         let homeCoordinator = HomeCoordinator(homeVC, userInfoViewModel: shareUserInfoViewModel)
49
-        let messageCoordinator = MessageCoordinator(messageVC, userInfoViewModel: shareUserInfoViewModel)
49
+        let messageCoordinator = MessageCoordinator(messageVC,
50
+                                                    navigationController: navigationController,
51
+                                                    userInfoViewModel: shareUserInfoViewModel)
50 52
         
51 53
         coordinators[.home] = homeCoordinator
52 54
         coordinators[.message] = messageCoordinator

+ 24 - 0
PaiAi/Paiai_iOS/App/Group/GroupCoordinator.swift

@@ -0,0 +1,24 @@
1
+//
2
+//  GroupCoordinator.swift
3
+//  Paiai_iOS
4
+//
5
+//  Created by ffib on 2019/1/29.
6
+//  Copyright © 2019 yb. All rights reserved.
7
+//
8
+
9
+import Foundation
10
+
11
+class GroupCoordinator: Coordinator {
12
+    
13
+    var navigationController: UINavigationController
14
+    
15
+    init(navigationController: UINavigationController) {
16
+        self.navigationController = navigationController
17
+    }
18
+}
19
+
20
+extension UIStoryboard {
21
+    static var group: UIStoryboard {
22
+        return UIStoryboard(name: "Group", bundle: Bundle(identifier: "com.Paiai-iOS"))
23
+    }
24
+}

PaiAi/Paiai_iOS/App/GroupDetail/ChangeGroupNameController.swift → PaiAi/Paiai_iOS/App/Group/GroupDetail/ChangeGroupNameController.swift


PaiAi/Paiai_iOS/App/GroupDetail/GroupDetail.storyboard → PaiAi/Paiai_iOS/App/Group/GroupDetail/GroupDetail.storyboard


PaiAi/Paiai_iOS/App/GroupDetail/GroupDetailController.swift → PaiAi/Paiai_iOS/App/Group/GroupDetail/GroupDetailController.swift


PaiAi/Paiai_iOS/App/GroupDetail/GroupDetailCoordinator.swift → PaiAi/Paiai_iOS/App/Group/GroupDetail/GroupDetailCoordinator.swift


PaiAi/Paiai_iOS/App/GroupDetail/GroupMebersController.swift → PaiAi/Paiai_iOS/App/Group/GroupDetail/GroupMebersController.swift


PaiAi/Paiai_iOS/App/GroupDetail/GroupMemberController.swift → PaiAi/Paiai_iOS/App/Group/GroupDetail/GroupMemberController.swift


PaiAi/Paiai_iOS/App/GroupDetail/MemberCell.swift → PaiAi/Paiai_iOS/App/Group/GroupDetail/MemberCell.swift


PaiAi/Paiai_iOS/App/GroupDetail/ShowGroupQRController.swift → PaiAi/Paiai_iOS/App/Group/GroupDetail/ShowGroupQRController.swift


+ 252 - 0
PaiAi/Paiai_iOS/App/Group/GroupViewController.swift

@@ -0,0 +1,252 @@
1
+//
2
+//  GroupViewController.swift
3
+//  PaiAi
4
+//
5
+//  Created by zhengjianfei on 16/3/28.
6
+//  Copyright © 2016年 FFIB. All rights reserved.
7
+//
8
+
9
+import UIKit
10
+import RxSwift
11
+import RxCocoa
12
+import RxDataSources
13
+import PaiaiUIKit
14
+import PaiaiDataKit
15
+import PullToRefresh
16
+
17
+final class GroupViewController: UIViewController {
18
+
19
+    // MARK: Storyboard property
20
+    @IBOutlet var collectionView: UICollectionView!
21
+    @IBOutlet weak var photographBtn: UIButton!
22
+
23
+    // MARK: custom UI property
24
+    var navigationBarView: UIView = {
25
+        let view = UIView()
26
+        view.alpha = 0
27
+        
28
+        return view
29
+    }()
30
+    
31
+    var navigationBarViewTitle: UILabel = {
32
+        let label = UILabel()
33
+        label.textColor = UIColor.white
34
+        
35
+        return label
36
+    }()
37
+    
38
+    var navigationBarViewImage: UIImageView = {
39
+        let image = UIImageView()
40
+        image.cornerRadius = 20
41
+        return image
42
+    }()
43
+    
44
+    // MARK: data property
45
+    var viewModel: GroupViewModel!
46
+    var groupItem: GroupItem!
47
+    
48
+    fileprivate var navigationViewNotReady = true
49
+    fileprivate let disposeBag = DisposeBag()
50
+    
51
+    override func viewDidLoad() {
52
+        super.viewDidLoad()
53
+        initalize()
54
+    }
55
+    
56
+    func initalize() {
57
+        collectionView.register(UINib(nibName: "PhotoCell",
58
+                                      bundle: Bundle(identifier: "com.Paiai-iOS")),
59
+                                forCellWithReuseIdentifier: "photoCell")
60
+        setup()
61
+        binding()
62
+    }
63
+    
64
+    private func setup() {
65
+        setupReloadControl()
66
+    }
67
+    
68
+    private func setupReloadControl() {
69
+        collectionView.addPullToRefresh(PullToRefresh()) {
70
+            [unowned self] in
71
+            self.viewModel.reload()
72
+        }
73
+    }
74
+}
75
+
76
+/// UI bindings
77
+fileprivate extension GroupViewController {
78
+    
79
+    var dataSource: RxCollectionViewSectionedAnimatedDataSource<AnimatableSectionModel<Int, PhotoItem>> {
80
+        return RxCollectionViewSectionedAnimatedDataSource<AnimatableSectionModel<Int, PhotoItem>>(configureCell:
81
+            { (dataSource, collectionView, indexPath, item) -> UICollectionViewCell in
82
+                let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "photoCell", for: indexPath) as! PhotoCell
83
+                cell.setInfo(item, source: .group)
84
+                return cell
85
+        })
86
+    }
87
+    
88
+    func binding() {
89
+        bindInteraction()
90
+        bindViewModelToRefreshing()
91
+        bindCollectionViewDelegate()
92
+        bindViewModelToCollectionView()
93
+        bindCollectionViewToViewModel()
94
+        bindViewModelToNavigationBarImage()
95
+        bindViewModelToNavigationBarTitle()
96
+    }
97
+    
98
+    func bindInteraction() {
99
+        photographBtn.rx.tap.bind(to: viewModel.photographBtnTapped).disposed(by: disposeBag)
100
+    }
101
+    
102
+    func bindViewModelToRefreshing() {
103
+        viewModel.isLoading
104
+            .subscribe(onNext: {[unowned self] flag in
105
+                self.collectionView.endRefreshing(at: .top)
106
+            }).disposed(by: disposeBag)
107
+    }
108
+    
109
+    func bindCollectionViewDelegate() {
110
+        collectionView.rx.setDelegate(self).disposed(by: disposeBag)
111
+    }
112
+    
113
+    func bindViewModelToCollectionView() {
114
+        viewModel.contents
115
+            .bind(to: collectionView.rx.items(dataSource: dataSource))
116
+            .disposed(by: disposeBag)
117
+    }
118
+    
119
+    func bindCollectionViewToViewModel() {
120
+        collectionView.rx.modelSelected(PhotoItem.self)
121
+            .asDriver()
122
+            .drive(onNext: { [unowned self] in self.viewModel.didSelect($0) })
123
+            .disposed(by: disposeBag)
124
+    }
125
+    
126
+    func bindViewModelToNavigationBarTitle() {
127
+        navigationBarViewTitle.text = groupItem.group_name
128
+    }
129
+    
130
+    func bindViewModelToNavigationBarImage() {
131
+        navigationBarViewImage.setImage(groupItem.group_avatar,
132
+                                        placeholder: UIImage(named: "Group\(groupItem.group_default_avatar)"))
133
+    }
134
+}
135
+
136
+extension GroupViewController: NavigationBarInteractiveViewController {
137
+    var navigationView: UIView {
138
+        return navigationBarView
139
+    }
140
+    
141
+    func setNavigationBar() {
142
+        guard navigationViewNotReady else { return }
143
+        setRightBarButtonItems()
144
+        construvtNaivgationViewHierarchy()
145
+        activateConstraintsNavigation()
146
+        
147
+        navigationViewNotReady = false
148
+    }
149
+    
150
+    private func construvtNaivgationViewHierarchy() {
151
+        navigationController?.navigationBar.addSubview(navigationBarView)
152
+        navigationBarView.addSubview(navigationBarViewImage)
153
+        navigationBarView.addSubview(navigationBarViewTitle)
154
+    }
155
+    
156
+    private func setRightBarButtonItems() {
157
+        let item = UIBarButtonItem(images: [UIImage(named: "navigation-QR"),
158
+                                            UIImage(named: "navigation-right")],
159
+                                   btnSpace: 6,
160
+                                   target: self,
161
+                                   actions: [#selector(viewModel!.presentGroupQR),
162
+                                             #selector(viewModel!.navigateToGroupDetail)])
163
+        navigationItem.rightBarButtonItem = item
164
+    }
165
+}
166
+
167
+/// layout
168
+fileprivate extension GroupViewController {
169
+    
170
+    func activateConstraintsNavigation() {
171
+        activateConstraintsNavigationBarView()
172
+        activateConstraintsNavigationBarViewImage()
173
+        activateConstraintsNavigationBarViewTitle()
174
+    }
175
+    
176
+    func activateConstraintsNavigationBarView() {
177
+        guard let barContentView = navigationController?.navigationBar else {  return }
178
+        
179
+        navigationBarView.translatesAutoresizingMaskIntoConstraints = false
180
+        
181
+        NSLayoutConstraint.activate([
182
+            navigationBarView.topAnchor.constraint(equalTo: barContentView.topAnchor),
183
+            navigationBarView.bottomAnchor.constraint(equalTo: barContentView.bottomAnchor),
184
+            navigationBarView.centerXAnchor.constraint(equalTo: barContentView.centerXAnchor)
185
+            ])
186
+    }
187
+    
188
+    func activateConstraintsNavigationBarViewTitle() {
189
+        navigationBarViewTitle.translatesAutoresizingMaskIntoConstraints = false
190
+        NSLayoutConstraint.activate([
191
+            navigationBarViewTitle.centerYAnchor.constraint(equalTo: navigationBarView.centerYAnchor),
192
+            navigationBarViewTitle.leadingAnchor.constraint(equalTo: navigationBarViewImage.trailingAnchor, constant: 6),
193
+            navigationBarViewTitle.trailingAnchor.constraint(equalTo: navigationBarView.trailingAnchor),
194
+            navigationBarViewTitle.widthAnchor.constraint(lessThanOrEqualToConstant: view.width - 200)
195
+            ])
196
+    }
197
+    
198
+    func activateConstraintsNavigationBarViewImage() {
199
+        navigationBarViewImage.translatesAutoresizingMaskIntoConstraints = false
200
+        
201
+        NSLayoutConstraint.activate([
202
+            navigationBarViewImage.widthAnchor.constraint(equalToConstant: 40),
203
+            navigationBarViewImage.heightAnchor.constraint(equalToConstant: 40),
204
+            navigationBarViewImage.centerYAnchor.constraint(equalTo: navigationBarView.centerYAnchor),
205
+            navigationBarViewImage.leadingAnchor.constraint(equalTo: navigationBarView.leadingAnchor),
206
+            ])
207
+    }
208
+}
209
+
210
+extension GroupViewController: UICollectionViewDelegateFlowLayout {
211
+    func collectionView(_ collectionView: UICollectionView,
212
+                        layout collectionViewLayout: UICollectionViewLayout,
213
+                        sizeForItemAt indexPath: IndexPath) -> CGSize {
214
+        return viewModel.layoutSizeForIndexPath(indexPath)
215
+    }
216
+}
217
+
218
+/// MARK: imagepicker delegate
219
+extension GroupViewController: UIImagePickerControllerDelegate, UINavigationControllerDelegate {
220
+
221
+    @IBAction func takePhotoAction() {
222
+        let vc = UIImagePickerController()
223
+        #if (arch(i386) || arch(x86_64))
224
+            vc.sourceType = .photoLibrary
225
+        #else
226
+            vc.sourceType = .camera
227
+        #endif
228
+        vc.delegate = self
229
+        present(vc, animated: true, completion: nil)
230
+    }
231
+
232
+    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
233
+        dismiss(animated: true, completion: nil)
234
+        
235
+        guard let image = info[.originalImage] as? UIImage else { return }
236
+        
237
+        viewModel.submit(image: image)
238
+    }
239
+    
240
+    func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
241
+        dismiss(animated: true, completion: nil)
242
+    }
243
+}
244
+
245
+extension GroupViewController: NavigationBackViewController {}
246
+
247
+extension GroupViewController: Storyboarded {
248
+    static func instantiate() -> GroupViewController {
249
+        let vc = UIStoryboard.group.instantiateController(GroupViewController.self)
250
+        return vc
251
+    }
252
+}

+ 1 - 1
PaiAi/Paiai_iOS/App/Home/CreateGroupConfirmViewController.swift

@@ -54,7 +54,7 @@ final class CreateGroupConfirmViewController: AlertViewController {
54 54
 //    }
55 55
 
56 56
 //    func confirmAndJump() {
57
-//        let ctl = UIStoryboard.main.instantiateController(GroupPageController.self)
57
+//        let ctl = UIStoryboard.main.instantiateController(GroupViewController.self)
58 58
 //        ctl.groupModel = group
59 59
 //        ctl.isCreate = true
60 60
 //        guard let parentController = presentingViewController as? UINavigationController else {

+ 0 - 140
PaiAi/Paiai_iOS/App/Home/Group/GroupPageController.swift

@@ -1,140 +0,0 @@
1
-//
2
-//  GroupPageController.swift
3
-//  PaiAi
4
-//
5
-//  Created by zhengjianfei on 16/3/28.
6
-//  Copyright © 2016年 FFIB. All rights reserved.
7
-//
8
-
9
-import UIKit
10
-import RxSwift
11
-import RxCocoa
12
-import RxDataSources
13
-import PaiaiUIKit
14
-import PaiaiDataKit
15
-
16
-final class GroupPageController: UIViewController {
17
-
18
-    // MARK: Storyboard property
19
-    @IBOutlet var collectionView: UICollectionView!
20
-    @IBOutlet weak var photographLabel: UILabel!
21
-    @IBOutlet weak var photographBtn: UIButton!
22
-
23
-    // MARK: custom UI property
24
-    var maskImageView = UIImageView()
25
-    var maskLabel = UILabel()
26
-
27
-    // MARK: data property
28
-    var viewModel: GroupPageViewModel!
29
-    fileprivate let disposeBag = DisposeBag()
30
-    
31
-    // MARK: view function
32
-    override func viewDidLoad() {
33
-        super.viewDidLoad()
34
-        
35
-        collectionView.register(UINib(nibName: "PhotoCell", bundle: nil),
36
-                                forCellWithReuseIdentifier: "photoCell")
37
-        
38
-        configurationRx()
39
-        
40
-        addReloadControl()
41
-    }
42
-
43
-    override func viewWillAppear(_ animated: Bool) {
44
-        super.viewWillAppear(true)
45
-        makeNavigationBar()
46
-    }
47
-
48
-    // MARK: init interface
49
-    func makeNavigationBar() {
50
-//        navigationItem.setRightBars(buttonSpace: 0,
51
-//                                    images: [UIImage(named: "二维码"), UIImage(named: "更多-右上角-1")],
52
-//                                    actions: [#selector(showEWM), #selector(pushToGroupDetailController)],
53
-//                                    target: self)
54
-//        titleWithbackBar = ""
55
-//        let barView = UIView(frame: CGRect(x: 0, y: 0, width: kScreenWidth - 150, height: 40))
56
-//        let label = UILabel()
57
-////        label.text = groupModel.group_name
58
-//        label.textColor = UIColor.white
59
-//        let labelWidth = min(label.sizeThatFits(CGSize(width: kScreenWidth - 200, height: 40)).width, kScreenWidth - 200)
60
-//        let imageView = UIImageView(frame: CGRect(x: 0, y: 2, width: 40, height: 40))
61
-//        imageView.center = CGPoint(x: barView.center.x - labelWidth / 2, y: barView.center.y)
62
-////        imageView.setImageWithNullableURL(groupModel.group_avatar, placeholderImage: UIImage(named: "Group\(groupModel.group_default_avatar)"))
63
-//        imageView.cornerRadius = 20
64
-//        label.frame = CGRect(x: 40 + imageView.x + 5, y: 2, width: kScreenWidth - 200, height: 40)
65
-//        barView.addSubViews([imageView, label])
66
-//        navigationItem.titleView = barView
67
-    }
68
-    
69
-    var dataSource: RxCollectionViewSectionedAnimatedDataSource<AnimatableSectionModel<Int, PhotoItem>> {
70
-        return RxCollectionViewSectionedAnimatedDataSource<AnimatableSectionModel<Int, PhotoItem>>(configureCell: { (dataSource, collectionView, indexPath, item) -> UICollectionViewCell in
71
-            let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "photoCell", for: indexPath) as! PhotoCell
72
-            cell.setInfo(item, source: .group)
73
-            return cell
74
-        })
75
-    }
76
-
77
-    func configurationRx() {
78
-        
79
-        collectionView.rx.setDelegate(self).disposed(by: disposeBag)
80
-        
81
-//        viewModel.isReload.subscribe(onNext: {
82
-//            [weak self] _ in
83
-//            guard let `self` = self else { return }
84
-//            self.collectionView.es.stopPullToRefresh()
85
-//        }).disposed(by: disposeBag)
86
-        
87
-        viewModel.groupPhotoContents
88
-            .bind(to: collectionView.rx.items(dataSource: dataSource))
89
-            .disposed(by: disposeBag)
90
-        
91
-        collectionView.rx.modelSelected(PhotoItem.self)
92
-            .subscribe(onNext: { [unowned self] in self.viewModel.didSelect($0) })
93
-            .disposed(by: disposeBag)
94
-        
95
-        collectionView.collectionViewLayout = WaterfallFlowLayout()
96
-    }
97
-    
98
-    func addReloadControl() {
99
-//        collectionView.es.addPullToRefresh {
100
-//            [unowned self] in
101
-//            self.viewModel.reload()
102
-//        }
103
-//        collectionView.es.startPullToRefresh()
104
-    }
105
-}
106
-
107
-extension GroupPageController: UICollectionViewDelegateFlowLayout {
108
-
109
-    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
110
-        return viewModel.layoutSizeForIndexPath(indexPath)
111
-    }
112
-}
113
-
114
-// MARK: imagepicker delegate
115
-extension GroupPageController: UIImagePickerControllerDelegate, UINavigationControllerDelegate {
116
-
117
-    @IBAction func takePhotoAction() {
118
-        let vc = UIImagePickerController()
119
-        #if (arch(i386) || arch(x86_64))
120
-            vc.sourceType = .photoLibrary
121
-        #else
122
-            vc.sourceType = .camera
123
-        #endif
124
-        vc.delegate = self
125
-        present(vc, animated: true, completion: nil)
126
-    }
127
-
128
-    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
129
-        dismiss(animated: true, completion: nil)
130
-        
131
-        guard let image = info[.originalImage] as? UIImage else { return }
132
-        
133
-        viewModel.submit(image: image)
134
-    }
135
-    
136
-    func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
137
-        dismiss(animated: true, completion: nil)
138
-    }
139
-
140
-}

+ 0 - 1
PaiAi/Paiai_iOS/App/Home/HomeViewController.swift

@@ -21,7 +21,6 @@ final class HomeViewController: UIViewController {
21 21
     @IBOutlet weak var collectionView: UICollectionView!
22 22
     // MARK: data property
23 23
     fileprivate let disposeBag = DisposeBag()
24
-    fileprivate let refresher = PullToRefresh()
25 24
     
26 25
     internal var viewModel: HomeViewModel!
27 26
     internal var userInfoViewModel: UserInfoViewModel!

+ 0 - 76
PaiAi/Paiai_iOS/App/Home/Main.storyboard

@@ -158,80 +158,6 @@
158 158
             </objects>
159 159
             <point key="canvasLocation" x="1705" y="-152"/>
160 160
         </scene>
161
-        <!--GroupPageController-->
162
-        <scene sceneID="ntn-JA-tbk">
163
-            <objects>
164
-                <viewController storyboardIdentifier="GroupPageController" automaticallyAdjustsScrollViewInsets="NO" id="R29-hC-gNv" userLabel="GroupPageController" customClass="GroupPageController" customModule="PaiAi" sceneMemberID="viewController">
165
-                    <view key="view" contentMode="scaleToFill" id="ljL-8h-aZ0">
166
-                        <rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
167
-                        <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
168
-                        <subviews>
169
-                            <collectionView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" showsHorizontalScrollIndicator="NO" dataMode="prototypes" translatesAutoresizingMaskIntoConstraints="NO" id="lAJ-ZU-GPi">
170
-                                <rect key="frame" x="6" y="25" width="363" height="642"/>
171
-                                <color key="backgroundColor" red="0.8784313725490196" green="0.8784313725490196" blue="0.8784313725490196" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
172
-                                <collectionViewLayout key="collectionViewLayout" id="D17-J3-rSa" customClass="WaterfallFlowLayout" customModule="Paiai_iOS" customModuleProvider="target"/>
173
-                                <cells/>
174
-                                <connections>
175
-                                    <outlet property="delegate" destination="R29-hC-gNv" id="XgJ-WA-ub2"/>
176
-                                </connections>
177
-                            </collectionView>
178
-                            <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="lOt-ls-oe7">
179
-                                <rect key="frame" x="199" y="493" width="168" height="168"/>
180
-                                <state key="normal" image="BTN-拍照"/>
181
-                                <state key="selected" image="BTN-拍照-press"/>
182
-                                <connections>
183
-                                    <action selector="takePhotoAction" destination="R29-hC-gNv" eventType="touchUpInside" id="YIr-6E-LS2"/>
184
-                                </connections>
185
-                            </button>
186
-                            <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="6Ai-Cd-a0J">
187
-                                <rect key="frame" x="199" y="525" width="168" height="168"/>
188
-                                <state key="normal" image="BTN-扫码"/>
189
-                                <state key="selected" image="BTN-扫码-press"/>
190
-                            </button>
191
-                            <label hidden="YES" opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="点我,拍摄照片" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="zdv-Nb-P68">
192
-                                <rect key="frame" x="72.5" y="567" width="121.5" height="20.5"/>
193
-                                <fontDescription key="fontDescription" type="system" pointSize="17"/>
194
-                                <color key="textColor" red="0.1960784314" green="0.1960784314" blue="0.1960784314" alpha="1" colorSpace="calibratedRGB"/>
195
-                                <nil key="highlightedColor"/>
196
-                            </label>
197
-                            <view hidden="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="88M-NH-Qgh" customClass="FFProgress" customModule="Paiai_iOS" customModuleProvider="target">
198
-                                <rect key="frame" x="162.5" y="308.5" width="50" height="50"/>
199
-                                <color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
200
-                                <constraints>
201
-                                    <constraint firstAttribute="height" constant="50" id="6A3-02-EsP"/>
202
-                                    <constraint firstAttribute="width" constant="50" id="g6l-6C-4jG"/>
203
-                                </constraints>
204
-                            </view>
205
-                        </subviews>
206
-                        <color key="backgroundColor" red="0.8784313725490196" green="0.8784313725490196" blue="0.8784313725490196" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
207
-                        <constraints>
208
-                            <constraint firstItem="efW-A4-fyT" firstAttribute="bottom" secondItem="lAJ-ZU-GPi" secondAttribute="bottom" id="23G-aq-F9a"/>
209
-                            <constraint firstItem="efW-A4-fyT" firstAttribute="bottom" secondItem="lOt-ls-oe7" secondAttribute="bottom" constant="6" id="2ff-CO-xJk"/>
210
-                            <constraint firstItem="lOt-ls-oe7" firstAttribute="leading" secondItem="zdv-Nb-P68" secondAttribute="trailing" constant="5" id="3cy-f1-xck"/>
211
-                            <constraint firstItem="6Ai-Cd-a0J" firstAttribute="centerX" secondItem="lOt-ls-oe7" secondAttribute="centerX" id="9rZ-z1-OKI"/>
212
-                            <constraint firstItem="lOt-ls-oe7" firstAttribute="top" secondItem="6Ai-Cd-a0J" secondAttribute="bottom" constant="-200" id="Chs-ne-dS2"/>
213
-                            <constraint firstItem="88M-NH-Qgh" firstAttribute="centerX" secondItem="efW-A4-fyT" secondAttribute="centerX" id="IRY-CY-KnW"/>
214
-                            <constraint firstItem="efW-A4-fyT" firstAttribute="trailing" secondItem="lOt-ls-oe7" secondAttribute="trailing" constant="8" id="IUI-dd-MNf"/>
215
-                            <constraint firstItem="lAJ-ZU-GPi" firstAttribute="leading" secondItem="efW-A4-fyT" secondAttribute="leading" constant="6" id="TN2-dq-Bfm"/>
216
-                            <constraint firstItem="zdv-Nb-P68" firstAttribute="centerY" secondItem="lOt-ls-oe7" secondAttribute="centerY" id="Tkh-kV-puR"/>
217
-                            <constraint firstItem="efW-A4-fyT" firstAttribute="trailing" secondItem="lAJ-ZU-GPi" secondAttribute="trailing" constant="6" id="j5S-4o-gNP"/>
218
-                            <constraint firstItem="88M-NH-Qgh" firstAttribute="centerY" secondItem="ljL-8h-aZ0" secondAttribute="centerY" id="qMc-hm-LSD"/>
219
-                            <constraint firstItem="lAJ-ZU-GPi" firstAttribute="top" secondItem="efW-A4-fyT" secondAttribute="top" constant="5" id="tdF-Kt-yAO"/>
220
-                        </constraints>
221
-                        <viewLayoutGuide key="safeArea" id="efW-A4-fyT"/>
222
-                    </view>
223
-                    <navigationItem key="navigationItem" id="aeg-ac-MGk"/>
224
-                    <connections>
225
-                        <outlet property="collectionView" destination="lAJ-ZU-GPi" id="MGB-rX-4dB"/>
226
-                        <outlet property="photographBtn" destination="lOt-ls-oe7" id="ynl-na-505"/>
227
-                        <outlet property="photographLabel" destination="zdv-Nb-P68" id="NJO-Ae-y4X"/>
228
-                        <outlet property="progressView" destination="88M-NH-Qgh" id="2bw-7m-FfB"/>
229
-                    </connections>
230
-                </viewController>
231
-                <placeholder placeholderIdentifier="IBFirstResponder" id="Wws-ea-mVh" sceneMemberID="firstResponder"/>
232
-            </objects>
233
-            <point key="canvasLocation" x="700" y="57.121439280359823"/>
234
-        </scene>
235 161
         <!--CreateGroupViewController-->
236 162
         <scene sceneID="AAe-LB-J2k">
237 163
             <objects>
@@ -556,8 +482,6 @@
556 482
     <resources>
557 483
         <image name="BTN-扫码" width="168" height="168"/>
558 484
         <image name="BTN-扫码-press" width="168" height="168"/>
559
-        <image name="BTN-拍照" width="168" height="168"/>
560
-        <image name="BTN-拍照-press" width="168" height="168"/>
561 485
         <image name="BTN-新增" width="168" height="168"/>
562 486
         <image name="BTN-新增-press" width="168" height="168"/>
563 487
         <image name="guide1" width="1462" height="2600"/>

+ 2 - 2
PaiAi/Paiai_iOS/App/Home/ScanQRViewController.swift

@@ -63,7 +63,7 @@ extension ScanQRViewController: QRCodeScanViewDelegate {
63 63
 
64 64
 //            let request = GroupNetworkRequest(path: .joinTourGroup, parameter: params)
65 65
 //            NetworkApi.share.post(request: request, handler: { (res) in
66
-//                let ctl = UIStoryboard.main.instantiateController(GroupPageController.self)
66
+//                let ctl = UIStoryboard.main.instantiateController(GroupViewController.self)
67 67
 //                ctl.isCreate = true
68 68
 //                ctl.isScan = true
69 69
 //                ctl.groupModel = res[0]
@@ -101,7 +101,7 @@ extension ScanQRViewController: QRCodeScanViewDelegate {
101 101
 
102 102
 //        let request = GroupNetworkRequest(path: path, parameter: params)
103 103
 //        NetworkApi.share.post(request: request, handler: { (res) in
104
-//            let ctl = UIStoryboard.main.instantiateController(GroupPageController.self)
104
+//            let ctl = UIStoryboard.main.instantiateController(GroupViewController.self)
105 105
 //            ctl.isCreate = true
106 106
 //            ctl.isScan = true
107 107
 //            ctl.groupModel = res[0]

+ 6 - 2
PaiAi/Paiai_iOS/App/Message/MessageCoordinator.swift

@@ -11,10 +11,14 @@ import PaiaiDataKit
11 11
 
12 12
 class MessageCoordinator: Coordinator {
13 13
     let messageViewController: MessageViewController
14
+    let navigationController: UINavigationController
14 15
     var shareUserInfoViewModel: UserInfoViewModel
15 16
     
16
-    init(_ messageVC: MessageViewController, userInfoViewModel: UserInfoViewModel) {
17
+    init(_ messageVC: MessageViewController,
18
+         navigationController: UINavigationController,
19
+         userInfoViewModel: UserInfoViewModel) {
17 20
         messageViewController = messageVC
21
+        self.navigationController = navigationController
18 22
         shareUserInfoViewModel = userInfoViewModel
19 23
         messageViewController.viewModel.delegate = self
20 24
     }
@@ -33,7 +37,7 @@ extension MessageCoordinator {
33 37
 extension MessageCoordinator: MessageViewModelDelegate {
34 38
     func didSelect(type: MessageType) {
35 39
         let messageListVC = makeMessageListViewContorller(type: type)
36
-        messageViewController.pushViewController(messageListVC)
40
+        navigationController.pushViewController(messageListVC)
37 41
     }
38 42
 }
39 43
 

+ 2 - 2
PaiAi/Paiai_iOS/App/Mine/MineAboutViewController.swift

@@ -46,7 +46,7 @@ fileprivate extension MineAboutViewController {
46 46
             .subscribe { (_) in
47 47
                 let webVC = WebViewController(title: "联系我们",
48 48
                                               path: "https://pai.ai/page/contact_us")
49
-                self.pushViewController(webVC)
49
+                self.navigationController?.pushViewController(webVC)
50 50
             }.disposed(by: disposeBag)
51 51
     }
52 52
     
@@ -67,7 +67,7 @@ fileprivate extension MineAboutViewController {
67 67
             .subscribe { (_) in
68 68
                 let webVC = WebViewController(title: "用户协议",
69 69
                                               path: "https://pai.ai/page/user_agreement")
70
-                self.pushViewController(webVC)
70
+                self.navigationController?.pushViewController(webVC)
71 71
             }.disposed(by: disposeBag)
72 72
     }
73 73
 }

+ 25 - 7
PaiAi/Paiai_iOS/App/Mine/MineCoordinator.swift

@@ -14,9 +14,10 @@ class MineCoordinator: Coordinator {
14 14
     
15 15
     let mineViewController: MineViewController
16 16
     let navigationController: UINavigationController
17
+    var childCoordinator = [String: Coordinator]()
17 18
 //    let shareUserInfoViewModel
18 19
     
19
-    init(_ mineViewController: MineViewController, containerViewController: UINavigationController) {
20
+    init(_ mineViewController: MineViewController, navigationController: UINavigationController) {
20 21
         self.mineViewController = mineViewController
21 22
         self.navigationController = navigationController
22 23
         self.mineViewController.delegate = self
@@ -30,7 +31,7 @@ class MineCoordinator: Coordinator {
30 31
 extension MineCoordinator: MineViewControllerDelegate {
31 32
     func logout() {
32 33
         let vc = makeLoginViewController()
33
-        containerViewController.presentController(vc)
34
+        navigationController.presentController(vc)
34 35
     }
35 36
     
36 37
     func didSelect(_ item: MineItem) {
@@ -39,17 +40,17 @@ extension MineCoordinator: MineViewControllerDelegate {
39 40
         switch item {
40 41
         case .group:
41 42
             let vc = makeMineGroupViewController()
42
-            navigationController
43
-            containerViewController.pushViewController(vc)
43
+            vc.viewModel.delegate = self
44
+            navigationController.pushViewController(vc)
44 45
         case .order:
45 46
             let vc = makeMineOrderViewController()
46
-            containerViewController.pushViewController(vc)
47
+            navigationController.pushViewController(vc)
47 48
         case .feedback:
48 49
             let vc = makeMineFeedbackViewController()
49
-            containerViewController.pushViewController(vc)
50
+            navigationController.pushViewController(vc)
50 51
         case .about:
51 52
             let vc = makeMineAboutViewController()
52
-            containerViewController.pushViewController(vc)
53
+            navigationController.pushViewController(vc)
53 54
         }
54 55
     }
55 56
     
@@ -57,6 +58,16 @@ extension MineCoordinator: MineViewControllerDelegate {
57 58
     }
58 59
 }
59 60
 
61
+extension MineCoordinator: MineGroupViewModelDelegate {
62
+    func didSelect(_ item: GroupItem) {
63
+        let vc = makeGroupViewController(item: item)
64
+        let coordinator = GroupCoordinator(navigationController: navigationController)
65
+        childCoordinator["group"] = coordinator
66
+        
67
+        navigationController.pushViewController(vc)
68
+    }
69
+}
70
+
60 71
 fileprivate extension MineCoordinator {
61 72
     func makeLoginViewController() -> LoginViewController {
62 73
         let vc = UIStoryboard.main.instantiateController(LoginViewController.self)
@@ -86,6 +97,13 @@ fileprivate extension MineCoordinator {
86 97
         let vc = UIStoryboard.mine.instantiateController(MineAboutViewController.self)
87 98
         return vc
88 99
     }
100
+    
101
+    func makeGroupViewController(item: GroupItem) -> GroupViewController {
102
+        let vc = GroupViewController.instantiate()
103
+        vc.viewModel = GroupViewModel(groupItem: item)
104
+        vc.groupItem = item
105
+        return vc
106
+    }
89 107
 }
90 108
 
91 109
 extension UIStoryboard {

+ 1 - 1
PaiAi/Paiai_iOS/App/Mine/MineFeedbackViewController.swift

@@ -32,7 +32,7 @@ final class MineFeedbackViewController: UIViewController {
32 32
     @IBAction func sendFeedBack() {
33 33
         feedbackAPI.submit(text: textView.text).subscribe(onCompleted: {[weak self] in
34 34
             guard let `self` = self else { return }
35
-            self.popController()
35
+            self.navigationController?.popViewController(animated: true)
36 36
             Toast.show(message: "感谢您的建议")
37 37
         }) { (error) in
38 38
             

+ 2 - 2
PaiAi/Paiai_iOS/App/PhotoDetail/DetailPageController.swift

@@ -65,7 +65,7 @@ final class DetailPageController: UIViewController {
65 65
 ////            last.mainViewModel.models.value = datas
66 66
 //        }
67 67
 //
68
-//        if let last = navigationController?.viewControllers[(navigationController?.viewControllers.count)! - 1] as? GroupPageController {
68
+//        if let last = navigationController?.viewControllers[(navigationController?.viewControllers.count)! - 1] as? GroupViewController {
69 69
 ////            last.MineGroupViewModel.models.value = datas
70 70
 //        }
71 71
 //    }
@@ -287,7 +287,7 @@ extension DetailPageController: CellDelegate {
287 287
     }
288 288
 
289 289
     func pushNext() {
290
-        let ctl = UIStoryboard.main.instantiateController(GroupPageController.self)
290
+        let ctl = UIStoryboard.main.instantiateController(GroupViewController.self)
291 291
 
292 292
 //        ctl.groupModel = GroupModel(map: Map(mappingType: .fromJSON, JSON: datas[currentPhotoIndex].toJSON()))
293 293
         show(ctl, sender: nil)

kodo - Gogs: Go Git Service

暂无描述

storage_utils.py 4.3KB

    # -*- coding: utf-8 -*- import os import shortuuid from django.conf import settings from django.core.files.storage import default_storage from django.db import transaction from django_file_md5 import calculate_md5 from photo.models import PhotoUUIDInfo from utils.thumbnail_utils import make_thumbnail from utils.watermark_utils import watermark_wrap class DotDict(dict): """ dot.notation access to dictionary attributes """ def __getattr__(self, attr): return self.get(attr) __setattr__ = dict.__setitem__ __delattr__ = dict.__delitem__ @transaction.atomic def file_save(file_=None, file_path=None, prefix='img', ext='.jpeg', watermark=False, thumbnail=False): # Photo file_ = file_ or default_storage.open(file_path) # Ext ext = os.path.splitext(file_.name)[-1] or ext # Photo MD5 photo_md5 = calculate_md5(file_) # Photo UUID Get or Create photo, created = PhotoUUIDInfo.objects.select_for_update().get_or_create(photo_md5=photo_md5) # 无水印 if not photo.photo_path: photo_path = '{}/{}{}'.format(prefix, shortuuid.uuid(), ext) if default_storage.exists(photo_path): default_storage.delete(photo_path) default_storage.save(photo_path, file_) photo.photo_path = photo_path photo.save() # 有水印 if watermark: if not photo.photo_watermark_path: if settings.WATERMARK_OR_NOT: photo_watermark_path = 'photo/{}{}'.format(shortuuid.uuid(), ext) watermark_wrap( os.path.join(settings.MEDIA_ROOT, photo_path).replace('\\', '/'), settings.WATERMARK_LOGO_PATH, os.path.join(settings.MEDIA_ROOT, photo_watermark_path).replace('\\', '/') ) photo.photo_watermark_path = photo_watermark_path else: photo.photo_watermark_path = photo_path photo.save() # 缩略图 if thumbnail: if not photo.photo_thumbnail_path: # 双列: 540, 40-50K photo_thumbnail_path = photo_path.replace('.', '_thumbnail.') photo_w, photo_h, photo_thumbnail_w, photo_thumbnail_h = make_thumbnail( os.path.join(settings.MEDIA_ROOT, photo_path).replace('\\', '/'), os.path.join(settings.MEDIA_ROOT, photo_thumbnail_path).replace('\\', '/'), settings.THUMBNAIL_MAX_WIDTH ) photo.photo_w = photo_w photo.photo_h = photo_h photo.photo_thumbnail_path = photo_thumbnail_path photo.photo_thumbnail_w = photo_thumbnail_w photo.photo_thumbnail_h = photo_thumbnail_h if not photo.photo_thumbnail2_path: # 单列: 1080, xx-100K photo_thumbnail2_path = photo_path.replace('.', '_thumbnail2.') photo_w, photo_h, photo_thumbnail2_w, photo_thumbnail2_h = make_thumbnail( os.path.join(settings.MEDIA_ROOT, photo_path).replace('\\', '/'), os.path.join(settings.MEDIA_ROOT, photo_thumbnail2_path).replace('\\', '/'), settings.THUMBNAIL_MAX_WIDTH2 ) if watermark and settings.WATERMARK_OR_NOT: watermark_wrap( os.path.join(settings.MEDIA_ROOT, photo_thumbnail2_path).replace('\\', '/'), settings.WATERMARK_LOGO_PATH, os.path.join(settings.MEDIA_ROOT, photo_thumbnail2_path).replace('\\', '/') ) photo.photo_w = photo_w photo.photo_h = photo_h photo.photo_thumbnail2_path = photo_thumbnail2_path photo.photo_thumbnail2_w = photo_thumbnail2_w photo.photo_thumbnail2_h = photo_thumbnail2_h photo.save() return DotDict({ 'ext': ext, 'photo_md5': photo_md5, 'photo_path': photo.photo_path, 'photo_w': photo.photo_w, 'photo_h': photo.photo_h, 'photo_watermark_path': photo.photo_watermark_path, 'photo_thumbnail_path': photo.photo_thumbnail_path, 'photo_thumbnail_w': photo.photo_thumbnail_w, 'photo_thumbnail_h': photo.photo_thumbnail_h, 'photo_thumbnail2_path': photo.photo_thumbnail2_path, 'photo_thumbnail2_w': photo.photo_thumbnail2_w, 'photo_thumbnail2_h': photo.photo_thumbnail2_h, })
kodo - Gogs: Go Git Service

Brak opisu

sale_views.py 20KB

    # -*- coding: utf-8 -*- from __future__ import division from django.conf import settings from django.db import transaction from django_logit import logit from django_response import response from paginator import pagination from TimeConvert import TimeConvert as tc from account.models import UserInfo from coupon.models import UserCouponInfo from integral.models import SaleclerkIntegralIncomeExpensesInfo, SaleclerkSubmitLogInfo from logs.models import MchInfoEncryptLogInfo from mch.models import (BrandInfo, ConsumeInfoSubmitLogInfo, DistributorInfo, MaintenancemanInfo, ModelInfo, SaleclerkInfo) from member.models import RightInfo from statistic.models import (DistributorSaleStatisticInfo, ModelSaleStatisticInfo, ProvinceSaleStatisticInfo, SaleclerkSaleStatisticInfo, SaleStatisticInfo) from utils.error.errno_utils import (CouponStatusCode, ProductBrandStatusCode, ProductDistributorStatusCode, ProductMachineStatusCode, ProductModelStatusCode, SaleclerkStatusCode) @logit @transaction.atomic def clerk_sale_submit_api(request): user_id = request.POST.get('user_id', '') iv = request.POST.get('iv', '') encryptedData = request.POST.get('encryptedData', '') lat = request.POST.get('lat', .0) lon = request.POST.get('lon', .0) brandID = request.POST.get('BrandID', settings.KODO_DEFAULT_BRAND_PK) modelID = request.POST.get('ModelID', '') distributorID = request.POST.get('DistributorID', '') serialNo = request.POST.get('SerialNo', '') verifyResult = request.POST.get('verifyResult', '') remark = request.POST.get('remark', '') is_wxwork = request.POST.get('is_wxwork', False) consumer_name = request.POST.get('consumer_name', '') consumer_phone = request.POST.get('consumer_phone', '') file_path = request.POST.get('file_path', '') code_image_path = request.POST.get('code_image_path', '') trackingNo = request.POST.get('trackingNo', '') code_version = request.POST.get('code_version', 0) test_sn = serialNo in settings.TESTING_SNS if lat == 'undefined': lat = .0 if lon == 'undefined': lon = .0 try: user = UserInfo.objects.get(user_id=user_id, status=True) except UserInfo.DoesNotExist: return response(SaleclerkStatusCode.CLERK_NOT_FOUND) try: brand = BrandInfo.objects.get(pk=brandID) except BrandInfo.DoesNotExist: brand = None except ValueError: brand = None if not brand: try: brand = BrandInfo.objects.get(brand_id=brandID) except BrandInfo.DoesNotExist: return response(ProductBrandStatusCode.BRAND_NOT_FOUND) try: model = ModelInfo.objects.get(pk=modelID) except ModelInfo.DoesNotExist: return response(ProductModelStatusCode.MODEL_NOT_FOUND) except ValueError: return response(ProductModelStatusCode.MODEL_NOT_FOUND) try: clerk = SaleclerkInfo.objects.select_for_update().get(brand_id=brand.brand_id, clerk_phone=user.phone, status=True) except SaleclerkInfo.DoesNotExist: return response(SaleclerkStatusCode.CLERK_NOT_FOUND) if not clerk.is_auth: return response(SaleclerkStatusCode.CLERK_NOT_AUTH) try: distributor = DistributorInfo.objects.get(distributor_id=clerk.distributor_id) except DistributorInfo.DoesNotExist: return response(ProductDistributorStatusCode.DISTRIBUTOR_NOT_FOUND) except ValueError: return response(ProductDistributorStatusCode.DISTRIBUTOR_NOT_FOUND) ymd = tc.local_string(format='%Y%m%d') # 是否被消费者扫过 has_scan = ConsumeInfoSubmitLogInfo.objects.filter(model_id=model.model_id, serialNo=serialNo, status=True).exists() # 是否是新二维码,即统览码2 if not code_version: code_version = 1 code = filter(lambda ch: ch in '0123456789', serialNo) encrypt_logs = MchInfoEncryptLogInfo.objects.filter(model_pk=model.pk, sn=code) if encrypt_logs: code_version = encrypt_logs[0].version # 店员提交记录 ssli = SaleclerkSubmitLogInfo.objects.create( brand_pk=brand.pk, brand_name=brand.brand_name, model_pk=modelID, model_name=model.model_name, model_uni_name=model.model_uni_name, distributor_pk=distributorID, distributor_id=distributor.distributor_id, distributor_name=distributor.distributor_name, clerk_id=clerk.clerk_id, clerk_name=clerk.clerk_name, code=serialNo, consumer_name=consumer_name, consumer_phone=consumer_phone, remark=remark, lat=lat, lon=lon, image=file_path, code_image=code_image_path, test_user=clerk.test_user, test_sn=test_sn, ym=ymd[:6], ymd=ymd, has_scan=has_scan, trackingNo=trackingNo, is_wxwork=is_wxwork, code_version=code_version, ) if test_sn: return response(200, data={ 'integral': 0, 'total_integral': clerk.integral, }) try: sci = SaleclerkIntegralIncomeExpensesInfo.objects.get( brand_id=brand.brand_id, model_id=model.model_id, code=serialNo, status=True ) except SaleclerkIntegralIncomeExpensesInfo.DoesNotExist: sci = None if sci: ssli.dupload = True ssli.save() try: clerk = SaleclerkInfo.objects.get(clerk_id=sci.clerk_id, status=True) except SaleclerkInfo.DoesNotExist: clerk = None return response(SaleclerkStatusCode.DUPLICATE_SUBMIT, data={ 'franchiser_name': clerk.distributor_name, 'clerk_name': clerk.clerk_name, } if clerk else {}) # 店员积分 integral = model.integral clerk.num += 1 clerk.integral += integral clerk.total_integral += integral clerk.save() # 店员积分记录 if integral > 0: SaleclerkIntegralIncomeExpensesInfo.objects.create( clerk_id=clerk.clerk_id, type=SaleclerkIntegralIncomeExpensesInfo.INCOME, brand_id=brand.brand_id, brand_name=brand.brand_name, model_id=model.model_id, model_name=model.model_name, distributor_id=distributor.distributor_id, distributor_name=distributor.distributor_name, code=serialNo, consumer_name=consumer_name, consumer_phone=consumer_phone, lat=lat, lon=lon, image=file_path, integral=integral, left_integral=clerk.total_integral, test_user=clerk.test_user, ) # TODO: Make statistic async if not clerk.test_user and not sci: # 日销量统计 ssi, _ = SaleStatisticInfo.objects.select_for_update().get_or_create( brand_id=brand.brand_id, ymd=ymd, ) ssi.num += 1 ssi.save() # 月销量统计 ssi, _ = SaleStatisticInfo.objects.select_for_update().get_or_create( brand_id=brand.brand_id, ymd=ymd[:6], ) ssi.num += 1 ssi.save() # 年销量统计 ssi, _ = SaleStatisticInfo.objects.select_for_update().get_or_create( brand_id=brand.brand_id, ymd=ymd[:4], ) ssi.num += 1 ssi.save() # 型号销量统计 mssi, _ = ModelSaleStatisticInfo.objects.select_for_update().get_or_create( brand_id=brand.brand_id, model_name=model.model_uni_name, ymd=ymd, ) mssi.saleclerks += [clerk.clerk_id] mssi.num = len(mssi.saleclerks) mssi.save() mssi, _ = ModelSaleStatisticInfo.objects.select_for_update().get_or_create( brand_id=brand.brand_id, model_name=model.model_uni_name, ymd=ymd[:6], ) mssi.saleclerks += [clerk.clerk_id] mssi.num = len(mssi.saleclerks) mssi.save() mssi, _ = ModelSaleStatisticInfo.objects.select_for_update().get_or_create( brand_id=brand.brand_id, model_name=model.model_uni_name, ymd=ymd[:4], ) mssi.saleclerks += [clerk.clerk_id] mssi.num = len(mssi.saleclerks) mssi.save() # 经销商销量统计 dssi, _ = DistributorSaleStatisticInfo.objects.select_for_update().get_or_create( brand_id=brand.brand_id, distributor_id=distributor.distributor_id, ymd=ymd, ) dssi.distributor_name = distributor.distributor_name dssi.num += 1 dssi.save() dssi2, _ = DistributorSaleStatisticInfo.objects.select_for_update().get_or_create( brand_id=brand.brand_id, distributor_id=distributor.distributor_id, ymd=0, ) dssi2.distributor_name = distributor.distributor_name dssi2.num += 1 dssi2.save() # 日省份销量统计 pssi, _ = ProvinceSaleStatisticInfo.objects.select_for_update().get_or_create( brand_id=brand.brand_id, province_code=distributor.distributor_province_code, ymd=ymd, ) pssi.province_name = distributor.distributor_province_name pssi.num += 1 pssi.save() # 月省份销量统计 pssi, _ = ProvinceSaleStatisticInfo.objects.select_for_update().get_or_create( brand_id=brand.brand_id, province_code=distributor.distributor_province_code, ymd=ymd[:6], ) pssi.province_name = distributor.distributor_province_name pssi.num += 1 pssi.save() # 年省份销量统计 pssi, _ = ProvinceSaleStatisticInfo.objects.select_for_update().get_or_create( brand_id=brand.brand_id, province_code=distributor.distributor_province_code, ymd=ymd[:4], ) pssi.province_name = distributor.distributor_province_name pssi.num += 1 pssi.save() # 日销售员销量统计 sssi, _ = SaleclerkSaleStatisticInfo.objects.select_for_update().get_or_create( brand_id=brand.brand_id, clerk_id=clerk.clerk_id, ymd=ymd, ) sssi.distributor_id = distributor.distributor_id sssi.distributor_name = distributor.distributor_name sssi.distributor_short_name = distributor.distributor_short_name sssi.clerk_name = clerk.clerk_name sssi.num += 1 sssi.save() # 月销售员销量统计 sssi, _ = SaleclerkSaleStatisticInfo.objects.select_for_update().get_or_create( brand_id=brand.brand_id, clerk_id=clerk.clerk_id, ymd=ymd[:6], ) sssi.distributor_id = distributor.distributor_id sssi.distributor_name = distributor.distributor_name sssi.distributor_short_name = distributor.distributor_short_name sssi.clerk_name = clerk.clerk_name sssi.num += 1 sssi.save() # 年销售员销量统计 sssi, _ = SaleclerkSaleStatisticInfo.objects.select_for_update().get_or_create( brand_id=brand.brand_id, clerk_id=clerk.clerk_id, ymd=ymd[:4], ) sssi.distributor_id = distributor.distributor_id sssi.distributor_name = distributor.distributor_name sssi.distributor_short_name = distributor.distributor_short_name sssi.clerk_name = clerk.clerk_name sssi.num += 1 sssi.save() return response(200, data={ 'integral': integral, 'total_integral': clerk.integral, }) @logit def clerk_integral_list_api(request): brandID = request.POST.get('BrandID', settings.KODO_DEFAULT_BRAND_PK) user_id = request.POST.get('user_id', '') ftime = request.POST.get('ftime', '') ttime = request.POST.get('ttime', '') page = int(request.POST.get('page', 1)) num = int(request.POST.get('num', settings.GROUP_NUM_PER_PAGE)) try: user = UserInfo.objects.get(user_id=user_id, status=True) except UserInfo.DoesNotExist: return response(SaleclerkStatusCode.CLERK_NOT_FOUND) try: brand = BrandInfo.objects.get(pk=brandID) except BrandInfo.DoesNotExist: brand = None except ValueError: brand = None if not brand: try: brand = BrandInfo.objects.get(brand_id=brandID) except BrandInfo.DoesNotExist: return response(ProductBrandStatusCode.BRAND_NOT_FOUND) try: clerk = SaleclerkInfo.objects.get(brand_id=brand.brand_id, clerk_phone=user.phone, status=True) except SaleclerkInfo.DoesNotExist: return response(SaleclerkStatusCode.CLERK_NOT_FOUND) integrals = SaleclerkIntegralIncomeExpensesInfo.objects.filter(clerk_id=clerk.clerk_id).order_by('-pk') if ftime: integrals = integrals.filter(created_at__gte=tc.string_to_utc_datetime(ftime)) if ttime: integrals = integrals.filter(created_at__lte=tc.string_to_utc_datetime(ttime)) integrals, left = pagination(integrals, page, num) integrals = [integral.data for integral in integrals] return response(200, data={ 'integrals': integrals, 'total_integral': clerk.integral, 'left_integral': clerk.integral, }) @logit def clerk_model_list_api(request): brandID = request.POST.get('brand_id', settings.KODO_DEFAULT_BRAND_PK) user_id = request.POST.get('user_id', '') try: user = UserInfo.objects.get(user_id=user_id, status=True) except UserInfo.DoesNotExist: return response(SaleclerkStatusCode.CLERK_NOT_FOUND) try: brand = BrandInfo.objects.get(pk=brandID) except BrandInfo.DoesNotExist: brand = None except ValueError: brand = None if not brand: try: brand = BrandInfo.objects.get(brand_id=brandID) except BrandInfo.DoesNotExist: return response(ProductBrandStatusCode.BRAND_NOT_FOUND) try: clerk = SaleclerkInfo.objects.get(brand_id=brand.brand_id, clerk_phone=user.phone, status=True) except SaleclerkInfo.DoesNotExist: return response(SaleclerkStatusCode.CLERK_NOT_FOUND) models = ModelInfo.objects.filter(status=True).order_by('position') models = [model.data for model in models] return response(200, data={ 'models': models, }) @logit def clerk_query_coupon(request): brandID = request.POST.get('brand_id', settings.KODO_DEFAULT_BRAND_PK) user_id = request.POST.get('user_id', '') user_coupon_id = request.POST.get('user_coupon_id', '') is_maintenance = int(request.POST.get('is_maintenance', 0)) try: user = UserInfo.objects.get(user_id=user_id, status=True) except UserInfo.DoesNotExist: return response(SaleclerkStatusCode.CLERK_NOT_FOUND) try: brand = BrandInfo.objects.get(pk=brandID) except BrandInfo.DoesNotExist: brand = None except ValueError: brand = None if not brand: try: brand = BrandInfo.objects.get(brand_id=brandID) except BrandInfo.DoesNotExist: return response(ProductBrandStatusCode.BRAND_NOT_FOUND) try: user_coupon = UserCouponInfo.objects.get(user_coupon_id=user_coupon_id) except UserCouponInfo.DoesNotExist: return response(CouponStatusCode.COUPON_NOT_FOUND) right_detail = '' if is_maintenance: try: maintenance = MaintenancemanInfo.objects.get(brand_id=brand.brand_id, user_id=user.user_id, status=True) except MaintenancemanInfo.DoesNotExist: return response(400001, 'MaintenancemanInfo Not Found', u'维修员不存在') # 维修人工费 try: right = RightInfo.objects.get(right_id='X457xEV8KVxHQiTvhA7Dtf') except RightInfo.DoesNotExist: return response(400001, 'MaintenancemanInfo Not Found', u'维修员不存在') try: member = UserInfo.objects.get(user_id=user_coupon.user_id) except UserInfo.DoesNotExist: return response(400001, 'MaintenancemanInfo Not Found', u'维修员不存在') right_detail = right.maintaindata(level=member.level) else: try: clerk = SaleclerkInfo.objects.get(brand_id=brand.brand_id, clerk_phone=user.phone, status=True) except SaleclerkInfo.DoesNotExist: return response(SaleclerkStatusCode.CLERK_NOT_FOUND) return response(200, data={ 'user_coupon': user_coupon.data, 'right': right_detail }) @logit def clerk_writeoff_coupon(request): brandID = request.POST.get('brand_id', settings.KODO_DEFAULT_BRAND_PK) user_id = request.POST.get('user_id', '') user_coupon_id = request.POST.get('user_coupon_id', '') is_maintenance = int(request.POST.get('is_maintenance', 0)) try: user = UserInfo.objects.get(user_id=user_id, status=True) except UserInfo.DoesNotExist: return response(SaleclerkStatusCode.CLERK_NOT_FOUND) try: brand = BrandInfo.objects.get(pk=brandID) except BrandInfo.DoesNotExist: brand = None except ValueError: brand = None if not brand: try: brand = BrandInfo.objects.get(brand_id=brandID) except BrandInfo.DoesNotExist: return response(ProductBrandStatusCode.BRAND_NOT_FOUND) try: user_coupon = UserCouponInfo.objects.get(user_coupon_id=user_coupon_id) except UserCouponInfo.DoesNotExist: return response(CouponStatusCode.COUPON_NOT_FOUND) if user_coupon.has_used: return response(CouponStatusCode.COUPON_HAS_USED) elif user_coupon.is_coupon_admin_writeoff and not is_maintenance: return response(CouponStatusCode.COUPON_PERMISSION_DENIED) elif user_coupon.has_expired: return response(CouponStatusCode.COUPON_EXPIRED) user_coupon.has_used = True user_coupon.used_at = tc.utc_datetime() if is_maintenance: try: maintenance = MaintenancemanInfo.objects.get(brand_id=brand.brand_id, user_id=user.user_id, status=True) except MaintenancemanInfo.DoesNotExist: return response(400001, 'MaintenancemanInfo Not Found', u'维修员不存在') user_coupon.admin_id = maintenance.maintenance_id user_coupon.admin_name = maintenance.maintenance_name user_coupon.save() else: try: clerk = SaleclerkInfo.objects.get(brand_id=brand.brand_id, clerk_phone=user.phone, status=True) except SaleclerkInfo.DoesNotExist: return response(SaleclerkStatusCode.CLERK_NOT_FOUND) user_coupon.clerk_id = clerk.clerk_id user_coupon.clerk_name = clerk.clerk_name user_coupon.distributor_id = clerk.distributor_id user_coupon.distributor_name = clerk.distributor_name user_coupon.save() return response(200, 'Write Off Coupon Success', u'劵核销成功') @logit def clerk_checkout_serialNo_api(request): brandID = request.POST.get('brand_id', settings.KODO_DEFAULT_BRAND_PK) user_id = request.POST.get('user_id', '') serialNo = request.POST.get('serial', '') model_pk = request.POST.get('model_pk', '') try: user = UserInfo.objects.get(user_id=user_id, status=True) except UserInfo.DoesNotExist: return response(SaleclerkStatusCode.CLERK_NOT_FOUND) try: brand = BrandInfo.objects.get(pk=brandID) except BrandInfo.DoesNotExist: brand = None except ValueError: brand = None if not brand: try: brand = BrandInfo.objects.get(brand_id=brandID) except BrandInfo.DoesNotExist: return response(ProductBrandStatusCode.BRAND_NOT_FOUND) try: clerk = SaleclerkInfo.objects.get(brand_id=brand.brand_id, clerk_phone=user.phone, status=True) except SaleclerkInfo.DoesNotExist: return response(SaleclerkStatusCode.CLERK_NOT_FOUND) log = MchInfoEncryptLogInfo.objects.filter(model_pk=model_pk, sn=serialNo).order_by('-pk') if not log: return response(ProductMachineStatusCode.SN_NOT_FOUND) return response(200, 'SerialNo Checkout Success', u'序列号校验成功', data={ 'code_version': log[0].version })