// 相关api
enum CommomApi
{
+ /// 获取验证码
case sms(phone:String,type:SmsType)
+ /// 获取国家
case countryList
case list(pageNO: Int = 1, pageSize: Int = 10)
+ /// 注册
case register(param:[String:Any])
+ /// 验证码登录
case smsLogin(param:[String:Any])
+ /// 登录
case login(param:[String:Any])
+ /// 注销
case deactivate
+ /// 更新密码
case updatePwd(param:[String:Any])
+ /// 检查令牌
case token
+
+ /// 更新用户信息
+ case updateUserInfo(param:[String:Any])
+ /// 获取用户存储空间
+ case storageSize
+ /// 获取音乐分类
+ case musicCategory
+ /// 获取音乐列表
+ case muiscCategoryList(categoryId:String,page:Int)
}
// 实现TargetType协议
return "/uc/reset"
case .token:
return "/uc/token"
+ case .updateUserInfo(_):
+ return "/uc/userinfo"
+ case .storageSize:
+ return "/res/voice-file/storage-size"
+ case .musicCategory:
+ return "/res/music-category/list"
+ case .muiscCategoryList(let categoryId,let page):
+ return "/res/sleep-music/list/\(page)?categoryId=\(categoryId)"
+
}
}
switch self {
case .register(_),.smsLogin(_),.login(_):
return .post
- case .updatePwd(_):
+ case .updatePwd(_),.updateUserInfo(_):
return .put
default:
return .get
// let idfv = UIDevice.current.identifierForVendor?.uuidString
var param: [String:Any] {
// 公共参数
- // var params: [String: Any] = ["token": "Gz1qYLXeBW8MZuUfDlr9wsAYuVS1cZFMJY9BbaF842L2gRps747o4w=="]
+ //var params: [String: Any] = ["token": "Gz1qYLXeBW8MZuUfDlr9wsAYuVS1cZFMJY9BbaF842L2gRps747o4w=="]
var params: [String: Any] = [:]
// 收集参数
case let .updatePwd(para):
params += para
break
+ case let .updateUserInfo(para):
+ params += para
+ break
default:
break
}
enum GenderType:Int{
case man
case female
+ case unnkown
var title:String{
switch self {
case .man:
return "男"
case .female:
return "女"
+ case .unnkown:
+ return "保密"
+ }
+ }
+ var value:Int{
+ switch self {
+ case .man:
+ return 1
+ case .female:
+ return 0
+ default:
+ return 2
}
}
}
v.textColor = .hexString("#121212")
}
phoneView.do { v in
- v.textField.text = "13480939445"
+// v.textField.text = "13480939445"
}
codeView.do { v in
v.codeButton.addTarget(self, action: #selector(codeButtonAction), for: .touchUpInside)
v.region = CountryModel.chinese()
}
phoneView.do { v in
- v.textField.text = "19276672101"
+// v.textField.text = "19276672101"
}
registerBtn.set(title: "注册",style: .theme1, target: self, action: #selector(registerAction))
view.addSubviews([tipsLabel,bgView])
v.region = CountryModel.chinese()
}
phoneView.do { v in
- v.textField.text = "13480939445"
+// v.textField.text = "13480939445"
}
loginBtn.set(title: "登录",style: .theme1, target: self, action: #selector(loginAction))
pwdBtn.set(title: "密码登录", style: .theme2,target: self, action: #selector(pwdAction))
--- /dev/null
+//
+// Untitled.swift
+// ShenYin
+//
+// Created by liangshi on 2025/9/29.
+//
+class UserInfoRoot:ResponseBaseModel {
+ var data = UserInfo()
+}
+
+class UserInfo:ResponseBaseModel {
+ var id = ""
+ var avatar = ""
+ var userName = ""
+ var createTime = ""
+ var phone = ""
+ var state = "1"
+ var gender = 1
+ var verify = false
+ var countryName = ""
+ var countryId = ""
+
+ var genderText:String{
+ if gender == 1 {
+ return "男"
+ }
+ else if gender == 0 {
+ return "女"
+ }
+ else{
+ return "保密"
+ }
+ }
+}
//
// Created by liangshi on 2025/7/30.
//
+class StorageSizeModel:ResponseBaseModel {
+ var data:Int = 0
+}
class UserModel {
if self.token != nil {
}
}
+
+ var storageSize = 0
+ var info = UserInfo()
+}
+
+extension UserModel{
+ func getStorageSize(completion:@escaping (_ result:StorageSizeModel) ->Void){
+ HttpClient.request(.storageSize) { [weak self](result:StorageSizeModel,res) in
+ guard let self = self else{return}
+ if result.isSuccess{
+ storageSize = result.data
+ }
+ completion(result)
+ }
+ }
}
+
+
+
+
extension UserModel{
private func getToken()->String?{
if let value = UserDefaults.standard.value(forKey: UserModel.cacheKey),let token = value as? String{
//
import UIKit
+import Kingfisher
class MineHeaderView: BaseView {
let userInfo = MineUserInfoView()
let banner = MineBannerView()
v.image = UIImage(named: "head")
v.yc.setCornerRadius(40)
v.backgroundColor = .white
+
}
titleLabel.do { (v) in
v.textColor = .rgb(0x121212)
v.font = .regular(26)
v.textAlignment = .left
- v.text = "Juliaxxxx"
}
deviceLabel.do { (v) in
m.top.equalToSuperview().inset(10)
}
}
+ func updateUI(){
+ titleLabel.text = CacheManager.shared.user.info.userName
+ icon.kf.setImage(with:CacheManager.shared.user.info.avatar.yc.asUrl )
+
+ }
@objc func tapAction(){
App.shared.goToPage(UserInfoVC())
}
class MineVC: BaseVC{
let tableView = UITableView(frame: .zero, style: .plain)
let list:[MineCellType] = [.instructions,.update,.more,.feeback,.about]
+ let headerView = MineHeaderView(frame: CGRect(x: 0, y: 0, width: kScreenWid, height: 266))
override func viewDidLoad() {
super.viewDidLoad()
v.sectionHeaderHeight = 52
v.separatorStyle = .none
v.register(MineCell.self, forCellReuseIdentifier: MineCell.reuseID)
- v.tableHeaderView = MineHeaderView(frame: CGRect(x: 0, y: 0, width: kScreenWid, height: 266))
+ v.tableHeaderView = headerView
}
make.top.equalTo(kNavBtm)
}
}
+ override func setupData() {
+
+ CacheManager.shared.user.getStorageSize { result in
+
+ }
+ }
+ override func viewDidAppear(_ animated: Bool) {
+ super.viewDidAppear(animated)
+ headerView.userInfo.updateUI()
+ }
}
extension MineVC:UITableViewDelegate,UITableViewDataSource {
else{
valueLabel.isHidden = true
}
- valueLabel.text = "123"
+ let info = CacheManager.shared.user.info
+ if type == .nickName {
+ valueLabel.text = info.userName
+ }
+ else if type == .gender {
+ //1表示男,0表示女,2表示保密
+ valueLabel.text = info.genderText
+ }
+ else if type == .area {
+ valueLabel.text = info.countryName
+ }
}
}
let tableView = UITableView(frame: .zero, style: .plain)
var list:[GenderType] = [.man,.female,]
var currentType = GenderType.man
+ var didSelected:((GenderType)->Void)?
override func viewDidLoad() {
super.viewDidLoad()
let data = list[indexPath.row]
currentType = data
tableView.reloadData()
+ didSelected?(currentType)
+ navigationController?.popViewController(animated: true)
+
}
}
case .nickName:
App.shared.goToPage(NickNameVC())
case .gender:
- App.shared.goToPage(GenderVC())
+ genderAction()
case .area:
- App.shared.goToPage(AreaVC())
+ areaAction()
break
default:
break
extension UserInfoVC{
+ func genderAction(){
+ let vc = GenderVC()
+ vc.didSelected = {[weak self] model in
+ guard let self = self else{return}
+ CacheManager.shared.user.info.gender = model.value
+ tableView.reloadData()
+
+ var params:[String:Any] = [:]
+ params["gender"] = CacheManager.shared.user.info.gender
+
+ HttpClient.request(.updateUserInfo(param: params)) { (model:ResponseBaseModel,res) in
+ if model.isSuccess{
+
+ }
+ }
+ }
+ App.shared.goToPage(vc)
+ }
+ func areaAction(){
+ let vc = ContryListVC()
+ vc.didSelected = {[weak self] model in
+ guard let self = self else{return}
+ CacheManager.shared.user.info.countryName = model.name
+ CacheManager.shared.user.info.countryId = model.id
+ tableView.reloadData()
+
+ var params:[String:Any] = [:]
+ params["countryId"] = model.id
+
+ HttpClient.request(.updateUserInfo(param: params)) { (model:ResponseBaseModel,res) in
+ if model.isSuccess{
+
+ }
+ }
+ }
+ App.shared.goToPage(vc)
+ }
+
+
+
+
+
@objc func pickImageAction() -> Void {
imgPicker.showImagePicker(from: App.shared.topVC()) {[weak self] image in
guard let self = self else { return }
--- /dev/null
+//
+// MusicCategoryModel.swift
+// ShenYin
+//
+// Created by liangshi on 2025/9/29.
+//
+import HandyJSON
+
+class MusicCategoryRoot:ResponseBaseModel {
+ var data = [MusicCategory]()
+}
+
+class MusicCategory:HandyJSON {
+ var id = ""
+ var name = ""
+ var ord = ""
+ var enable = ""
+ required public init() { }
+}
-//
-// Untitled.swift
-// ShenYin
-//
-// Created by liangshi on 2025/8/5.
-//
-//import UIKit
-//import TabPageViewController
-//
-//class SleepVC:TabPageViewController{
-// override init() {
-// super.init()
-// tabItems = [(SleepPageVC(), "First"),
-// (SleepPageVC(), "Second1"),
-// (SleepPageVC(), "Second2"),
-// (SleepPageVC(), "Second3"),
-// (SleepPageVC(), "Second411111111"),
-// (SleepPageVC(), "Second5"),
-// (SleepPageVC(), "Second6"),
-// ]
-//
-//
-// // 初始化配置
-// var option = TabPageOption()
-//// option.tabWidth = view.frame.width / CGFloat(tabItems.count)
-// option.currentColor = .red
-// option.currentBarHeight = 5
-// // 标签文字大小
-// option.fontSize = 16
-//
-// // 当前选中标签的颜色
-// option.currentColor = .systemBlue
-//
-// // 未选中标签的颜色
-// option.defaultColor = .darkGray
-//
-// // 标签栏高度
-// option.tabHeight = 44
-//
-// // 标签项间距
-// option.tabMargin = 16
-//
-// // 标签栏背景色
-// option.tabBackgroundColor = .white
-//
-// // 页面背景色
-// option.pageBackgoundColor = .yellow
-//
-// // 是否透明(影响导航栏)
-// option.isTranslucent = true
-//
-//
-// // 滑动时是否隐藏标签栏
-// option.hidesTopViewOnSwipeType = .all // .none / .tabBar / .navigationBar / .all
-//
-// // 应用配置
-// self.option = option
-// }
-//
-// @MainActor required init?(coder aDecoder: NSCoder) {
-// fatalError("init(coder:) has not been implemented")
-// }
-//
-// override func viewDidLoad() {
-// super.viewDidLoad()
-//// self.navBar.title = "睡眠"
-// view.backgroundColor = .color(.bgColor)
-//
-//
-//
-// }
-//// override func setupViews() {
-////
-//// }
-//// override func setupLayout() {
-////
-//// }
-//}
import Foundation
import JXSegmentedView
class SleepVC: BaseVC {
- private var titles = ["专注","旋律","自然","都市","冥想"]
+// private var titles = ["专注","旋律","自然","都市","冥想"]
private let segmentedDataSource = JXSegmentedTitleDataSource()
private let segmentedView = JXSegmentedView()
private lazy var listContainerView: JXSegmentedListContainerView! = {
return view
}()
+ let vm = SleepVM()
override func viewDidLoad() {
super.viewDidLoad()
segmentedDataSource.isItemSpacingAverageEnabled = true
segmentedDataSource.isTitleColorGradientEnabled = true
// segmentedDataSource.titles = titles.map{"\($0.name)"}
- segmentedDataSource.titles = titles
+ segmentedDataSource.titles = vm.catogory.map{"\($0.name)"}
segmentedView.backgroundColor = .clear
//配置指示器
}
// self.tz_addPopGesture(to: listContainerView.scrollView)
}
+
+ override func setupData() {
+ vm.getCagory { [weak self ]model in
+ guard let self = self else{return}
+
+ segmentedDataSource.titles = vm.catogory.map{"\($0.name)"}
+ segmentedView.dataSource = segmentedDataSource
+
+ listContainerView.reloadData()
+ segmentedView.reloadData()
+
+ }
+ }
}
extension SleepVC: JXSegmentedListContainerViewListDelegate {
--- /dev/null
+//
+// SleepVM.swift
+// ShenYin
+//
+// Created by liangshi on 2025/9/29.
+//
+
+class SleepVM:BaseVM{
+ var catogory = [MusicCategory]()
+
+ public func getCagory( completion:@escaping (_ result:MusicCategoryRoot) ->Void) {
+ let api = CommomApi.musicCategory
+ HttpClient.request(api) {[weak self] (model:MusicCategoryRoot,res) in
+ guard let self = self else {return}
+ if model.isSuccess{
+ catogory = model.data
+ }
+ completion(model)
+ }
+ }
+
+ public func getCagoryList(categoryId:String,page:Int, completion:@escaping (_ result:ResponseBaseModel) ->Void) {
+ let api = CommomApi.muiscCategoryList(categoryId: categoryId, page: 1)
+ HttpClient.request(api) {[weak self] (model:ResponseBaseModel,res) in
+ guard let self = self else {return}
+ if model.isSuccess{
+ }
+ completion(model)
+ }
+ }
+}
App.shared.goToLogin()
}
func tokenIsValid(){
- HttpClient.request(CommomApi.token) { [weak self](model:ResponseBaseModel,res) in
+ HttpClient.request(CommomApi.token) { [weak self](model:UserInfoRoot,res) in
guard let self = self else{return}
if model.isSuccess{
-
+ user.info = model.data
}
else{
logout()