From: liangzhenying <867174124@qq.com>
Date: Fri, 6 Feb 2026 10:44:18 +0000 (+0800)
Subject: 运动功能开发
X-Git-Tag: 1.0.4~10
X-Git-Url: http://git.snicker.com.cn/Users/apple/Desktop/static/gitweb.css?a=commitdiff_plain;h=083f9d1d957c1a31f1a75cc7f93da7633e2b3637;p=mirrors%2FShenYin.git
运动功能开发
---
diff --git a/DeepChordsSdk_iOS/DeepChordsSdk/Example/Example.xcodeproj/project.pbxproj b/DeepChordsSdk_iOS/DeepChordsSdk/Example/Example.xcodeproj/project.pbxproj
index f73584e..b99cdee 100644
--- a/DeepChordsSdk_iOS/DeepChordsSdk/Example/Example.xcodeproj/project.pbxproj
+++ b/DeepChordsSdk_iOS/DeepChordsSdk/Example/Example.xcodeproj/project.pbxproj
@@ -267,7 +267,9 @@
);
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = Example/Info.plist;
+ INFOPLIST_KEY_CFBundleDisplayName = "éª¨ä¼ å¯¼sdk";
INFOPLIST_KEY_NSBluetoothAlwaysUsageDescription = "使ç¨èçå¦";
+ INFOPLIST_KEY_NSMicrophoneUsageDescription = "使ç¨éº¦å
é£å¦";
INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen;
INFOPLIST_KEY_UIMainStoryboardFile = Main;
@@ -318,7 +320,7 @@
"\"UIKit\"",
"-ObjC",
);
- PRODUCT_BUNDLE_IDENTIFIER = deepchords.guchuandao.Example;
+ PRODUCT_BUNDLE_IDENTIFIER = deepchords.ai.Example;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_OBJC_BRIDGING_HEADER = "Example/VC/Example-Bridging-Header.h";
@@ -348,7 +350,9 @@
);
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = Example/Info.plist;
+ INFOPLIST_KEY_CFBundleDisplayName = "éª¨ä¼ å¯¼sdk";
INFOPLIST_KEY_NSBluetoothAlwaysUsageDescription = "使ç¨èçå¦";
+ INFOPLIST_KEY_NSMicrophoneUsageDescription = "使ç¨éº¦å
é£å¦";
INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen;
INFOPLIST_KEY_UIMainStoryboardFile = Main;
@@ -399,7 +403,7 @@
"\"UIKit\"",
"-ObjC",
);
- PRODUCT_BUNDLE_IDENTIFIER = deepchords.guchuandao.Example;
+ PRODUCT_BUNDLE_IDENTIFIER = deepchords.ai.Example;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_OBJC_BRIDGING_HEADER = "Example/VC/Example-Bridging-Header.h";
diff --git a/DeepChordsSdk_iOS/DeepChordsSdk/Example/Example/Info.plist b/DeepChordsSdk_iOS/DeepChordsSdk/Example/Example/Info.plist
index b571c8d..c0ae0b4 100644
--- a/DeepChordsSdk_iOS/DeepChordsSdk/Example/Example/Info.plist
+++ b/DeepChordsSdk_iOS/DeepChordsSdk/Example/Example/Info.plist
@@ -2,6 +2,11 @@
+ NSAppTransportSecurity
+
+ NSAllowsArbitraryLoads
+
+
UIApplicationSceneManifest
UIApplicationSupportsMultipleScenes
@@ -21,14 +26,5 @@
- NSAppTransportSecurity
-
- NSAllowsArbitraryLoads
-
-
- CFBundleDisplayName
- éª¨ä¼ å¯¼sdk
- NSMicrophoneUsageDescription
- 使ç¨éº¦å
é£å¦
diff --git a/ShenYin/ShenYin.xcodeproj/project.pbxproj b/ShenYin/ShenYin.xcodeproj/project.pbxproj
index a9c06e7..9de0b86 100644
--- a/ShenYin/ShenYin.xcodeproj/project.pbxproj
+++ b/ShenYin/ShenYin.xcodeproj/project.pbxproj
@@ -484,6 +484,10 @@
UI/Sleep/SleepVM.swift,
UI/Sport/MusicRootView.swift,
UI/Sport/RecordRootView.swift,
+ UI/Sport/Sport/Light/BrightnessView.swift,
+ UI/Sport/Sport/Light/LightSetVC.swift,
+ UI/Sport/Sport/Light/ModeView.swift,
+ UI/Sport/Sport/Light/StateView.swift,
UI/Sport/Sport/Ready/CountdownView.swift,
UI/Sport/Sport/Ready/CustomMapView.swift,
UI/Sport/Sport/Ready/FooterView.swift,
@@ -499,6 +503,15 @@
UI/Sport/Sport/Set/SportSetCell.swift,
UI/Sport/Sport/Set/SportSetModel.swift,
UI/Sport/Sport/Set/SportSetVC.swift,
+ UI/Sport/Sport/SportDetail/SportDetailBoard.swift,
+ UI/Sport/Sport/SportDetail/SportDetailVC.swift,
+ UI/Sport/Sport/Sporting/DetailBoard.swift,
+ UI/Sport/Sport/Sporting/SimpleBoard.swift,
+ UI/Sport/Sport/Sporting/SportingVC.swift,
+ UI/Sport/Sport/Target/CalorieView.swift,
+ UI/Sport/Sport/Target/DistanceView.swift,
+ UI/Sport/Sport/Target/DurationView.swift,
+ UI/Sport/Sport/Target/SportTargetVC.swift,
UI/Sport/Sport/Tools/MapManager.swift,
UI/Sport/SportHomeVC.swift,
UI/Sport/TranslateRootView.swift,
@@ -576,6 +589,10 @@
Sdk/JoySdk/VC/ModeVC.swift,
UI/Sport/MusicRootView.swift,
UI/Sport/RecordRootView.swift,
+ UI/Sport/Sport/Light/BrightnessView.swift,
+ UI/Sport/Sport/Light/LightSetVC.swift,
+ UI/Sport/Sport/Light/ModeView.swift,
+ UI/Sport/Sport/Light/StateView.swift,
UI/Sport/Sport/Ready/CountdownView.swift,
UI/Sport/Sport/Ready/CustomMapView.swift,
UI/Sport/Sport/Ready/FooterView.swift,
@@ -591,6 +608,15 @@
UI/Sport/Sport/Set/SportSetCell.swift,
UI/Sport/Sport/Set/SportSetModel.swift,
UI/Sport/Sport/Set/SportSetVC.swift,
+ UI/Sport/Sport/SportDetail/SportDetailBoard.swift,
+ UI/Sport/Sport/SportDetail/SportDetailVC.swift,
+ UI/Sport/Sport/Sporting/DetailBoard.swift,
+ UI/Sport/Sport/Sporting/SimpleBoard.swift,
+ UI/Sport/Sport/Sporting/SportingVC.swift,
+ UI/Sport/Sport/Target/CalorieView.swift,
+ UI/Sport/Sport/Target/DistanceView.swift,
+ UI/Sport/Sport/Target/DurationView.swift,
+ UI/Sport/Sport/Target/SportTargetVC.swift,
UI/Sport/Sport/Tools/MapManager.swift,
UI/Sport/SportHomeVC.swift,
UI/Sport/TranslateRootView.swift,
diff --git a/ShenYin/ShenYin/Api/HttpClient.swift b/ShenYin/ShenYin/Api/HttpClient.swift
index 1187a97..c611c63 100644
--- a/ShenYin/ShenYin/Api/HttpClient.swift
+++ b/ShenYin/ShenYin/Api/HttpClient.swift
@@ -54,6 +54,8 @@ enum CommomApi
case updatePhone(param:[String:Any])
/// æ´æ°é®ç®±
case updateEmail(param:[String:Any])
+ /// è·åç¨æ·ä¿¡æ¯
+ case getUserInfo
/// æ´æ°ç¨æ·ä¿¡æ¯
case updateUserInfo(param:[String:Any])
/// è·åç¨æ·åå¨ç©ºé´
@@ -124,6 +126,13 @@ enum CommomApi
case voiceRecordCollection(param:[String:Any])
/// è·åèæ¯å¾
case backgroundList
+
+ /// å建å¢é
+ case createSportGroup(param:[String:Any])
+ /// è·åå¢é
+ case getSportGroupList(param:[String:Any])
+ /// ç³è¯·å å
¥å¢é
+ case applyJoinGroup(param:[String:Any])
}
// å®ç°TargetTypeåè®®
@@ -179,17 +188,32 @@ extension CommomApi{
return "/uc/phone/bind?smsCode=\(param["smsCode"]!)&phone=\(param["phone"]!)"
case .updateEmail(let param):
return "/uc/email?emailCode=\(param["emailCode"]!)&email=\(param["email"]!)"
+ case .getUserInfo:
+ return "/uc/userinfo"
case .updateUserInfo(let param):
var path = "/uc/userinfo?"
- if let username = param["username"]{
- path += "username=\(username)&"
+ if let text = param["username"]{
+ path += "username=\(text)&"
+ }
+ if let text = param["gender"]{
+ path += "gender=\(text)&"
+ }
+ if let text = param["tall"]{
+ path += "tall=\(text)&"
}
- if let gender = param["gender"]{
- path += "gender=\(gender)&"
+ if let text = param["weight"]{
+ path += "weight=\(text)&"
}
- if let countyId = param["countryId"]{
- path += "countyId=\(countyId)"
+ if let text = param["birthday"]{
+ path += "birthday=\(text)&"
}
+ if let text = param["preference"]{
+ path += "preference=\(text)&"
+ }
+ if let text = param["countryId"]{
+ path += "countyId=\(text)"
+ }
+ Logger.debug("path => ",path)
return path
case .storageSize:
return "/res/voice-file/storage-size"
@@ -266,12 +290,22 @@ extension CommomApi{
case .backgroundList:
return "/dev/devBg/list"
+
+
+ case .createSportGroup(_):
+ return "/sp/sport-group"
+ case .getSportGroupList(_):
+ return "/sp/sport-group/list"
+ case .applyJoinGroup(let param):
+ return "/sp/sport-group/\(param["id"]!)/apply"
+
+
}
}
var method:RequestMethod{
switch self {
- case .register(_),.phoneCodeLogin(_),.emailCodeLogin(_),.appleLogin(_),.login(_),.commitFeedback(_),.voiceRecord(_),.voiceRecordText(_):
+ case .register(_),.phoneCodeLogin(_),.emailCodeLogin(_),.appleLogin(_),.login(_),.commitFeedback(_),.voiceRecord(_),.voiceRecordText(_),.createSportGroup(_),.applyJoinGroup(_):
return .post
case .updatePwd(_),.updateUserInfo(_),.updatePhone(_),.bindPhone(_),.updateEmail(_),.bindDevice(_),.otaUpdateVersion(_),.voiceRecordCollection(_),.updateVoiceRecord(_):
return .put
@@ -351,6 +385,12 @@ extension CommomApi{
params += para
case let .updateVoiceRecord(para):
params += para
+ case let .createSportGroup(para):
+ params += para
+ case let .getSportGroupList(para):
+ params += para
+ case let .applyJoinGroup(para):
+ params += para
default:
break
}
@@ -363,6 +403,7 @@ extension CommomApi{
"devtype": "iOS",
"devid": UIDevice().identifierForVendor?.uuidString ?? "unknow",
// "Content - Type": "application/json"
+ "dc-ut":CacheManager.shared.user.token ?? ""
]
}
}
@@ -372,26 +413,26 @@ class HttpClient{
static func request(_ target: CommomApi,completionHandler:@escaping ((T, String) -> Void)){
let url = target.url
let params = target.param
- Logger.debug("request => ",url)
- Logger.debug(YLToos.jsonToString(params))
+ Logger.debug("request => ",url,YLToos.jsonToString(params))
+// Logger.debug("header =>",YLToos.jsonToString(target.headers!))
if target.method == .get {
- HTTP.GET(url,parameters: params,requestSerializer: JSONParameterSerializer()){ response in
+ HTTP.GET(url,parameters: params,headers: target.headers,requestSerializer: JSONParameterSerializer()){ response in
handleResponse(response, completionHandler: completionHandler)
}
}
else if target.method == .post{
- HTTP.POST(url,parameters: params,requestSerializer: JSONParameterSerializer()){ response in
+ HTTP.POST(url,parameters: params,headers: target.headers,requestSerializer: JSONParameterSerializer()){ response in
handleResponse(response, completionHandler: completionHandler)
}
}
else if target.method == .put{
- HTTP.PUT(url,parameters: params,requestSerializer: JSONParameterSerializer()){ response in
+ HTTP.PUT(url,parameters: params,headers: target.headers,requestSerializer: JSONParameterSerializer()){ response in
handleResponse(response, completionHandler: completionHandler)
}
}
else if target.method == .delete{
- HTTP.DELETE(url,parameters: params,requestSerializer: JSONParameterSerializer()){ response in
+ HTTP.DELETE(url,parameters: params,headers: target.headers,requestSerializer: JSONParameterSerializer()){ response in
handleResponse(response, completionHandler: completionHandler)
}
}
diff --git a/ShenYin/ShenYin/Assets.xcassets/sport/add_2.imageset/Contents.json b/ShenYin/ShenYin/Assets.xcassets/sport/add_2.imageset/Contents.json
new file mode 100644
index 0000000..71dfb63
--- /dev/null
+++ b/ShenYin/ShenYin/Assets.xcassets/sport/add_2.imageset/Contents.json
@@ -0,0 +1,22 @@
+{
+ "images" : [
+ {
+ "idiom" : "universal",
+ "scale" : "1x"
+ },
+ {
+ "filename" : "Slice 137@2x.png",
+ "idiom" : "universal",
+ "scale" : "2x"
+ },
+ {
+ "filename" : "Slice 137@3x.png",
+ "idiom" : "universal",
+ "scale" : "3x"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/ShenYin/ShenYin/Assets.xcassets/sport/add_2.imageset/Slice 137@2x.png b/ShenYin/ShenYin/Assets.xcassets/sport/add_2.imageset/Slice 137@2x.png
new file mode 100644
index 0000000..9e0e80c
Binary files /dev/null and b/ShenYin/ShenYin/Assets.xcassets/sport/add_2.imageset/Slice 137@2x.png differ
diff --git a/ShenYin/ShenYin/Assets.xcassets/sport/add_2.imageset/Slice 137@3x.png b/ShenYin/ShenYin/Assets.xcassets/sport/add_2.imageset/Slice 137@3x.png
new file mode 100644
index 0000000..8a3667d
Binary files /dev/null and b/ShenYin/ShenYin/Assets.xcassets/sport/add_2.imageset/Slice 137@3x.png differ
diff --git a/ShenYin/ShenYin/Assets.xcassets/sport/btn_lock.imageset/Contents.json b/ShenYin/ShenYin/Assets.xcassets/sport/btn_lock.imageset/Contents.json
new file mode 100644
index 0000000..68cd0ef
--- /dev/null
+++ b/ShenYin/ShenYin/Assets.xcassets/sport/btn_lock.imageset/Contents.json
@@ -0,0 +1,22 @@
+{
+ "images" : [
+ {
+ "idiom" : "universal",
+ "scale" : "1x"
+ },
+ {
+ "filename" : "Slice 156@2x.png",
+ "idiom" : "universal",
+ "scale" : "2x"
+ },
+ {
+ "filename" : "Slice 156@3x.png",
+ "idiom" : "universal",
+ "scale" : "3x"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/ShenYin/ShenYin/Assets.xcassets/sport/btn_lock.imageset/Slice 156@2x.png b/ShenYin/ShenYin/Assets.xcassets/sport/btn_lock.imageset/Slice 156@2x.png
new file mode 100644
index 0000000..e7bd624
Binary files /dev/null and b/ShenYin/ShenYin/Assets.xcassets/sport/btn_lock.imageset/Slice 156@2x.png differ
diff --git a/ShenYin/ShenYin/Assets.xcassets/sport/btn_lock.imageset/Slice 156@3x.png b/ShenYin/ShenYin/Assets.xcassets/sport/btn_lock.imageset/Slice 156@3x.png
new file mode 100644
index 0000000..9dc4350
Binary files /dev/null and b/ShenYin/ShenYin/Assets.xcassets/sport/btn_lock.imageset/Slice 156@3x.png differ
diff --git a/ShenYin/ShenYin/Assets.xcassets/sport/btn_pause.imageset/Contents.json b/ShenYin/ShenYin/Assets.xcassets/sport/btn_pause.imageset/Contents.json
new file mode 100644
index 0000000..df62631
--- /dev/null
+++ b/ShenYin/ShenYin/Assets.xcassets/sport/btn_pause.imageset/Contents.json
@@ -0,0 +1,22 @@
+{
+ "images" : [
+ {
+ "idiom" : "universal",
+ "scale" : "1x"
+ },
+ {
+ "filename" : "Slice 42@2x.png",
+ "idiom" : "universal",
+ "scale" : "2x"
+ },
+ {
+ "filename" : "Slice 42@3x.png",
+ "idiom" : "universal",
+ "scale" : "3x"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/ShenYin/ShenYin/Assets.xcassets/sport/btn_pause.imageset/Slice 42@2x.png b/ShenYin/ShenYin/Assets.xcassets/sport/btn_pause.imageset/Slice 42@2x.png
new file mode 100644
index 0000000..7c44451
Binary files /dev/null and b/ShenYin/ShenYin/Assets.xcassets/sport/btn_pause.imageset/Slice 42@2x.png differ
diff --git a/ShenYin/ShenYin/Assets.xcassets/sport/btn_pause.imageset/Slice 42@3x.png b/ShenYin/ShenYin/Assets.xcassets/sport/btn_pause.imageset/Slice 42@3x.png
new file mode 100644
index 0000000..c28d3ef
Binary files /dev/null and b/ShenYin/ShenYin/Assets.xcassets/sport/btn_pause.imageset/Slice 42@3x.png differ
diff --git a/ShenYin/ShenYin/Assets.xcassets/sport/btn_set.imageset/Contents.json b/ShenYin/ShenYin/Assets.xcassets/sport/btn_set.imageset/Contents.json
new file mode 100644
index 0000000..078cd1b
--- /dev/null
+++ b/ShenYin/ShenYin/Assets.xcassets/sport/btn_set.imageset/Contents.json
@@ -0,0 +1,22 @@
+{
+ "images" : [
+ {
+ "idiom" : "universal",
+ "scale" : "1x"
+ },
+ {
+ "filename" : "Slice 157@2x.png",
+ "idiom" : "universal",
+ "scale" : "2x"
+ },
+ {
+ "filename" : "Slice 157@3x.png",
+ "idiom" : "universal",
+ "scale" : "3x"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/ShenYin/ShenYin/Assets.xcassets/sport/btn_set.imageset/Slice 157@2x.png b/ShenYin/ShenYin/Assets.xcassets/sport/btn_set.imageset/Slice 157@2x.png
new file mode 100644
index 0000000..6ce9d45
Binary files /dev/null and b/ShenYin/ShenYin/Assets.xcassets/sport/btn_set.imageset/Slice 157@2x.png differ
diff --git a/ShenYin/ShenYin/Assets.xcassets/sport/btn_set.imageset/Slice 157@3x.png b/ShenYin/ShenYin/Assets.xcassets/sport/btn_set.imageset/Slice 157@3x.png
new file mode 100644
index 0000000..89f5013
Binary files /dev/null and b/ShenYin/ShenYin/Assets.xcassets/sport/btn_set.imageset/Slice 157@3x.png differ
diff --git a/ShenYin/ShenYin/Assets.xcassets/sport/group_avatar.imageset/Contents.json b/ShenYin/ShenYin/Assets.xcassets/sport/group_avatar.imageset/Contents.json
new file mode 100644
index 0000000..2b86952
--- /dev/null
+++ b/ShenYin/ShenYin/Assets.xcassets/sport/group_avatar.imageset/Contents.json
@@ -0,0 +1,22 @@
+{
+ "images" : [
+ {
+ "idiom" : "universal",
+ "scale" : "1x"
+ },
+ {
+ "filename" : "Slice 205@2x.png",
+ "idiom" : "universal",
+ "scale" : "2x"
+ },
+ {
+ "filename" : "Slice 205@3x.png",
+ "idiom" : "universal",
+ "scale" : "3x"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/ShenYin/ShenYin/Assets.xcassets/sport/group_avatar.imageset/Slice 205@2x.png b/ShenYin/ShenYin/Assets.xcassets/sport/group_avatar.imageset/Slice 205@2x.png
new file mode 100644
index 0000000..511476f
Binary files /dev/null and b/ShenYin/ShenYin/Assets.xcassets/sport/group_avatar.imageset/Slice 205@2x.png differ
diff --git a/ShenYin/ShenYin/Assets.xcassets/sport/group_avatar.imageset/Slice 205@3x.png b/ShenYin/ShenYin/Assets.xcassets/sport/group_avatar.imageset/Slice 205@3x.png
new file mode 100644
index 0000000..ee95729
Binary files /dev/null and b/ShenYin/ShenYin/Assets.xcassets/sport/group_avatar.imageset/Slice 205@3x.png differ
diff --git a/ShenYin/ShenYin/Cache/UserInfo.swift b/ShenYin/ShenYin/Cache/UserInfo.swift
index 8d61a2f..e54c4c2 100644
--- a/ShenYin/ShenYin/Cache/UserInfo.swift
+++ b/ShenYin/ShenYin/Cache/UserInfo.swift
@@ -7,8 +7,8 @@
import HandyJSON
enum GenderType:String,HandyJSONEnum{
- case man = "1"
case female = "0"
+ case man = "1"
case unnkown = "2"
var title:String{
switch self {
@@ -28,15 +28,33 @@ class UserInfoRoot:ResponseBaseModel {
}
class UserInfo:ResponseBaseModel {
+ /// ç¨æ·id
var id = ""
+ /// 头å
var avatar = ""
+ /// æµç§°
var userName = ""
+ /// å建æ¶é´
var createTime = ""
+ /// ææºå·ç
var phone = ""
+ /// é®ç®±
var email = ""
+ /// æ§å«
var gender = GenderType.unnkown
+ /// å½å®¶
var countryName = ""
+ /// å½å®¶id
var countryId = ""
+ /// çæ¥
+ var birthday:String = ""
+ /// 身é«
+ var tall:String = ""
+ ///ä½é
+ var weight:String = ""
+ /// å好
+ var preference:String = ""
+
var cacheCountryName:String{
for item in LoginVM.shared.countryList {
diff --git a/ShenYin/ShenYin/Cache/UserModel.swift b/ShenYin/ShenYin/Cache/UserModel.swift
index 72b217c..d9ca19e 100644
--- a/ShenYin/ShenYin/Cache/UserModel.swift
+++ b/ShenYin/ShenYin/Cache/UserModel.swift
@@ -21,10 +21,6 @@ class UserModel {
if let cache = UserCache.shared.get(){
self.info = cache
}
-
- if self.token != nil {
- tokenIsValid()
- }
}
var storageSize = 0
@@ -72,6 +68,38 @@ extension UserModel{
}
}
+ func getUserInfo(finished: ((Bool) -> Void)? = nil){
+ if CCDevice.isJoy {
+ HttpClient.request(CommomApi.getUserInfo) { [weak self](model:UserInfoRoot,res) in
+ guard let self = self else{return}
+ if model.isSuccess{
+ self.info = model.data
+ UserCache.shared.save(self.info)
+ finished?(true)
+ }
+ else{
+ if let dict = YLToos.stringToJson(res),let code = dict["code"] as? Int{
+ if code == 50000{
+ logout()
+ }
+ else if code == 50022{
+ if let vc = App.shared.topVC() as? BindingPhoneVC{
+
+ }
+ else{
+ App.shared.goToPage(BindingPhoneVC())
+ }
+ }
+ }
+ finished?(false)
+ }
+
+ }
+ }
+ else{
+ tokenIsValid(finished: finished)
+ }
+ }
func getStorageSize(completion:@escaping (_ result:CommonDataIntModel) ->Void){
HttpClient.request(.storageSize) { [weak self](result:CommonDataIntModel,res) in
diff --git a/ShenYin/ShenYin/Launch/AppLaunch.swift b/ShenYin/ShenYin/Launch/AppLaunch.swift
index 977eae8..76b0ce5 100644
--- a/ShenYin/ShenYin/Launch/AppLaunch.swift
+++ b/ShenYin/ShenYin/Launch/AppLaunch.swift
@@ -31,6 +31,7 @@ class AppLaunch:NSObject{
}
static func loadCache(){
if CacheManager.shared.user.isLogin {
+ CacheManager.shared.user.tokenIsValid()
App.shared.didLogin()
}
else{
diff --git a/ShenYin/ShenYin/Launch/AppManager.swift b/ShenYin/ShenYin/Launch/AppManager.swift
index 9000a42..740b4d9 100644
--- a/ShenYin/ShenYin/Launch/AppManager.swift
+++ b/ShenYin/ShenYin/Launch/AppManager.swift
@@ -19,7 +19,7 @@ class App{
}
func willLogin(){
- CacheManager.shared.user.tokenIsValid {[weak self] success in
+ CacheManager.shared.user.getUserInfo {[weak self] success in
guard let self = self else{return}
if success {
didLogin()
diff --git a/ShenYin/ShenYin/Launch/SceneDelegate.swift b/ShenYin/ShenYin/Launch/SceneDelegate.swift
index e4b59b1..fd80973 100644
--- a/ShenYin/ShenYin/Launch/SceneDelegate.swift
+++ b/ShenYin/ShenYin/Launch/SceneDelegate.swift
@@ -19,8 +19,8 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate {
App.shared.window = window
AppLaunch.start()
// MapManager.shared.setupSdk()
-// window?.rootViewController = UINavigationController(rootViewController: SportingVC())
-
+// window?.rootViewController = UINavigationController(rootViewController: CreateGroupVC())
+//
}
func sceneDidDisconnect(_ scene: UIScene) {
diff --git a/ShenYin/ShenYin/Sdk/DcSdk/VC/HomeDeviceVC.swift b/ShenYin/ShenYin/Sdk/DcSdk/VC/HomeDeviceVC.swift
index b2d414b..0f24292 100644
--- a/ShenYin/ShenYin/Sdk/DcSdk/VC/HomeDeviceVC.swift
+++ b/ShenYin/ShenYin/Sdk/DcSdk/VC/HomeDeviceVC.swift
@@ -90,7 +90,7 @@ class HomeDeviceVC:BaseVC{
self?.startConectBle(model)
}
}
- CacheManager.shared.user.tokenIsValid(){[weak self] sucess in
+ CacheManager.shared.user.getUserInfo{[weak self] sucess in
self?.collectionView.reloadData()
}
}
diff --git a/ShenYin/ShenYin/Sdk/DcSdk/tool/CCBleManager.swift b/ShenYin/ShenYin/Sdk/DcSdk/tool/CCBleManager.swift
index a89ee81..ab99e56 100644
--- a/ShenYin/ShenYin/Sdk/DcSdk/tool/CCBleManager.swift
+++ b/ShenYin/ShenYin/Sdk/DcSdk/tool/CCBleManager.swift
@@ -109,7 +109,7 @@ extension CCBleManager:CBCentralManagerDelegate{
conetedFailureCallback?(connectPeripheral!)
}
func centralManager(_ central: CBCentralManager, didDisconnectPeripheral peripheral: CBPeripheral, error: Error?) {
- Logger.debug("èçå·²æå¼ \(peripheral)")
+ Logger.debug("èçå·²æå¼ \(peripheral)",error?.localizedDescription ?? "",error.debugDescription)
YLprogressHUD.showAutoHiden("èçå·²æå¼".l10n)
self.isConnetd = false
if CCDevice.isJoy{
diff --git a/ShenYin/ShenYin/Sdk/DcSdk/tool/CCConfig.swift b/ShenYin/ShenYin/Sdk/DcSdk/tool/CCConfig.swift
index 52dcfb3..7feb772 100644
--- a/ShenYin/ShenYin/Sdk/DcSdk/tool/CCConfig.swift
+++ b/ShenYin/ShenYin/Sdk/DcSdk/tool/CCConfig.swift
@@ -5,41 +5,37 @@
// Created by liangshi on 2026/1/28.
//
-class CCConfig{
- static var appLanguage = AppSupportLanguage.english
-
- static let wxAppID = "wxd9d677e0024caa90"
- static let wxUniversalLink = "https://dc-cloud-pub.tos-cn-guangzhou.volces.com/app/"
- static let appStoreLink = "https://itunes.apple.com/cn/app/6752551504?mt=8"
- /// çæ¬æ£æµ
- static let appStoreVersionURL = "https://itunes.apple.com/cn/lookup?id=6752551504"
-
- /// æå¡å¨å°å
- //static let baseURL = "http://118.145.178.188:32000"
- static let baseURL = "https://app-api.deepchords.com"
- //æµ·å¤ç
- // static let baseURL = "https://app-api.deepchords-ai.com"
-
- /// ç¨æ·éç§åè®®å°å
- static let yonghuBaseURL = "https://pub-tos.deepchords.com"
-}
-
-
-
//class CCConfig{
// static var appLanguage = AppSupportLanguage.english
-//
+//
// static let wxAppID = "wxeb3291e720293abc"
// static let wxUniversalLink = "https://www.playboykq.com/app/"
// static let appStoreLink = "https://itunes.apple.com/cn/app/6757697090?mt=8"
// /// çæ¬æ£æµ
// static let appStoreVersionURL = "https://itunes.apple.com/cn/lookup?id=6757697090"
-//
+//
// /// æå¡å¨å°å
-// static let baseURL = "https://app-api.playboykq.com"
-//
+// static let baseURL = "https://app-api.deepchords.com"
+//
// /// ç¨æ·éç§åè®®å°å
// static let yonghuBaseURL = "https://pub-cdn.playboykq.com"
-//
+//
//}
+
+class CCConfig{
+ static var appLanguage = AppSupportLanguage.english
+
+ static let wxAppID = "wxeb3291e720293abc"
+ static let wxUniversalLink = "https://www.playboykq.com/app/"
+ static let appStoreLink = "https://itunes.apple.com/cn/app/6757697090?mt=8"
+ /// çæ¬æ£æµ
+ static let appStoreVersionURL = "https://itunes.apple.com/cn/lookup?id=6757697090"
+
+ /// æå¡å¨å°å
+ static let baseURL = "https://app-api.playboykq.com"
+
+ /// ç¨æ·éç§åè®®å°å
+ static let yonghuBaseURL = "https://pub-cdn.playboykq.com"
+
+}
diff --git a/ShenYin/ShenYin/Sdk/JoySdk/VC/HomeDeviceVC.swift b/ShenYin/ShenYin/Sdk/JoySdk/VC/HomeDeviceVC.swift
index 2364006..03dc84d 100644
--- a/ShenYin/ShenYin/Sdk/JoySdk/VC/HomeDeviceVC.swift
+++ b/ShenYin/ShenYin/Sdk/JoySdk/VC/HomeDeviceVC.swift
@@ -103,7 +103,7 @@ class HomeDeviceVC:BaseVC{
self?.startConectBle(model)
}
}
- CacheManager.shared.user.tokenIsValid(){[weak self] sucess in
+ CacheManager.shared.user.getUserInfo(){[weak self] sucess in
self?.collectionView.reloadData()
}
}
diff --git a/ShenYin/ShenYin/Sdk/LogManager.swift b/ShenYin/ShenYin/Sdk/LogManager.swift
index f61e054..8735333 100644
--- a/ShenYin/ShenYin/Sdk/LogManager.swift
+++ b/ShenYin/ShenYin/Sdk/LogManager.swift
@@ -9,7 +9,7 @@ import Foundation
/// æ¥è®°ç®¡ç
class Logger {
- static var isDebug: Bool = false
+ static var isDebug: Bool = true
fileprivate static let shared = Logger()
private var fileHandle:FileHandle?
diff --git a/ShenYin/ShenYin/UI/Base/BaseTC.swift b/ShenYin/ShenYin/UI/Base/BaseTC.swift
index f2105fd..c2d9684 100644
--- a/ShenYin/ShenYin/UI/Base/BaseTC.swift
+++ b/ShenYin/ShenYin/UI/Base/BaseTC.swift
@@ -21,6 +21,8 @@ class BaseTC:UITabBarController{
func setupUI(){
if CCDevice.isJoy{
let homeVC = HomeDeviceVC()
+// let homeVC = SportHomeVC()
+
let modeVC = ModeVC()
let sleepVC = SleepVC()
let mineVC = MineVC()
diff --git a/ShenYin/ShenYin/UI/Mine/AccountSetVC.swift b/ShenYin/ShenYin/UI/Mine/AccountSetVC.swift
index 8116b4b..907fdaf 100644
--- a/ShenYin/ShenYin/UI/Mine/AccountSetVC.swift
+++ b/ShenYin/ShenYin/UI/Mine/AccountSetVC.swift
@@ -39,7 +39,7 @@ class AccountSetVC: BaseVC{
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
- CacheManager.shared.user.tokenIsValid(){[weak self] sucess in
+ CacheManager.shared.user.getUserInfo{[weak self] sucess in
self?.header.updateUI()
}
}
diff --git a/ShenYin/ShenYin/UI/Mine/Root/MineHeaderView.swift b/ShenYin/ShenYin/UI/Mine/Root/MineHeaderView.swift
index b0a1e88..6763925 100644
--- a/ShenYin/ShenYin/UI/Mine/Root/MineHeaderView.swift
+++ b/ShenYin/ShenYin/UI/Mine/Root/MineHeaderView.swift
@@ -95,7 +95,7 @@ class MineUserInfoView: BaseView {
}
}
func updateUI(){
- CacheManager.shared.user.tokenIsValid(){[weak self] sucess in
+ CacheManager.shared.user.getUserInfo{[weak self] sucess in
guard let self = self else {return}
titleLabel.text = CacheManager.shared.user.info.userName
icon.kf.setImage(with:CacheManager.shared.user.info.avatar.yc.asUrl )
diff --git a/ShenYin/ShenYin/UI/Mine/UserInfo/UserInfoCell.swift b/ShenYin/ShenYin/UI/Mine/UserInfo/UserInfoCell.swift
index 4f5b527..a50cd1d 100644
--- a/ShenYin/ShenYin/UI/Mine/UserInfo/UserInfoCell.swift
+++ b/ShenYin/ShenYin/UI/Mine/UserInfo/UserInfoCell.swift
@@ -50,11 +50,11 @@ class UserInfoCell: BaseTableViewCell {
titleLabel.text = type.title
valueIcon.isHidden = type != .avatar
- if type == .nickName || type == .gender || type == .area {
- valueLabel.isHidden = false
+ if type == .avatar {
+ valueLabel.isHidden = true
}
else{
- valueLabel.isHidden = true
+ valueLabel.isHidden = false
}
let info = CacheManager.shared.user.info
if type == .nickName {
@@ -68,6 +68,18 @@ class UserInfoCell: BaseTableViewCell {
// valueLabel.text = info.countryName
valueLabel.text = info.cacheCountryName
}
+ else if type == .birthday {
+ valueLabel.text = info.birthday
+ }
+ else if type == .height {
+ valueLabel.text = info.tall + "cm"
+ }
+ else if type == .weight {
+ valueLabel.text = info.weight + "kg"
+ }
+ else if type == .hobbies {
+ valueLabel.text = info.preference
+ }
else if type == .avatar{
valueIcon.kf.setImage(with:CacheManager.shared.user.info.avatar.yc.asUrl )
}
diff --git a/ShenYin/ShenYin/UI/Mine/UserInfo/UserInfoVC.swift b/ShenYin/ShenYin/UI/Mine/UserInfo/UserInfoVC.swift
index 45e7ad0..4c05333 100644
--- a/ShenYin/ShenYin/UI/Mine/UserInfo/UserInfoVC.swift
+++ b/ShenYin/ShenYin/UI/Mine/UserInfo/UserInfoVC.swift
@@ -103,9 +103,14 @@ extension UserInfoVC{
let v = CustomPicker3(title: "æ¥æ".l10n)
// v.selectedIndex = 50
v.show()
- v.didSelected = {[weak self] (date) in
+ v.didSelected = {[weak self] (value) in
guard let self = self else { return }
-
+ CacheManager.shared.user.info.birthday = value.format(.short)
+// CacheManager.shared.user.info.birthday = "\(Int(value.timeIntervalSince1970))"
+
+ var params:[String:Any] = [:]
+ params["birthday"] = CacheManager.shared.user.info.birthday
+ uploadUserData(params)
}
}
func heightAction(){
@@ -115,7 +120,10 @@ extension UserInfoVC{
v.show()
v.didSelected = {[weak self] (index,value) in
guard let self = self else { return }
-
+ CacheManager.shared.user.info.tall = String(value.prefix(value.count - 2))
+ var params:[String:Any] = [:]
+ params["tall"] = CacheManager.shared.user.info.tall
+ uploadUserData(params)
}
}
func weightAction(){
@@ -125,7 +133,10 @@ extension UserInfoVC{
v.show()
v.didSelected = {[weak self] (index,value) in
guard let self = self else { return }
-
+ CacheManager.shared.user.info.weight = String(value.prefix(value.count - 2))
+ var params:[String:Any] = [:]
+ params["weight"] = CacheManager.shared.user.info.weight
+ uploadUserData(params)
}
}
func hobiesAction(){
@@ -135,7 +146,10 @@ extension UserInfoVC{
v.show()
v.didSelected = {[weak self] (index,value) in
guard let self = self else { return }
-
+ CacheManager.shared.user.info.preference = value
+ var params:[String:Any] = [:]
+ params["preference"] = CacheManager.shared.user.info.preference
+ uploadUserData(params)
}
}
func genderAction(){
@@ -217,7 +231,7 @@ extension UserInfoVC{
}
}
func refreshUI(){
- CacheManager.shared.user.tokenIsValid(){ [weak self] success in
+ CacheManager.shared.user.getUserInfo{ [weak self] success in
self?.tableView.reloadData()
}
LoginVM.fetchCountryList {[weak self] result in
diff --git a/ShenYin/ShenYin/UI/Sport/Sport/Group/Create/AddGroupHeader.swift b/ShenYin/ShenYin/UI/Sport/Sport/Group/Create/AddGroupHeader.swift
new file mode 100644
index 0000000..f9912ab
--- /dev/null
+++ b/ShenYin/ShenYin/UI/Sport/Sport/Group/Create/AddGroupHeader.swift
@@ -0,0 +1,40 @@
+//
+// AddGroupHeader.swift
+// ShenYin
+//
+// Created by liangshi on 2026/2/6.
+//
+
+class AddGroupHeader: BaseView {
+ let icon = UIImageView()
+ let titleLabel = UILabel()
+
+ override func setupViews() {
+ addSubviews([icon,titleLabel])
+
+ titleLabel.do { v in
+ v.textColor = .color(.secondary)
+ v.font = .regular(10)
+ v.text = "设置å¢é头å".l10n
+ }
+
+ icon.do { v in
+ v.image = UIImage(named: "group_avatar")
+ yc.setCornerRadius(12)
+
+ }
+ }
+
+ override func setupLayout() {
+ icon.snp.makeConstraints { make in
+ make.size.equalTo(90)
+ make.centerX.equalToSuperview()
+ make.top.equalToSuperview()
+ }
+ titleLabel.snp.makeConstraints { make in
+ make.centerX.equalToSuperview()
+ make.top.equalTo(icon.snp.bottom).offset(6)
+ }
+
+ }
+}
diff --git a/ShenYin/ShenYin/UI/Sport/Sport/Group/Create/CreateGroupVC.swift b/ShenYin/ShenYin/UI/Sport/Sport/Group/Create/CreateGroupVC.swift
new file mode 100644
index 0000000..d381349
--- /dev/null
+++ b/ShenYin/ShenYin/UI/Sport/Sport/Group/Create/CreateGroupVC.swift
@@ -0,0 +1,134 @@
+//
+// CreateGroupVC.swift
+// ShenYin
+//
+// Created by liangshi on 2026/2/5.
+//
+
+import UIKit
+
+class CreateGroupVC: BaseVC{
+ let headerView = AddGroupHeader()
+ let nameView = SportInputItem()
+ let typeView = SportSelectItem()
+ let desView = SportInputItem()
+ let lightView = SportSelectItem()
+ let verifyView = SportSwitchItem()
+ let okBtn = CustomButton()
+ var sportType:SportType = .walk
+
+ override func setupViews() {
+ navBar.do { v in
+ v.title = "å建å¢é".l10n
+ }
+ view.addSubviews([headerView,nameView,typeView,desView,lightView,verifyView,okBtn])
+ nameView.do { v in
+ v.yc.setCornerRadius(12)
+ v.titleLabel.text = "å¢éåç§°".l10n
+ v.textField.text = "111"
+ v.textField.attributedPlaceholder = NSAttributedString(string: "ç»å¢é起个åå".l10n, attributes: [NSAttributedString.Key.foregroundColor: UIColor.color(.placeholder)])
+
+ }
+ typeView.do { v in
+ v.yc.setCornerRadius(12)
+ v.titleLabel.text = "å¢éç±»å".l10n
+ v.detailLabel.text = sportType.name
+ v.yc.addTap(target: self, action: #selector(typeAction))
+ }
+ desView.do { v in
+ v.yc.setCornerRadius(12)
+ v.titleLabel.text = "ç®ä»".l10n
+ v.textField.attributedPlaceholder = NSAttributedString(string: "æè¿°ä¸ä¸æ¨çå¢".l10n, attributes: [NSAttributedString.Key.foregroundColor: UIColor.color(.placeholder)])
+ }
+ lightView.do { v in
+ v.yc.setCornerRadius(12)
+ v.titleLabel.text = "ç¯å¸¦è®¾ç½®".l10n
+ v.yc.addTap(target: self, action: #selector(lightAction))
+
+ }
+ verifyView.do { v in
+ v.yc.setCornerRadius(12)
+ v.titleLabel.text = "å å
¥éªè¯".l10n
+ v.detailLabel.text = "å¼å¯åï¼æåéè¦ç³è¯·æè½å å
¥".l10n
+ }
+ okBtn.set(title: "宿å建".l10n,style: .theme1, target: self, action: #selector(okAction))
+ }
+ override func setupLayout() {
+ headerView.snp.makeConstraints { make in
+ make.left.right.equalToSuperview()
+ make.top.equalToSuperview().inset(kNavBtm + 20)
+ make.height.equalTo(120)
+ }
+ nameView.snp.makeConstraints { make in
+ make.left.right.equalToSuperview().inset(18)
+ make.top.equalTo(headerView.snp.bottom).offset(10)
+ make.height.equalTo(51)
+ }
+ typeView.snp.makeConstraints { make in
+ make.left.right.equalToSuperview().inset(18)
+ make.top.equalTo(nameView.snp.bottom).offset(10)
+ make.height.equalTo(51)
+ }
+ desView.snp.makeConstraints { make in
+ make.left.right.equalToSuperview().inset(18)
+ make.top.equalTo(typeView.snp.bottom).offset(10)
+ make.height.equalTo(65)
+ }
+ lightView.snp.makeConstraints { make in
+ make.left.right.equalToSuperview().inset(18)
+ make.top.equalTo(desView.snp.bottom).offset(10)
+ make.height.equalTo(51)
+ }
+ verifyView.snp.makeConstraints { make in
+ make.left.right.equalToSuperview().inset(18)
+ make.top.equalTo(lightView.snp.bottom).offset(10)
+ make.height.equalTo(65)
+ }
+ okBtn.snp.makeConstraints { make in
+ make.bottom.equalToSuperview().inset(80)
+ make.left.right.equalToSuperview().inset(51)
+ make.height.equalTo(46)
+ }
+ }
+ @objc func typeAction(){
+ let vc = GroupTypeVC()
+ vc.didSelected = {[weak self] value in
+ self?.sportType = value
+ self?.typeView.detailLabel.text = value.name
+ }
+ App.shared.goToPage(vc)
+ }
+ @objc func lightAction(){
+ App.shared.goToPage(LightSetVC())
+ }
+ @objc func okAction(){
+ if nameView.isEmpty {
+ YLprogressHUD.showAutoHiden("å¢éåç§°ä¸è½ä¸ºç©º".l10n)
+ return
+ }
+
+ YLprogressHUD.showLoading()
+ var params:[String:Any] = [:]
+ // å¢éåç§°ï¼å¿
é¡»
+ params["name"] = nameView.value
+ // 头å
+// params["icon"] = ""
+ // è¿å¨ç±»åï¼running | cycling | walkingï¼å¿
é¡»
+ params["type"] = sportType.rawValue
+ // å¢éç®ä»ï¼éå¿
é¡»
+// params["introduction"] = ""
+ // 1å å
¥å®¡æ ¸ï¼0ä¸éè¦å®¡æ ¸ï¼éå¿
é¡»ï¼é»è®¤0
+ params["joinReview"] = verifyView.iSwitch.isOn ? "1":"0"
+ let api = CommomApi.createSportGroup(param: params)
+ HttpClient.request(api){ (model:ResponseBaseModel, res) in
+
+ if model.isSuccess{
+ YLprogressHUD.hidden()
+ }
+ else{
+ YLprogressHUD.showAutoHiden("请æ±å¤±è´¥".l10n)
+ }
+ }
+ }
+}
+
diff --git a/ShenYin/ShenYin/UI/Sport/Sport/Group/Create/SportInputItem.swift b/ShenYin/ShenYin/UI/Sport/Sport/Group/Create/SportInputItem.swift
new file mode 100644
index 0000000..4c10566
--- /dev/null
+++ b/ShenYin/ShenYin/UI/Sport/Sport/Group/Create/SportInputItem.swift
@@ -0,0 +1,136 @@
+//
+// SportInputItem.swift
+// ShenYin
+//
+// Created by liangshi on 2026/2/6.
+//
+
+class SportInputItem: BaseView,UITextFieldDelegate {
+ let valueLabel = UILabel()
+ let textField = UITextField()
+ let titleLabel = UILabel()
+ var maxLength = 10
+
+ var isEmpty:Bool{
+ if let text = textField.text,text.isNotEmpty {
+ return false
+ }
+ return true
+ }
+ var value:String{
+ return textField.text ?? ""
+ }
+
+ override func setupViews() {
+ yc.setCornerRadius(12)
+ addSubviews([valueLabel,titleLabel,textField])
+
+ titleLabel.do { v in
+ v.textColor = .color(.first)
+ v.font = .medium(14)
+ }
+ textField.do { v in
+ v.textColor = .color(.first)
+ v.keyboardType = .default
+ v.returnKeyType = .done
+ v.textAlignment = .left
+ v.addTarget(self, action: #selector(textFieldValueChange), for: .valueChanged)
+// v.backgroundColor = .red
+ v.delegate = self
+ }
+ valueLabel.do { v in
+ v.textColor = .color(.placeholder)
+ v.font = .regular(10)
+ v.textAlignment = .right
+ v.text = "0/\(maxLength)"
+ }
+ backgroundColor = .white
+ }
+
+ override func setupLayout() {
+
+ titleLabel.snp.makeConstraints { make in
+ make.centerY.equalToSuperview()
+ make.left.equalToSuperview().inset(14)
+ }
+ textField.snp.makeConstraints { make in
+ make.left.equalTo(titleLabel.snp.right).offset(10).priority(.high)
+ make.centerY.height.equalToSuperview()
+ make.right.equalToSuperview().inset(50).priority(.low)
+ }
+ valueLabel.snp.makeConstraints { make in
+ make.width.equalTo(38)
+ make.height.equalToSuperview()
+ make.centerY.equalToSuperview()
+ make.right.equalToSuperview().inset(12)
+ }
+ }
+ @objc func textFieldValueChange(){
+ valueLabel.text = "\(textField.text?.count ?? 0)/\(maxLength)"
+ }
+ func textFieldShouldReturn(_ textField: UITextField) -> Bool {
+ textField.resignFirstResponder()
+ return false
+ }
+}
+
+class SportTextViewItem: BaseView,UITextViewDelegate {
+ let valueLabel = UILabel()
+ let textView = UITextView()
+ let titleLabel = UILabel()
+ var maxLength = 10
+
+ override func setupViews() {
+ yc.setCornerRadius(12)
+ addSubviews([valueLabel,titleLabel,textView])
+
+ titleLabel.do { v in
+ v.textColor = .color(.first)
+ v.font = .medium(14)
+ v.text = "ç®ä»".l10n
+ }
+ textView.do { v in
+ v.textColor = .color(.first)
+ v.keyboardType = .default
+ v.returnKeyType = .done
+ v.textAlignment = .left
+ v.delegate = self
+ }
+ valueLabel.do { v in
+ v.textColor = .color(.placeholder)
+ v.font = .regular(10)
+ v.textAlignment = .right
+ v.text = "0/\(maxLength)"
+ }
+ backgroundColor = .white
+ }
+
+ override func setupLayout() {
+
+ titleLabel.snp.makeConstraints { make in
+ make.centerY.equalToSuperview()
+ make.left.equalToSuperview().inset(14)
+ }
+ textView.snp.makeConstraints { make in
+ make.left.equalTo(titleLabel.snp.right).offset(10).priority(.high)
+ make.centerY.height.equalToSuperview()
+ make.right.equalToSuperview().inset(50).priority(.low)
+ }
+ valueLabel.snp.makeConstraints { make in
+ make.width.equalTo(38)
+ make.height.equalToSuperview()
+ make.centerY.equalToSuperview()
+ make.right.equalToSuperview().inset(12)
+ }
+ }
+
+ func textViewDidChange(_ textView: UITextView) {
+ valueLabel.text = "\(textView.text?.count ?? 0)/\(maxLength)"
+ }
+
+ func textView(_ textView: UITextView, shouldChangeTextInRanges ranges: [NSValue], replacementText text: String) -> Bool {
+ textView.resignFirstResponder()
+
+ return false
+ }
+}
diff --git a/ShenYin/ShenYin/UI/Sport/Sport/Group/Create/SportSelectItem.swift b/ShenYin/ShenYin/UI/Sport/Sport/Group/Create/SportSelectItem.swift
new file mode 100644
index 0000000..51d8041
--- /dev/null
+++ b/ShenYin/ShenYin/UI/Sport/Sport/Group/Create/SportSelectItem.swift
@@ -0,0 +1,48 @@
+//
+// SportItem.swift
+// ShenYin
+//
+// Created by liangshi on 2026/2/6.
+//
+
+class SportSelectItem: BaseView {
+ let icon = UIImageView()
+ let detailLabel = UILabel()
+ let titleLabel = UILabel()
+
+ override func setupViews() {
+ yc.setCornerRadius(12)
+ addSubviews([icon,titleLabel,detailLabel])
+
+ titleLabel.do { v in
+ v.textColor = .color(.first)
+ v.font = .medium(14)
+ }
+ detailLabel.do { v in
+ v.textColor = .color(.secondary)
+ v.font = .regular(12)
+ }
+ icon.do { v in
+ v.image = UIImage(named: "arrow_2")
+ }
+ backgroundColor = .white
+ }
+
+ override func setupLayout() {
+
+ titleLabel.snp.makeConstraints { make in
+ make.centerY.equalToSuperview()
+ make.left.equalToSuperview().inset(14)
+ }
+ detailLabel.snp.makeConstraints { make in
+ make.centerY.equalToSuperview()
+ make.right.equalToSuperview().inset(27)
+ }
+ icon.snp.makeConstraints { make in
+ make.width.equalTo(7)
+ make.height.equalTo(13)
+ make.centerY.equalToSuperview()
+ make.right.equalToSuperview().inset(12)
+ }
+ }
+}
diff --git a/ShenYin/ShenYin/UI/Sport/Sport/Group/Create/SportSwitchItem.swift b/ShenYin/ShenYin/UI/Sport/Sport/Group/Create/SportSwitchItem.swift
new file mode 100644
index 0000000..4f5423a
--- /dev/null
+++ b/ShenYin/ShenYin/UI/Sport/Sport/Group/Create/SportSwitchItem.swift
@@ -0,0 +1,51 @@
+//
+// SportSwitchItem.swift
+// ShenYin
+//
+// Created by liangshi on 2026/2/6.
+//
+
+class SportSwitchItem: BaseTableViewCell {
+ let titleLabel = UILabel()
+ let detailLabel = UILabel()
+ let iSwitch = UISwitch()
+
+
+ override func setupViews() {
+ addSubviews([titleLabel,detailLabel,iSwitch])
+
+ backgroundColor = .color(.cellBg)
+ titleLabel.do { (v) in
+ v.textColor = .color(.first)
+ v.font = .bold(14)
+ v.textAlignment = .left
+ }
+ detailLabel.do { (v) in
+ v.textColor = .color(.secondary)
+ v.font = .regular(10)
+ v.textAlignment = .left
+ }
+ iSwitch.do { v in
+ v.addTarget(self, action: #selector(swicthAction), for: .valueChanged)
+ }
+ }
+
+ override func setupLayout() {
+ titleLabel.snp.makeConstraints { (m) in
+ m.top.equalToSuperview().inset(16)
+ m.left.equalToSuperview().offset(16)
+ }
+ detailLabel.snp.makeConstraints { (m) in
+ m.bottom.equalToSuperview().inset(16)
+ m.left.equalToSuperview().offset(16)
+ }
+ iSwitch.snp.makeConstraints { (m) in
+ m.right.equalToSuperview().inset(15)
+ m.centerY.equalToSuperview()
+ }
+ }
+
+
+ @objc func swicthAction(){
+ }
+}
diff --git a/ShenYin/ShenYin/UI/Sport/Sport/Group/MyGroup/MyGroupCell.swift b/ShenYin/ShenYin/UI/Sport/Sport/Group/MyGroup/MyGroupCell.swift
new file mode 100644
index 0000000..3174168
--- /dev/null
+++ b/ShenYin/ShenYin/UI/Sport/Sport/Group/MyGroup/MyGroupCell.swift
@@ -0,0 +1,90 @@
+//
+// MyGroupCell.swift
+// ShenYin
+//
+// Created by liangshi on 2026/2/6.
+//
+
+ class MyGroupCell: BaseTableViewCell {
+ let bgView = UIView()
+ let icon = UIImageView()
+ let nameLabel = UILabel()
+ let contentLabel = UILabel()
+
+ var model:MyGroupModel!{
+ didSet{
+ if model.icon.isEmpty{
+ icon.image = UIImage(named: "group_avatar")
+ }
+ else{
+ icon.kf.setImage(with: model.icon.yc.asUrl)
+ }
+ nameLabel.text = model.name
+ contentLabel.text = model.type.name + ".\(model.userCount)" + "人已å å
¥".l10n
+ }
+ }
+
+
+ override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
+ super.init(style: style, reuseIdentifier: reuseIdentifier)
+ }
+
+ required init?(coder: NSCoder) {
+ fatalError("init(coder:) has not been implemented")
+ }
+ override func setupViews() {
+ contentView.addSubview(bgView)
+ bgView.addSubviews([icon,nameLabel,contentLabel])
+
+ backgroundColor = .color(.bgColor)
+ contentView.backgroundColor = .clear
+ selectionStyle = .none
+ bgView.do { v in
+ v.backgroundColor = .color(.cellBg)
+ v.yc.setCornerRadius(8)
+ }
+ nameLabel.do { (v) in
+ v.textColor = .color(.first)
+ v.font = .medium(14)
+ v.textAlignment = .left
+ v.lineBreakMode = .byTruncatingTail
+ }
+ contentLabel.do { v in
+ v.textColor = .color(.secondary)
+ v.font = .regular(11)
+ v.textAlignment = .left
+ v.lineBreakMode = .byTruncatingTail
+ }
+
+ icon.do { v in
+ v.yc.setCornerRadius(8)
+ }
+ }
+
+ override func setupLayout() {
+ bgView.snp.makeConstraints { (m) in
+ m.left.right.equalToSuperview().inset(18)
+ m.top.equalToSuperview().inset(6)
+ m.bottom.equalToSuperview()
+ }
+
+ icon.snp.makeConstraints { (m) in
+ m.size.equalTo(36)
+ m.left.equalToSuperview().inset(15)
+ m.top.equalToSuperview().inset(15)
+ }
+ nameLabel.snp.makeConstraints { (m) in
+ m.top.equalToSuperview().inset(16)
+ m.left.equalToSuperview().offset(60)
+ m.right.lessThanOrEqualToSuperview().inset(16)
+ }
+ contentLabel.snp.makeConstraints { (m) in
+ m.bottom.equalToSuperview().inset(16)
+ m.left.equalToSuperview().offset(60)
+ m.right.lessThanOrEqualToSuperview().inset(16)
+ }
+
+ }
+
+
+}
diff --git a/ShenYin/ShenYin/UI/Sport/Sport/Group/MyGroup/MyGroupModel.swift b/ShenYin/ShenYin/UI/Sport/Sport/Group/MyGroup/MyGroupModel.swift
new file mode 100644
index 0000000..703df34
--- /dev/null
+++ b/ShenYin/ShenYin/UI/Sport/Sport/Group/MyGroup/MyGroupModel.swift
@@ -0,0 +1,31 @@
+//
+// Untitled.swift
+// ShenYin
+//
+// Created by liangshi on 2026/2/6.
+//
+
+import HandyJSON
+
+class MyGroupModelRoot:ResponseBaseModel {
+ var data = [MyGroupModel]()
+}
+
+class MyGroupModel:HandyJSON {
+ var id = "" // å¢éID
+ var userId = ""// ç¨æ·IDï¼å建è
çID
+ var creatorNickname = "" // å建è
æµç§°
+ var creatorAvatar = "" // https://example.com/avatar.jpg", // å建è
头å
+ var icon = "" // https://example.com/icon.jpg", // 徿
+ var state = "" // ç¶æï¼1æ£å¸¸ï¼0è§£æ£
+ var name = "" // å¢éåç§°
+ var type:SportType = SportType.walk // è¿å¨ç±»åï¼running | cycling | walking
+ var introduction = "" // å¢éç®ä»
+ var joinReview = ""// 1å å
¥å®¡æ ¸ï¼0ä¸éè¦å®¡æ ¸
+ var userCount = 0 //å å
¥äººæ°
+ var totalDistance = "" // æ»è·ç¦»ï¼åä½ç±³
+ var totalTime = "" // æ»è¿å¨æ¶é¿ï¼åä½ç§
+ var createTime = "" // å建æ¶é´
+ var updateTime = ""// æ´æ°æ¶é´
+ required public init() { }
+}
diff --git a/ShenYin/ShenYin/UI/Sport/Sport/Group/MyGroup/MyGroupVC.swift b/ShenYin/ShenYin/UI/Sport/Sport/Group/MyGroup/MyGroupVC.swift
new file mode 100644
index 0000000..7b3f120
--- /dev/null
+++ b/ShenYin/ShenYin/UI/Sport/Sport/Group/MyGroup/MyGroupVC.swift
@@ -0,0 +1,115 @@
+//
+// MyGroupVC.swift
+// ShenYin
+//
+// Created by liangshi on 2026/2/6.
+//
+
+import JXSegmentedView
+
+
+enum MyGroupType{
+ case create
+ case add
+
+ var name:String{
+ switch self {
+ case .create:
+ return "æç®¡çç"
+ case .add:
+ return "æå å
¥ç"
+ }
+ }
+ var value:String{
+ switch self {
+ case .create:
+ return "1"
+ case .add:
+ return "0"
+ }
+ }
+ static var all:[MyGroupType] = [.create,.add]
+}
+
+class MyGroupVC: BaseVC {
+ private let segmentedDataSource = JXSegmentedTitleDataSource()
+ private let segmentedView = JXSegmentedView()
+ private lazy var listContainerView: JXSegmentedListContainerView! = {
+ let view = JXSegmentedListContainerView(dataSource: self, type: .scrollView)
+ return view
+ }()
+
+ var list:[MyGroupType] = MyGroupType.all
+ override func viewDidLoad() {
+ super.viewDidLoad()
+
+ // AudioPlayView.shared.show()
+ self.view.addSubview(AudioPlayView.shared)
+ MapManager.shared.setupSdk()
+ }
+
+ override func setupLayout(){
+
+ segmentedView.snp.makeConstraints { (m) in
+ m.left.right.equalToSuperview()
+ m.height.equalTo(44.fitR)
+ m.top.equalToSuperview().inset(kNavBtm)
+ }
+ listContainerView.snp.makeConstraints { (m) in
+ m.width.left.equalToSuperview()
+ m.top.equalTo(segmentedView.snp.bottom)
+ m.bottom.equalToSuperview()
+ }
+ }
+ override func setupViews(){
+ view.addSubview(segmentedView)
+ view.addSubview(listContainerView)
+
+ view.backgroundColor = .color(.bgColor)
+ segmentedView.do { (v) in
+ segmentedDataSource.titleNormalColor = .color(.secondary)
+ segmentedDataSource.titleSelectedColor = .color(.first)
+ segmentedDataSource.titleNormalFont = .regular(14)
+ segmentedDataSource.titleSelectedFont = .bold(16)
+ segmentedDataSource.isTitleZoomEnabled = true
+ // segmentedDataSource.titleSelectedZoomScale = 1
+ segmentedDataSource.isTitleStrokeWidthEnabled = true
+ segmentedDataSource.isItemSpacingAverageEnabled = true
+ segmentedDataSource.isTitleColorGradientEnabled = true
+ segmentedDataSource.titles = list.map{"\($0.name)"}
+ segmentedView.backgroundColor = .clear
+
+ //é
ç½®æç¤ºå¨
+ let indicator = JXSegmentedIndicatorLineView()
+ indicator.indicatorWidth = 20
+ indicator.indicatorHeight = 4
+ indicator.verticalOffset = 6
+ indicator.indicatorColor = .color(.theme)
+ segmentedView.indicators = [indicator]
+
+ v.dataSource = segmentedDataSource
+ v.listContainer = listContainerView
+ }
+ }
+}
+
+extension MyGroupVC: JXSegmentedListContainerViewListDelegate {
+ func listView() -> UIView {
+ return view
+ }
+}
+
+extension MyGroupVC: JXSegmentedListContainerViewDataSource {
+ func numberOfLists(in listContainerView: JXSegmentedListContainerView) -> Int {
+ if let titleDataSource = segmentedView.dataSource as? JXSegmentedBaseDataSource {
+ return titleDataSource.dataSource.count
+ }
+ return 0
+ }
+
+ func listContainerView(_ listContainerView: JXSegmentedListContainerView, initListAt index: Int) -> JXSegmentedListContainerViewListDelegate {
+ let type = list[index]
+ return MyGroupView(selectType: type)
+
+ }
+}
diff --git a/ShenYin/ShenYin/UI/Sport/Sport/Group/MyGroup/MyGroupView.swift b/ShenYin/ShenYin/UI/Sport/Sport/Group/MyGroup/MyGroupView.swift
new file mode 100644
index 0000000..9cbc484
--- /dev/null
+++ b/ShenYin/ShenYin/UI/Sport/Sport/Group/MyGroup/MyGroupView.swift
@@ -0,0 +1,82 @@
+//
+// GroupListView.swift
+// ShenYin
+//
+// Created by liangshi on 2026/2/6.
+//
+
+import UIKit
+import JXSegmentedView
+import MJRefresh
+
+
+class MyGroupView: BaseView,UITableViewDelegate,UITableViewDataSource {
+ let tableView = UITableView(frame: .zero, style: .plain)
+ var list = [MyGroupModel]()
+ var type = MyGroupType.add
+
+ init(selectType type:MyGroupType){
+ super.init(frame: .zero)
+ self.type = type
+ tableView.mj_header?.beginRefreshing()
+ }
+
+ override func setupViews() {
+ addSubview(tableView)
+ tableView.do { v in
+ v.backgroundColor = .color(.bgColor)
+ v.delegate = self
+ v.dataSource = self
+ v.rowHeight = 74
+ v.separatorStyle = .none
+ v.register(MyGroupCell.self, forCellReuseIdentifier: MyGroupCell.reuseID)
+ v.mj_header = MJRefreshNormalHeader(refreshingTarget: self, refreshingAction: #selector(refreshAction))
+ }
+ }
+
+ override func setupLayout() {
+ tableView.snp.makeConstraints { (m) in
+ m.top.equalToSuperview().inset(10)
+ m.left.right.bottom.equalToSuperview()
+ }
+ }
+
+ @objc func refreshAction(){
+ var params:[String:Any] = [:]
+ params["type"] = type.value
+
+ let api = CommomApi.getSportGroupList(param: params)
+ HttpClient.request(api) {[weak self] (model:MyGroupModelRoot,res) in
+ guard let self = self else {return}
+ if model.isSuccess{
+ list = model.data
+ }
+ tableView.reloadData()
+ tableView.mj_header?.endRefreshing()
+ }
+
+ }
+
+
+ @MainActor required init?(coder: NSCoder) {
+ fatalError("init(coder:) has not been implemented")
+ }
+
+ func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
+ return list.count
+ }
+ func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
+ let cell = MyGroupCell.cell(withTableView: tableView, indexPath: indexPath)
+ cell.model = list[indexPath.row]
+ return cell
+ }
+ func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
+ }
+
+}
+
+extension MyGroupView: JXSegmentedListContainerViewListDelegate {
+ func listView() -> UIView {
+ return self
+ }
+}
diff --git a/ShenYin/ShenYin/UI/Sport/Sport/Group/Other/GroupRoleVC.swift b/ShenYin/ShenYin/UI/Sport/Sport/Group/Other/GroupRoleVC.swift
new file mode 100644
index 0000000..d3b91e0
--- /dev/null
+++ b/ShenYin/ShenYin/UI/Sport/Sport/Group/Other/GroupRoleVC.swift
@@ -0,0 +1,144 @@
+import UIKit
+import HandyJSON
+
+enum GroupRoleType:String,HandyJSONEnum{
+ case none = "none"
+ case pfs = "pfs"
+ case lpz = "lpz"
+ case gpz = "gpz"
+ case ccs = "ccs"
+ case psy = "psy"
+ case bjy = "bjy"
+ case qns = "qns"
+ case lqz = "lqz"
+ case gqz = "gqz"
+ case pps = "pps"
+
+
+ var name:String{
+ switch self {
+ case .none:
+ return "æ "
+ case .pfs:
+ return "ç ´é£æ"
+ case .lpz:
+ return "é¢è·è
"
+ case .gpz:
+ return "è·è·è
"
+ case .ccs:
+ return "å²åºæ"
+ case .psy:
+ return "é
éå"
+ case .bjy:
+ return "è¡¥ç»å"
+ case .qns:
+ return "å
¨è½æ"
+ case .lqz:
+ return "é¢éªè
"
+ case .gqz:
+ return "è·éªè
"
+ case .pps:
+ return "ç¬å¡æ"
+ }
+ }
+ var color:UIColor{
+ switch self {
+ case .none:
+ return .red
+ case .pfs:
+ return .red
+ case .lpz:
+ return .red
+ case .gpz:
+ return .red
+ case .ccs:
+ return .red
+ case .psy:
+ return .red
+ case .bjy:
+ return .red
+ case .qns:
+ return .red
+ case .lqz:
+ return .red
+ case .gqz:
+ return .red
+ case .pps:
+ return .red
+ }
+ }
+
+ static var all:[GroupRoleType] = [.none,.pfs,.lpz,.gpz,.ccs,.psy,.bjy,.qns]
+}
+
+class GroupRoleVC: BaseVC{
+ let tableView = UITableView(frame: .zero, style: .plain)
+ var list:[GroupRoleType] = GroupRoleType.all
+ var currentType = GroupRoleType.none
+ let btn = CustomButton()
+ var didSelected:((GroupRoleType)->Void)?
+
+ override func viewDidLoad() {
+ super.viewDidLoad()
+ // Do any additional setup after loading the view.
+ }
+ override func setupViews() {
+ self.navBar.title = "å¢éç±»å".l10n
+ tableView.do { v in
+ v.backgroundColor = .color(.bgColor)
+ v.delegate = self
+ v.dataSource = self
+ v.rowHeight = 52
+ v.separatorStyle = .none
+ v.contentInset = UIEdgeInsets(top: 10, left: 0, bottom: 0, right: 0)
+ v.register(SelectCell.self, forCellReuseIdentifier: SelectCell.reuseID)
+ }
+ view.addSubviews([tableView,btn])
+
+ btn.set(title: "ç¡®å®".l10n, target: self, action: #selector(btnAction))
+ }
+ override func setupLayout() {
+ tableView.snp.makeConstraints { make in
+ make.left.right.bottom.equalToSuperview()
+ make.top.equalTo(kNavBtm)
+ }
+ btn.snp.makeConstraints { make in
+ make.width.equalTo(272)
+ make.height.equalTo(46)
+ make.centerX.equalToSuperview()
+ make.bottom.equalToSuperview().inset(82)
+ }
+ }
+ @objc func btnAction(){
+ didSelected?(currentType)
+ self.navigationController?.popViewController(animated: true)
+ }
+}
+
+extension GroupRoleVC:UITableViewDelegate,UITableViewDataSource {
+ func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
+ return list.count
+ }
+
+ func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
+ let cell = SelectCell.cell(withTableView: tableView, indexPath: indexPath)
+ cell.titleLabel.text = list[indexPath.row].name
+ let rect = CGRect(x: 0, y: 0, width: kScreenWid - 36, height: 52)
+ if indexPath.row == 0 {
+ cell.bgView.yc.setCorners(withRoundedRect: rect, roundingCorners: [.topLeft,.topRight], cornerRadii: CGSize(width: 8, height: 8))
+ }
+ else if indexPath.row == list.count - 1{
+ cell.bgView.yc.setCorners(withRoundedRect: rect, roundingCorners: [.bottomLeft,.bottomRight], cornerRadii: CGSize(width: 8, height: 8))
+ }
+ else{
+ cell.bgView.yc.setCorners(withRoundedRect: rect, roundingCorners: [.allCorners], cornerRadii: CGSize(width: 0, height: 0))
+ }
+ cell.selectedIcon.isHidden = list[indexPath.row] != currentType
+ return cell
+ }
+ func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
+ let data = list[indexPath.row]
+ currentType = data
+ tableView.reloadData()
+ }
+}
diff --git a/ShenYin/ShenYin/UI/Sport/Sport/Group/Other/GroupTypeVC.swift b/ShenYin/ShenYin/UI/Sport/Sport/Group/Other/GroupTypeVC.swift
new file mode 100644
index 0000000..bb7a0e6
--- /dev/null
+++ b/ShenYin/ShenYin/UI/Sport/Sport/Group/Other/GroupTypeVC.swift
@@ -0,0 +1,80 @@
+//
+// GroupTypeVC.swift
+// ShenYin
+//
+// Created by liangshi on 2026/2/6.
+//
+
+import UIKit
+
+class GroupTypeVC: BaseVC{
+ let tableView = UITableView(frame: .zero, style: .plain)
+ var list:[SportType] = SportType.all
+ var currentType = SportType.walk
+ let btn = CustomButton()
+ var didSelected:((SportType)->Void)?
+
+ override func viewDidLoad() {
+ super.viewDidLoad()
+ // Do any additional setup after loading the view.
+ }
+ override func setupViews() {
+ self.navBar.title = "å¢éç±»å".l10n
+ tableView.do { v in
+ v.backgroundColor = .color(.bgColor)
+ v.delegate = self
+ v.dataSource = self
+ v.rowHeight = 52
+ v.separatorStyle = .none
+ v.contentInset = UIEdgeInsets(top: 10, left: 0, bottom: 0, right: 0)
+ v.register(SelectCell.self, forCellReuseIdentifier: SelectCell.reuseID)
+ }
+ view.addSubviews([tableView,btn])
+
+ btn.set(title: "ç¡®å®".l10n, target: self, action: #selector(btnAction))
+ }
+ override func setupLayout() {
+ tableView.snp.makeConstraints { make in
+ make.left.right.bottom.equalToSuperview()
+ make.top.equalTo(kNavBtm)
+ }
+ btn.snp.makeConstraints { make in
+ make.width.equalTo(272)
+ make.height.equalTo(46)
+ make.centerX.equalToSuperview()
+ make.bottom.equalToSuperview().inset(82)
+ }
+ }
+ @objc func btnAction(){
+ didSelected?(currentType)
+ self.navigationController?.popViewController(animated: true)
+ }
+}
+
+extension GroupTypeVC:UITableViewDelegate,UITableViewDataSource {
+ func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
+ return list.count
+ }
+
+ func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
+ let cell = SelectCell.cell(withTableView: tableView, indexPath: indexPath)
+ cell.titleLabel.text = list[indexPath.row].name
+ let rect = CGRect(x: 0, y: 0, width: kScreenWid - 36, height: 52)
+ if indexPath.row == 0 {
+ cell.bgView.yc.setCorners(withRoundedRect: rect, roundingCorners: [.topLeft,.topRight], cornerRadii: CGSize(width: 8, height: 8))
+ }
+ else if indexPath.row == list.count - 1{
+ cell.bgView.yc.setCorners(withRoundedRect: rect, roundingCorners: [.bottomLeft,.bottomRight], cornerRadii: CGSize(width: 8, height: 8))
+ }
+ else{
+ cell.bgView.yc.setCorners(withRoundedRect: rect, roundingCorners: [.allCorners], cornerRadii: CGSize(width: 0, height: 0))
+ }
+ cell.selectedIcon.isHidden = list[indexPath.row] != currentType
+ return cell
+ }
+ func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
+ let data = list[indexPath.row]
+ currentType = data
+ tableView.reloadData()
+ }
+}
diff --git a/ShenYin/ShenYin/UI/Sport/Sport/Group/add/AddGroupVC.swift b/ShenYin/ShenYin/UI/Sport/Sport/Group/add/AddGroupVC.swift
new file mode 100644
index 0000000..89046c7
--- /dev/null
+++ b/ShenYin/ShenYin/UI/Sport/Sport/Group/add/AddGroupVC.swift
@@ -0,0 +1,98 @@
+//
+// AddGrpupVC.swift
+// ShenYin
+//
+// Created by liangshi on 2026/2/6.
+//
+
+import UIKit
+
+class AddGroupVC: BaseVC{
+ let nameView = SportInputItem()
+ let typeView = SportSelectItem()
+ let desView = SportInputItem()
+ let okBtn = CustomButton()
+ var sportType:GroupRoleType = .none
+
+ override func setupViews() {
+ navBar.do { v in
+ v.title = "å å
¥å¢é".l10n
+ }
+ view.addSubviews([nameView,typeView,desView,okBtn])
+ nameView.do { v in
+ v.yc.setCornerRadius(12)
+ v.titleLabel.text = "å¢éå·".l10n
+ v.textField.text = "2019706199229804545"
+ v.textField.attributedPlaceholder = NSAttributedString(string: "请è¾å
¥å¢éå·".l10n, attributes: [NSAttributedString.Key.foregroundColor: UIColor.color(.placeholder)])
+
+ }
+ typeView.do { v in
+ v.yc.setCornerRadius(12)
+ v.titleLabel.text = "å¢éè§è²".l10n
+ v.detailLabel.text = sportType.name
+ v.yc.addTap(target: self, action: #selector(typeAction))
+ }
+ desView.do { v in
+ v.yc.setCornerRadius(12)
+ v.titleLabel.text = "ææå¼å
容".l10n
+ v.textField.attributedPlaceholder = NSAttributedString(string: "æè¿°ä¸ä¸æ¨çå¢".l10n, attributes: [NSAttributedString.Key.foregroundColor: UIColor.color(.placeholder)])
+ }
+ okBtn.set(title: "å å
¥".l10n,style: .theme1, target: self, action: #selector(okAction))
+ }
+ override func setupLayout() {
+ nameView.snp.makeConstraints { make in
+ make.left.right.equalToSuperview().inset(18)
+ make.top.equalToSuperview().inset(kNavBtm + 20)
+ make.height.equalTo(51)
+ }
+ typeView.snp.makeConstraints { make in
+ make.left.right.equalToSuperview().inset(18)
+ make.top.equalTo(nameView.snp.bottom).offset(10)
+ make.height.equalTo(51)
+ }
+ desView.snp.makeConstraints { make in
+ make.left.right.equalToSuperview().inset(18)
+ make.top.equalTo(typeView.snp.bottom).offset(10)
+ make.height.equalTo(65)
+ }
+ okBtn.snp.makeConstraints { make in
+ make.bottom.equalToSuperview().inset(80)
+ make.left.right.equalToSuperview().inset(51)
+ make.height.equalTo(46)
+ }
+ }
+ @objc func typeAction(){
+ let vc = GroupRoleVC()
+ vc.didSelected = {[weak self] value in
+ self?.sportType = value
+ self?.typeView.detailLabel.text = value.name
+ }
+ App.shared.goToPage(vc)
+ }
+ @objc func lightAction(){
+ App.shared.goToPage(LightSetVC())
+ }
+ @objc func okAction(){
+ if nameView.isEmpty {
+ YLprogressHUD.showAutoHiden("å¢éåç§°ä¸è½ä¸ºç©º".l10n)
+ return
+ }
+
+ YLprogressHUD.showLoading()
+ var params:[String:Any] = [:]
+ params["id"] = nameView.value
+ params["requestText"] = desView.value
+
+ let api = CommomApi.applyJoinGroup(param: params)
+ HttpClient.request(api){ (model:ResponseBaseModel, res) in
+
+ if model.isSuccess{
+ YLprogressHUD.hidden()
+ }
+ else{
+ YLprogressHUD.showAutoHiden("请æ±å¤±è´¥".l10n)
+ }
+ }
+ }
+}
+
diff --git a/ShenYin/ShenYin/UI/Sport/Sport/Ready/CountdownView.swift b/ShenYin/ShenYin/UI/Sport/Sport/Ready/CountdownView.swift
index 655cd2f..5afe77e 100644
--- a/ShenYin/ShenYin/UI/Sport/Sport/Ready/CountdownView.swift
+++ b/ShenYin/ShenYin/UI/Sport/Sport/Ready/CountdownView.swift
@@ -68,7 +68,7 @@ extension ReadyVC{
}
@objc func skipAction(){
timer.invalidate()
- App.shared.goToPage(BaseVC())
+ App.shared.goToPage(SportingVC())
removeFromSuperview()
}
}
diff --git a/ShenYin/ShenYin/UI/Sport/Sport/Ready/FooterView.swift b/ShenYin/ShenYin/UI/Sport/Sport/Ready/FooterView.swift
index 31318c4..78b2034 100644
--- a/ShenYin/ShenYin/UI/Sport/Sport/Ready/FooterView.swift
+++ b/ShenYin/ShenYin/UI/Sport/Sport/Ready/FooterView.swift
@@ -57,7 +57,7 @@ extension ReadyVC{
App.shared.goToPage(SportTargetVC())
}
@objc func goAction(){
- if true {
+ if false {
CustomAlert.showWith(title: "å®åæ°æ®".l10n, messgage: "å®åä½ çèº«ä½æ¡£æ¡ï¼è®©è¿å¨æ°æ®æ´åç¡®ã".l10n,ok: "åå¾".l10n) {
} okCallback: {
diff --git a/ShenYin/ShenYin/UI/Sport/Sport/Root/DataView.swift b/ShenYin/ShenYin/UI/Sport/Sport/Root/DataView.swift
index d09ceef..3c32ad5 100644
--- a/ShenYin/ShenYin/UI/Sport/Sport/Root/DataView.swift
+++ b/ShenYin/ShenYin/UI/Sport/Sport/Root/DataView.swift
@@ -7,14 +7,116 @@
extension SportRootView{
class DataView: BaseView {
-
+ let header = headItem()
+ let line = UIView()
+ let lastView = ItemView()
override func setupViews() {
backgroundColor = .color(.cellBg)
+ addSubviews([header,lastView,line])
+ line.backgroundColor = .color(.separateLine)
}
override func setupLayout() {
+ header.snp.makeConstraints { make in
+ make.left.right.top.equalToSuperview()
+ make.height.equalTo(51)
+ }
+ lastView.snp.makeConstraints { make in
+ make.left.right.bottom.equalToSuperview()
+ make.height.equalTo(72)
+ }
+ line.snp.makeConstraints { make in
+ make.left.right.equalToSuperview().inset(14)
+ make.height.equalTo(1)
+ make.bottom.equalTo(header)
+ }
+ }
+ class headItem: BaseView {
+ let icon = UIImageView()
+ let detailLabel = UILabel()
+ let titleLabel = UILabel()
+
+ override func setupViews() {
+ yc.setCornerRadius(12)
+ addSubviews([icon,titleLabel,detailLabel])
+
+ titleLabel.do { v in
+ v.textColor = .color(.first)
+ v.font = .medium(14)
+ v.text = "è¿å¨æ°æ®".l10n
+ }
+ detailLabel.do { v in
+ v.textColor = .color(.secondary)
+ v.font = .regular(12)
+ v.text = "å
¨é¨".l10n
+ }
+ icon.do { v in
+ v.image = UIImage(named: "arrow_2")
+ }
+ backgroundColor = .white
+ }
+
+ override func setupLayout() {
+
+ titleLabel.snp.makeConstraints { make in
+ make.centerY.equalToSuperview()
+ make.left.equalToSuperview().inset(14)
+ }
+ detailLabel.snp.makeConstraints { make in
+ make.centerY.equalToSuperview()
+ make.right.equalToSuperview().inset(27)
+ }
+ icon.snp.makeConstraints { make in
+ make.width.equalTo(7)
+ make.height.equalTo(13)
+ make.centerY.equalToSuperview()
+ make.right.equalToSuperview().inset(12)
+ }
+ }
+ }
+
+ class ItemView: BaseView {
+ let icon = UIImageView()
+ let detailLabel = UILabel()
+ let titleLabel = UILabel()
+
+ override func setupViews() {
+ yc.setCornerRadius(12)
+ addSubviews([icon,titleLabel,detailLabel])
+
+ titleLabel.do { v in
+ v.textColor = .color(.first)
+ v.font = .medium(14)
+ v.text = "æ·å¤è·æ¥ 6.21å
Ž"
+ }
+ detailLabel.do { v in
+ v.textColor = .color(.secondary)
+ v.font = .regular(10)
+ v.text = "30å26ç§"
+ }
+ icon.do { v in
+ v.image = UIImage(named: "add_2")
+ }
+ backgroundColor = .white
+ }
+ override func setupLayout() {
+
+ titleLabel.snp.makeConstraints { make in
+ make.top.equalToSuperview().inset(16)
+ make.left.equalToSuperview().inset(64)
+ }
+ detailLabel.snp.makeConstraints { make in
+ make.bottom.equalToSuperview().inset(16)
+ make.left.equalTo(titleLabel)
+ }
+ icon.snp.makeConstraints { make in
+ make.size.equalTo(40)
+ make.centerY.equalToSuperview()
+ make.left.equalToSuperview().inset(14)
+ }
+ }
}
}
}
diff --git a/ShenYin/ShenYin/UI/Sport/Sport/Root/GroupView.swift b/ShenYin/ShenYin/UI/Sport/Sport/Root/GroupView.swift
index 575d9b7..620dc8a 100644
--- a/ShenYin/ShenYin/UI/Sport/Sport/Root/GroupView.swift
+++ b/ShenYin/ShenYin/UI/Sport/Sport/Root/GroupView.swift
@@ -7,14 +7,96 @@
extension SportRootView{
class GroupView: BaseView {
+ let creatGroup = ItemView()
+ let addGroup = ItemView()
+ let myGroup = ItemView()
+ override func setupViews() {
+ addSubviews([creatGroup,addGroup,myGroup])
+ creatGroup.do { v in
+ v.titleLabel.text = "å建å¢é".l10n
+ v.detailLabel.text = "å建æçå¢é".l10n
+ v.yc.addTap(target: self, action: #selector(creatAction))
+ }
+ addGroup.do { v in
+ v.titleLabel.text = "å å
¥å¢é".l10n
+ v.detailLabel.text = "å å
¥å·²å建çå¢é".l10n
+ v.yc.addTap(target: self, action: #selector(joinAction))
+
+ }
+ myGroup.do { v in
+ v.titleLabel.text = "æçå¢é".l10n
+ v.detailLabel.text = "æå建åå·²å å
¥çå¢é".l10n
+ v.icon.isHidden = true
+ v.yc.addTap(target: self, action: #selector(myAction))
+ }
+ }
+
+ override func setupLayout() {
+ creatGroup.snp.makeConstraints { make in
+ make.left.top.right.equalToSuperview()
+ make.height.equalTo(65)
+ }
+ addGroup.snp.makeConstraints { make in
+ make.left.bottom.equalToSuperview()
+ make.height.equalTo(65)
+ make.width.equalTo((kScreenWid - 36 - 10)/2)
+ }
+ myGroup.snp.makeConstraints { make in
+ make.right.bottom.equalToSuperview()
+ make.height.equalTo(addGroup)
+ make.left.equalTo(addGroup.snp.right).offset(10)
+ }
+ }
+ @objc func creatAction(){
+ App.shared.goToPage(CreateGroupVC())
+ }
+ @objc func joinAction(){
+ App.shared.goToPage(AddGroupVC())
+ }
+ @objc func myAction(){
+ App.shared.goToPage(MyGroupVC())
+ }
+ }
+ class ItemView: BaseView {
+ let icon = UIImageView()
+ let detailLabel = UILabel()
+ let titleLabel = UILabel()
override func setupViews() {
- backgroundColor = .color(.cellBg)
+ backgroundColor = .color(.cellBg)
+ yc.setCornerRadius(12)
+ addSubviews([icon,titleLabel,detailLabel])
+
+ titleLabel.do { v in
+ v.textColor = .color(.first)
+ v.font = .medium(14)
+ }
+ detailLabel.do { v in
+ v.textColor = .color(.secondary)
+ v.font = .regular(10)
+ }
+ icon.do { v in
+ v.image = UIImage(named: "add_2")
+ }
+ backgroundColor = .white
}
override func setupLayout() {
+ titleLabel.snp.makeConstraints { make in
+ make.top.equalToSuperview().inset(16)
+ make.left.equalToSuperview().inset(14)
+ }
+ detailLabel.snp.makeConstraints { make in
+ make.bottom.equalToSuperview().inset(16)
+ make.left.equalTo(titleLabel)
+ }
+ icon.snp.makeConstraints { make in
+ make.size.equalTo(36)
+ make.centerY.equalToSuperview()
+ make.right.equalToSuperview().inset(12)
+ }
}
}
}
diff --git a/ShenYin/ShenYin/UI/Sport/Sport/Root/PlanView.swift b/ShenYin/ShenYin/UI/Sport/Sport/Root/PlanView.swift
index 05c6339..d29ffed 100644
--- a/ShenYin/ShenYin/UI/Sport/Sport/Root/PlanView.swift
+++ b/ShenYin/ShenYin/UI/Sport/Sport/Root/PlanView.swift
@@ -7,14 +7,20 @@
extension SportRootView{
class PlanView: BaseView {
-
+ let icon = ItemView()
override func setupViews() {
- backgroundColor = .color(.cellBg)
+ addSubviews([icon])
+ icon.do { v in
+ v.titleLabel.text = "æºè½è¿å¨è®¡å建议".l10n
+ v.detailLabel.text = "AIè§å个人å®å¶è¿å¨è®¡å".l10n
+ }
}
override func setupLayout() {
-
+ icon.snp.makeConstraints { make in
+ make.edges.equalToSuperview()
+ }
}
}
}
diff --git a/ShenYin/ShenYin/UI/Sport/Sport/Root/RouteView.swift b/ShenYin/ShenYin/UI/Sport/Sport/Root/RouteView.swift
index 245babb..dadc7a4 100644
--- a/ShenYin/ShenYin/UI/Sport/Sport/Root/RouteView.swift
+++ b/ShenYin/ShenYin/UI/Sport/Sport/Root/RouteView.swift
@@ -7,14 +7,92 @@
extension SportRootView{
class RouteView: BaseView {
-
+ let header = headItem()
+ let line = UIView()
+ let routeView1 = UIView()
+ let routeView2 = UIView()
+
override func setupViews() {
backgroundColor = .color(.cellBg)
+ addSubviews([header,routeView1,routeView2,line])
+ line.backgroundColor = .color(.separateLine)
+
+ routeView1.do { v in
+ v.backgroundColor = .lightGray
+ v.yc.setCornerRadius(12)
+ }
+ routeView2.do { v in
+ v.backgroundColor = .lightGray
+ v.yc.setCornerRadius(12)
+ }
}
override func setupLayout() {
+ header.snp.makeConstraints { make in
+ make.left.right.top.equalToSuperview()
+ make.height.equalTo(51)
+ }
+ routeView1.snp.makeConstraints { make in
+ make.left.bottom.equalToSuperview().inset(14)
+ make.height.equalTo(96)
+ make.width.equalTo(((kScreenWid - 64 - 10)/2))
+ }
+ routeView2.snp.makeConstraints { make in
+ make.right.bottom.equalToSuperview().inset(14)
+ make.height.equalTo(96)
+ make.width.equalTo(((kScreenWid - 64 - 10)/2))
+ }
+ line.snp.makeConstraints { make in
+ make.left.right.equalToSuperview().inset(14)
+ make.height.equalTo(1)
+ make.bottom.equalTo(header)
+ }
+ }
+ class headItem: BaseView {
+ let icon = UIImageView()
+ let detailLabel = UILabel()
+ let titleLabel = UILabel()
+
+ override func setupViews() {
+ yc.setCornerRadius(12)
+ addSubviews([icon,titleLabel,detailLabel])
+
+ titleLabel.do { v in
+ v.textColor = .color(.first)
+ v.font = .medium(14)
+ v.text = "路线æ¢ç´¢".l10n
+ }
+ detailLabel.do { v in
+ v.textColor = .color(.secondary)
+ v.font = .regular(12)
+ v.text = "å
¨é¨".l10n
+ }
+ icon.do { v in
+ v.image = UIImage(named: "arrow_2")
+ }
+ backgroundColor = .white
+ }
+ override func setupLayout() {
+
+ titleLabel.snp.makeConstraints { make in
+ make.centerY.equalToSuperview()
+ make.left.equalToSuperview().inset(14)
+ }
+ detailLabel.snp.makeConstraints { make in
+ make.centerY.equalToSuperview()
+ make.right.equalToSuperview().inset(27)
+ }
+ icon.snp.makeConstraints { make in
+ make.width.equalTo(7)
+ make.height.equalTo(13)
+ make.centerY.equalToSuperview()
+ make.right.equalToSuperview().inset(12)
+ }
+ }
}
+
+
}
}
diff --git a/ShenYin/ShenYin/UI/Sport/Sport/Root/SportTypeView.swift b/ShenYin/ShenYin/UI/Sport/Sport/Root/SportTypeView.swift
index a6c0a71..67a3834 100644
--- a/ShenYin/ShenYin/UI/Sport/Sport/Root/SportTypeView.swift
+++ b/ShenYin/ShenYin/UI/Sport/Sport/Root/SportTypeView.swift
@@ -4,12 +4,12 @@
//
// Created by liangshi on 2026/1/20.
//
+import HandyJSON
-
-enum SportType{
- case run
- case ride
- case walk
+enum SportType:String,HandyJSONEnum{
+ case run = "running"
+ case ride = "cycling"
+ case walk = "walking"
var name:String{
switch self {
@@ -31,6 +31,7 @@ enum SportType{
return "sport_walk"
}
}
+
static var all:[SportType] = [.run,.ride,.walk]
}
@@ -92,12 +93,13 @@ class SportTypeItem: BaseView {
var type:SportType = .run{
didSet{
titleLabel.text = type.name
+ icon.image = UIImage(named: type.icon)
}
}
override func setupViews() {
addSubviews([titleLabel,icon])
icon.do { v in
- v.image = UIImage(named: type.icon)
+
}
titleLabel.do { v in
v.textColor = .color(.first)
diff --git a/ShenYin/ShenYin/UI/Sport/Sport/SportDetail/SportDetailBoard.swift b/ShenYin/ShenYin/UI/Sport/Sport/SportDetail/SportDetailBoard.swift
new file mode 100644
index 0000000..31f67d9
--- /dev/null
+++ b/ShenYin/ShenYin/UI/Sport/Sport/SportDetail/SportDetailBoard.swift
@@ -0,0 +1,181 @@
+////
+//// Untitled.swift
+//// ShenYin
+////
+//// Created by liangshi on 2026/2/5.
+////
+//
+import UIKit
+
+extension SportDetailVC{
+ class SportDetailBoard: BaseView {
+ let topIcon = UIImageView()
+ let header = headerItem()
+ let distanceItem = LabelItem()
+ let durationItem = LabelItem()
+ let speedItem = LabelItem()
+ let calorieItem = LabelItem()
+ let stepItem = LabelItem()
+ let okBtn = UIButton(type: .custom)
+
+ override func setupViews() {
+ backgroundColor = .white
+ addSubviews([topIcon,header,distanceItem,durationItem,speedItem,calorieItem,stepItem,okBtn])
+ topIcon.do { v in
+ v.backgroundColor = .color(.secondary)
+ v.yc.setCornerRadius(2)
+ }
+ distanceItem.do { v in
+ v.titleLabel.text = "0"
+ v.detailLabel.text = "æ»è·ç¦»".l10n
+ }
+ durationItem.do { v in
+ v.titleLabel.text = "00:00:00"
+ v.detailLabel.text = "æ»æ¶é¿".l10n
+ }
+ speedItem.do { v in
+ v.titleLabel.text = "8'26\""
+ v.detailLabel.text = "é
é".l10n
+ }
+ calorieItem.do { v in
+ v.titleLabel.text = "300"
+ v.detailLabel.text = "å¡è·¯é".l10n
+ }
+ stepItem.do { v in
+ v.titleLabel.text = "1200"
+ v.detailLabel.text = "æ¥æ°".l10n
+ }
+ okBtn.do { v in
+ v.setImage(UIImage(named: "btn_pause"), for: .normal)
+ v.addTarget(self, action: #selector(okAction), for: .touchUpInside)
+ }
+ }
+
+ override func setupLayout() {
+ topIcon.snp.makeConstraints { make in
+ make.width.equalTo(50)
+ make.height.equalTo(4)
+ make.top.equalToSuperview().inset(6)
+ make.centerX.equalToSuperview()
+ }
+ header.snp.makeConstraints { make in
+ make.top.equalToSuperview().inset(28)
+ make.left.right.equalToSuperview()
+ make.height.equalTo(25)
+ }
+ distanceItem.snp.makeConstraints { make in
+ make.left.equalToSuperview().inset(18)
+ make.top.equalToSuperview().inset(100)
+ make.height.equalTo(50)
+ }
+ durationItem.snp.makeConstraints { make in
+ make.left.equalToSuperview().inset(18)
+ make.top.equalToSuperview().inset(180)
+ make.height.equalTo(50)
+ }
+ speedItem.snp.makeConstraints { make in
+ make.left.equalToSuperview().inset(kScreenWid/2 + 18)
+ make.top.equalTo(durationItem.snp.top)
+ make.height.equalTo(50)
+ }
+ calorieItem.snp.makeConstraints { make in
+ make.left.equalToSuperview().inset(18)
+ make.top.equalToSuperview().inset(250)
+ make.height.equalTo(50)
+ }
+ stepItem.snp.makeConstraints { make in
+ make.left.equalToSuperview().inset(kScreenWid/2 + 18)
+ make.top.equalTo(calorieItem.snp.top)
+ make.height.equalTo(50)
+ }
+ okBtn.snp.makeConstraints { make in
+ make.centerX.equalToSuperview()
+ make.bottom.equalToSuperview().inset(50)
+ make.size.equalTo(90)
+ }
+ }
+
+ @objc func okAction(){
+ App.shared.goToPage(SportDetailVC())
+ }
+
+
+ class headerItem: BaseView {
+ let deviceLabel = UILabel()
+ let deviceView = UIView()
+ let titleLabel = UILabel()
+
+ override func setupViews() {
+ addSubviews([titleLabel,deviceView])
+ deviceView.addSubviews([deviceLabel])
+ titleLabel.do { v in
+ v.textColor = .color(.first)
+ v.font = .bold(16)
+ v.textAlignment = .left
+ v.text = "æ·å¤è·æ¥"
+ }
+ deviceView.do { v in
+ v.backgroundColor = .rgb(0xF7F7F7 )
+ v.yc.setCornerRadius(13)
+ }
+ deviceLabel.do { v in
+ v.textColor = .color(.secondary)
+ v.font = .regular(10)
+ v.textAlignment = .center
+ v.text = "Deep Lite2 Ultra"
+ }
+ }
+
+ override func setupLayout() {
+ titleLabel.snp.makeConstraints { make in
+ make.centerY.equalToSuperview().inset(0)
+ make.left.equalToSuperview().inset(18)
+ }
+ deviceView.snp.makeConstraints { make in
+ make.width.equalTo(120)
+ make.height.equalTo(26)
+ make.left.equalToSuperview().inset(94)
+ make.centerY.equalToSuperview()
+ }
+ deviceLabel.snp.makeConstraints { make in
+ make.centerY.right.equalToSuperview()
+ make.left.equalToSuperview().inset(18)
+ }
+ }
+ }
+
+
+ class LabelItem: BaseView {
+ let detailLabel = UILabel()
+ let titleLabel = UILabel()
+
+ override func setupViews() {
+ addSubviews([titleLabel,detailLabel])
+ titleLabel.do { v in
+ v.textColor = .color(.first)
+ v.font = .bold(24)
+ v.textAlignment = .left
+ }
+ detailLabel.do { v in
+ v.textColor = .color(.secondary)
+ v.font = .regular(12)
+ v.textAlignment = .left
+ }
+ }
+
+ override func setupLayout() {
+ titleLabel.snp.makeConstraints { make in
+ make.top.equalToSuperview().inset(0)
+ make.left.right.equalToSuperview()
+ }
+ detailLabel.snp.makeConstraints { make in
+ make.bottom.equalToSuperview().inset(0)
+ make.left.right.equalToSuperview()
+ }
+ }
+ }
+ }
+
+
+
+}
diff --git a/ShenYin/ShenYin/UI/Sport/Sport/SportDetail/SportDetailVC.swift b/ShenYin/ShenYin/UI/Sport/Sport/SportDetail/SportDetailVC.swift
new file mode 100644
index 0000000..22a0030
--- /dev/null
+++ b/ShenYin/ShenYin/UI/Sport/Sport/SportDetail/SportDetailVC.swift
@@ -0,0 +1,87 @@
+//
+// SportDetailVC.swift
+// ShenYin
+//
+// Created by liangshi on 2026/2/5.
+//
+
+import MAMapKit
+
+class SportDetailVC: BaseVC {
+ var mapView:MAMapView!
+ let simpleView = UIView()
+ let detailView = SportDetailBoard()
+
+ override func setupViews() {
+
+
+
+ mapView = MAMapView(frame: .zero)
+ mapView.delegate = self
+ mapView.showsUserLocation = true
+ mapView.zoomLevel = 16
+ mapView.userTrackingMode = .followWithHeading
+
+ view.addSubviews([mapView,simpleView,detailView])
+ mapView.do { v in
+
+ }
+ simpleView.do { v in
+ v.yc.setCorners(withRoundedRect: CGRect(x: 0, y: 0, width: kScreenWid, height: 100), roundingCorners: [.topLeft,.topRight], cornerRadii: CGSize(width: 20, height: 20))
+ v.yc.addTap(target: self, action: #selector(simpleTapAction))
+ }
+ detailView.do { v in
+ v.yc.setCorners(withRoundedRect: CGRect(x: 0, y: 0, width: kScreenWid, height: 460), roundingCorners: [.topLeft,.topRight], cornerRadii: CGSize(width: 20, height: 20))
+ v.isHidden = true
+ v.yc.addTap(target: self, action: #selector(detailTapAction))
+ }
+ }
+ override func setupLayout() {
+ simpleView.snp.makeConstraints { make in
+ make.left.right.equalToSuperview()
+ make.bottom.equalToSuperview()
+ make.height.equalTo(100)
+ }
+ detailView.snp.makeConstraints { make in
+ make.left.right.equalToSuperview()
+ make.bottom.equalToSuperview()
+ make.height.equalTo(460)
+ }
+ mapView.snp.makeConstraints { make in
+ make.left.right.top.equalToSuperview()
+ make.bottom.equalTo(simpleView.snp.top).offset(20)
+ }
+ }
+ override func setupData() {
+
+ }
+
+ @objc func simpleTapAction(){
+ simpleView.isHidden = true
+ detailView.isHidden = false
+ showDetail()
+ }
+ @objc func detailTapAction(){
+ simpleView.isHidden = false
+ detailView.isHidden = true
+ showSimple()
+ }
+ func showSimple(){
+ mapView.snp.remakeConstraints { make in
+ make.left.right.top.equalToSuperview()
+ make.bottom.equalTo(simpleView.snp.top).offset(20)
+ }
+ }
+ func showDetail(){
+ mapView.snp.remakeConstraints { make in
+ make.left.right.top.equalToSuperview()
+ make.bottom.equalTo(detailView.snp.top).offset(20)
+ }
+ }
+}
+
+extension SportDetailVC:MAMapViewDelegate{
+ func mapViewRequireLocationAuth(_ locationManager: CLLocationManager!) {
+ // locationManager.requestAlwaysAuthorization()
+ }
+}
diff --git a/ShenYin/ShenYin/UI/Sport/Sport/Sporting/DetailBoard.swift b/ShenYin/ShenYin/UI/Sport/Sport/Sporting/DetailBoard.swift
index 87ce152..f14c052 100644
--- a/ShenYin/ShenYin/UI/Sport/Sport/Sporting/DetailBoard.swift
+++ b/ShenYin/ShenYin/UI/Sport/Sport/Sporting/DetailBoard.swift
@@ -10,15 +10,17 @@ import UIKit
extension SportingVC{
class DetailBoard: BaseView {
let topIcon = UIImageView()
+ let header = headerItem()
let distanceItem = LabelItem()
let durationItem = LabelItem()
let speedItem = LabelItem()
let calorieItem = LabelItem()
let stepItem = LabelItem()
+ let okBtn = UIButton(type: .custom)
override func setupViews() {
backgroundColor = .white
- addSubviews([topIcon,distanceItem,durationItem,speedItem,calorieItem,stepItem])
+ addSubviews([topIcon,header,distanceItem,durationItem,speedItem,calorieItem,stepItem,okBtn])
topIcon.do { v in
v.backgroundColor = .color(.secondary)
v.yc.setCornerRadius(2)
@@ -32,16 +34,20 @@ extension SportingVC{
v.detailLabel.text = "æ»æ¶é¿".l10n
}
speedItem.do { v in
- v.titleLabel.text = "00:00:00"
- v.detailLabel.text = "æ»æ¶é¿".l10n
+ v.titleLabel.text = "8'26\""
+ v.detailLabel.text = "é
é".l10n
}
calorieItem.do { v in
- v.titleLabel.text = "00:00:00"
- v.detailLabel.text = "æ»æ¶é¿".l10n
+ v.titleLabel.text = "300"
+ v.detailLabel.text = "å¡è·¯é".l10n
}
stepItem.do { v in
- v.titleLabel.text = "00:00:00"
- v.detailLabel.text = "æ»æ¶é¿".l10n
+ v.titleLabel.text = "1200"
+ v.detailLabel.text = "æ¥æ°".l10n
+ }
+ okBtn.do { v in
+ v.setImage(UIImage(named: "btn_pause"), for: .normal)
+ v.addTarget(self, action: #selector(okAction), for: .touchUpInside)
}
}
@@ -52,9 +58,14 @@ extension SportingVC{
make.top.equalToSuperview().inset(6)
make.centerX.equalToSuperview()
}
+ header.snp.makeConstraints { make in
+ make.top.equalToSuperview().inset(28)
+ make.left.right.equalToSuperview()
+ make.height.equalTo(25)
+ }
distanceItem.snp.makeConstraints { make in
make.left.equalToSuperview().inset(18)
- make.top.equalToSuperview().inset(27)
+ make.top.equalToSuperview().inset(100)
make.height.equalTo(50)
}
durationItem.snp.makeConstraints { make in
@@ -67,52 +78,104 @@ extension SportingVC{
make.top.equalTo(durationItem.snp.top)
make.height.equalTo(50)
}
- distanceItem.snp.makeConstraints { make in
+ calorieItem.snp.makeConstraints { make in
make.left.equalToSuperview().inset(18)
make.top.equalToSuperview().inset(250)
make.height.equalTo(50)
}
stepItem.snp.makeConstraints { make in
make.left.equalToSuperview().inset(kScreenWid/2 + 18)
- make.top.equalTo(distanceItem.snp.top)
+ make.top.equalTo(calorieItem.snp.top)
make.height.equalTo(50)
}
+ okBtn.snp.makeConstraints { make in
+ make.centerX.equalToSuperview()
+ make.bottom.equalToSuperview().inset(50)
+ make.size.equalTo(90)
+ }
}
- @objc func groupAction(){
- App.shared.goToPage(SportSetVC())
+ @objc func okAction(){
+ App.shared.goToPage(SportDetailVC())
}
- }
-
- class LabelItem: BaseView {
- let detailLabel = UILabel()
- let titleLabel = UILabel()
- override func setupViews() {
- addSubviews([titleLabel,detailLabel])
- titleLabel.do { v in
- v.textColor = .color(.first)
- v.font = .bold(24)
- v.textAlignment = .left
- }
- detailLabel.do { v in
- v.textColor = .color(.secondary)
- v.font = .regular(12)
- v.textAlignment = .left
+ class headerItem: BaseView {
+ let deviceLabel = UILabel()
+ let deviceView = UIView()
+ let titleLabel = UILabel()
+
+ override func setupViews() {
+ addSubviews([titleLabel,deviceView])
+ deviceView.addSubviews([deviceLabel])
+ titleLabel.do { v in
+ v.textColor = .color(.first)
+ v.font = .bold(16)
+ v.textAlignment = .left
+ v.text = "æ·å¤è·æ¥"
+ }
+ deviceView.do { v in
+ v.backgroundColor = .rgb(0xF7F7F7 )
+ v.yc.setCornerRadius(13)
+ }
+ deviceLabel.do { v in
+ v.textColor = .color(.secondary)
+ v.font = .regular(10)
+ v.textAlignment = .center
+ v.text = "Deep Lite2 Ultra"
+ }
+ }
+
+ override func setupLayout() {
+ titleLabel.snp.makeConstraints { make in
+ make.centerY.equalToSuperview().inset(0)
+ make.left.equalToSuperview().inset(18)
+ }
+ deviceView.snp.makeConstraints { make in
+ make.width.equalTo(120)
+ make.height.equalTo(26)
+ make.left.equalToSuperview().inset(94)
+ make.centerY.equalToSuperview()
+ }
+ deviceLabel.snp.makeConstraints { make in
+ make.centerY.right.equalToSuperview()
+ make.left.equalToSuperview().inset(18)
+ }
}
}
- override func setupLayout() {
- titleLabel.snp.makeConstraints { make in
- make.top.equalToSuperview().inset(0)
- make.left.right.equalToSuperview()
- }
- detailLabel.snp.makeConstraints { make in
- make.bottom.equalToSuperview().inset(0)
- make.left.right.equalToSuperview()
+
+ class LabelItem: BaseView {
+ let detailLabel = UILabel()
+ let titleLabel = UILabel()
+
+ override func setupViews() {
+ addSubviews([titleLabel,detailLabel])
+ titleLabel.do { v in
+ v.textColor = .color(.first)
+ v.font = .bold(24)
+ v.textAlignment = .left
+ }
+ detailLabel.do { v in
+ v.textColor = .color(.secondary)
+ v.font = .regular(12)
+ v.textAlignment = .left
+ }
+ }
+
+ override func setupLayout() {
+ titleLabel.snp.makeConstraints { make in
+ make.top.equalToSuperview().inset(0)
+ make.left.right.equalToSuperview()
+ }
+ detailLabel.snp.makeConstraints { make in
+ make.bottom.equalToSuperview().inset(0)
+ make.left.right.equalToSuperview()
+ }
}
}
}
-
+
+
+
}
diff --git a/ShenYin/ShenYin/UI/Sport/Sport/Sporting/SportingVC.swift b/ShenYin/ShenYin/UI/Sport/Sport/Sporting/SportingVC.swift
index ed528b3..fe9a9f6 100644
--- a/ShenYin/ShenYin/UI/Sport/Sport/Sporting/SportingVC.swift
+++ b/ShenYin/ShenYin/UI/Sport/Sport/Sporting/SportingVC.swift
@@ -27,10 +27,11 @@ class SportingVC: BaseVC {
}
simpleView.do { v in
- // v.backgroundColor = .blue
+ v.yc.setCorners(withRoundedRect: CGRect(x: 0, y: 0, width: kScreenWid, height: 100), roundingCorners: [.topLeft,.topRight], cornerRadii: CGSize(width: 20, height: 20))
v.yc.addTap(target: self, action: #selector(simpleTapAction))
}
detailView.do { v in
+ v.yc.setCorners(withRoundedRect: CGRect(x: 0, y: 0, width: kScreenWid, height: 460), roundingCorners: [.topLeft,.topRight], cornerRadii: CGSize(width: 20, height: 20))
v.isHidden = true
v.yc.addTap(target: self, action: #selector(detailTapAction))
}
@@ -48,7 +49,7 @@ class SportingVC: BaseVC {
}
mapView.snp.makeConstraints { make in
make.left.right.top.equalToSuperview()
- make.bottom.equalTo(simpleView.snp.top)
+ make.bottom.equalTo(simpleView.snp.top).offset(20)
}
}
override func setupData() {
@@ -68,13 +69,13 @@ class SportingVC: BaseVC {
func showSimple(){
mapView.snp.remakeConstraints { make in
make.left.right.top.equalToSuperview()
- make.bottom.equalTo(simpleView.snp.top)
+ make.bottom.equalTo(simpleView.snp.top).offset(20)
}
}
func showDetail(){
mapView.snp.remakeConstraints { make in
make.left.right.top.equalToSuperview()
- make.bottom.equalTo(detailView.snp.top)
+ make.bottom.equalTo(detailView.snp.top).offset(20)
}
}
}
diff --git a/ShenYin/ShenYin/UI/Sport/Sport/Tools/MapManager.swift b/ShenYin/ShenYin/UI/Sport/Sport/Tools/MapManager.swift
index 76af958..7344928 100644
--- a/ShenYin/ShenYin/UI/Sport/Sport/Tools/MapManager.swift
+++ b/ShenYin/ShenYin/UI/Sport/Sport/Tools/MapManager.swift
@@ -11,6 +11,7 @@ class MapManager {
static let shared = MapManager()
func setupSdk(){
+ MAMapView.updatePrivacyAgree(AMapPrivacyAgreeStatus.didAgree)
AMapServices.shared().apiKey = "57aebc5a63fa3ccb8cb81ae0cab649d1"
//夿æ¯å¦æ¯é¦æ¬¡å¯å¨
if !UserDefaults.standard.bool(forKey: "agreeStatus") {