Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
G
galaxy-iOS
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
mobile-group
galaxy-iOS
Commits
4fa16fab
Commit
4fa16fab
authored
Oct 10, 2025
by
Alex朱枝文
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
资源相关
parent
051ce9c5
Changes
10
Show whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
450 additions
and
633 deletions
+450
-633
YHResourceDetailViewController.swift
...y(社区)/Resource(资源)/C/YHResourceDetailViewController.swift
+41
-50
YHResourceViewController.swift
...mmunity(社区)/Resource(资源)/C/YHResourceViewController.swift
+42
-28
YHResourceListModel.swift
...es/Community(社区)/Resource(资源)/M/YHResourceListModel.swift
+160
-167
YHResourceCategoryView.swift
...Community(社区)/Resource(资源)/V/YHResourceCategoryView.swift
+62
-103
YHResourceDetailBaseInfoCell.swift
...ity(社区)/Resource(资源)/V/YHResourceDetailBaseInfoCell.swift
+13
-7
YHResourceDetailDemandCell.swift
...unity(社区)/Resource(资源)/V/YHResourceDetailDemandCell.swift
+6
-5
YHResourceDetailDocumentsCell.swift
...ty(社区)/Resource(资源)/V/YHResourceDetailDocumentsCell.swift
+1
-1
YHResourceDetailHeaderCell.swift
...unity(社区)/Resource(资源)/V/YHResourceDetailHeaderCell.swift
+24
-6
YHResourceTableViewCell.swift
...ommunity(社区)/Resource(资源)/V/YHResourceTableViewCell.swift
+18
-66
YHResourceViewModel.swift
...s/Community(社区)/Resource(资源)/VM/YHResourceViewModel.swift
+83
-200
No files found.
galaxy/galaxy/Classes/Modules/Community(社区)/Resource(资源)/C/YHResourceDetailViewController.swift
View file @
4fa16fab
...
...
@@ -12,7 +12,8 @@ import SnapKit
class
YHResourceDetailViewController
:
YHBaseViewController
{
// MARK: - Properties
var
resourceModel
:
YHResourceListModel
?
var
companyId
:
Int
=
0
// 只需要传入公司ID
var
detailModel
:
YHResourceDetailModel
?
// 详情数据
var
isMyCompany
:
Bool
=
false
{
didSet
{
...
...
@@ -20,6 +21,10 @@ class YHResourceDetailViewController: YHBaseViewController {
}
}
private
lazy
var
viewModel
:
YHResourceViewModel
=
{
return
YHResourceViewModel
()
}()
private
lazy
var
messageHandler
:
YHIMMessageHandler
=
{
return
YHIMMessageHandler
(
viewController
:
self
,
...
...
@@ -29,7 +34,7 @@ class YHResourceDetailViewController: YHBaseViewController {
// MARK: - UI Components
// 背景图
- 改为在tableView后面
// 背景图
private
lazy
var
bgIcon
:
UIImageView
=
{
let
view
=
UIImageView
()
view
.
image
=
UIImage
(
named
:
"resource_detail_bg"
)
...
...
@@ -87,7 +92,6 @@ class YHResourceDetailViewController: YHBaseViewController {
gk_backImage
=
UIImage
(
named
:
"nav_black_24"
)
view
.
addSubview
(
bgIcon
)
view
.
addSubview
(
tableView
)
// 添加底部操作栏
view
.
addSubview
(
bottomActionView
)
bottomActionView
.
addSubview
(
contactButton
)
setupConstraints
()
...
...
@@ -96,21 +100,15 @@ class YHResourceDetailViewController: YHBaseViewController {
private
func
updateViewIsMine
()
{
gk_navTitle
=
isMyCompany
?
"我的企业"
:
"企业详情"
if
isMyCompany
{
bottomActionView
.
isHidden
=
true
}
else
{
bottomActionView
.
isHidden
=
false
}
bottomActionView
.
isHidden
=
isMyCompany
updateRightBarButtonItem
()
}
private
func
setupConstraints
()
{
// 背景图约束 - 参照YHMemberCenterViewController
bgIcon
.
snp
.
makeConstraints
{
make
in
make
.
top
.
left
.
right
.
bottom
.
equalToSuperview
()
}
// tableView约束
tableView
.
snp
.
makeConstraints
{
make
in
make
.
left
.
right
.
equalToSuperview
()
make
.
top
.
equalTo
(
k_Height_NavigationtBarAndStatuBar
)
...
...
@@ -130,7 +128,6 @@ class YHResourceDetailViewController: YHBaseViewController {
make
.
height
.
equalTo
(
46
)
}
// 不需要设置contentInset,让内容从导航栏下方开始
tableView
.
tableFooterView
=
UIView
(
frame
:
CGRect
(
x
:
0
,
y
:
0
,
width
:
KScreenWidth
,
height
:
0.01
))
}
...
...
@@ -154,29 +151,42 @@ class YHResourceDetailViewController: YHBaseViewController {
gk_navRightBarButtonItem
=
rightButtonItem
gk_navItemRightSpace
=
16
}
}
// MARK: - Data
private
func
loadData
()
{
guard
let
_
=
resourceModel
else
{
return
}
tableView
.
reloadData
(
)
incrementViewCount
()
guard
companyId
>
0
else
{
YHHUD
.
flash
(
message
:
"公司ID无效"
)
return
}
private
func
incrementViewCount
()
{
resourceModel
?
.
incrementViewCount
()
// 直接调用详情接口
YHHUD
.
show
(
.
progress
(
message
:
"加载中..."
))
viewModel
.
getCompanyDetail
(
companyId
:
companyId
)
{
[
weak
self
]
detail
,
error
in
guard
let
self
=
self
else
{
return
}
DispatchQueue
.
main
.
async
{
YHHUD
.
hide
()
if
let
detail
=
detail
{
self
.
detailModel
=
detail
self
.
tableView
.
reloadData
()
}
else
if
let
error
=
error
{
YHHUD
.
flash
(
message
:
error
)
}
}
}
}
// MARK: - Actions
@objc
private
func
shareButtonClicked
()
{
//
//
分享功能
}
@objc
private
func
moreButtonClicked
()
{
//
//
更多操作
}
@objc
private
func
contactButtonClicked
()
{
...
...
@@ -184,9 +194,10 @@ class YHResourceDetailViewController: YHBaseViewController {
YHOneKeyLoginManager
.
shared
.
oneKeyLogin
()
return
}
messageHandler
.
gotoChatVC
(
senderID
:
""
)
if
let
detailModel
=
detailModel
,
!
detailModel
.
yh_id
.
isEmpty
{
messageHandler
.
gotoChatVC
(
senderID
:
detailModel
.
yh_id
)
}
}
}
// MARK: - UITableViewDataSource & UITableViewDelegate
...
...
@@ -202,12 +213,10 @@ extension YHResourceDetailViewController: UITableViewDataSource, UITableViewDele
}
func
tableView
(
_
tableView
:
UITableView
,
cellForRowAt
indexPath
:
IndexPath
)
->
UITableViewCell
{
guard
let
model
=
resource
Model
else
{
guard
let
model
=
detail
Model
else
{
return
UITableViewCell
()
}
let
hasDocuments
=
!
model
.
images
.
isEmpty
switch
indexPath
.
section
{
case
0
:
guard
let
cell
=
tableView
.
dequeueReusableCell
(
withIdentifier
:
"HeaderCell"
,
for
:
indexPath
)
as?
YHResourceDetailHeaderCell
else
{
...
...
@@ -224,37 +233,23 @@ extension YHResourceDetailViewController: UITableViewDataSource, UITableViewDele
return
cell
case
2
:
if
hasDocuments
{
guard
let
cell
=
tableView
.
dequeueReusableCell
(
withIdentifier
:
"DemandCell"
,
for
:
indexPath
)
as?
YHResourceDetailDemandCell
else
{
return
UITableViewCell
()
}
cell
.
configure
(
with
:
model
)
return
cell
}
else
{
guard
let
cell
=
tableView
.
dequeueReusableCell
(
withIdentifier
:
"DemandCell"
,
for
:
indexPath
)
as?
YHResourceDetailDemandCell
else
{
return
UITableViewCell
()
}
cell
.
configure
(
with
:
model
)
return
cell
}
case
3
:
guard
let
cell
=
tableView
.
dequeueReusableCell
(
withIdentifier
:
"DocumentsCell"
,
for
:
indexPath
)
as?
YHResourceDetailDocumentsCell
else
{
return
UITableViewCell
()
}
cell
.
configure
(
with
:
model
.
images
)
let
images
=
model
.
company_information
.
map
{
$0
.
url
}
cell
.
configure
(
with
:
images
)
cell
.
onImageTapped
=
{
[
weak
self
]
index
in
self
?
.
showImageBrowser
(
at
:
index
)
}
cell
.
onImageHeightChanged
=
{
[
weak
self
]
in
guard
let
self
=
self
else
{
return
}
// NSObject.cancelPreviousPerformRequests(
// withTarget: self,
// selector: #selector(self.performBatchReload),
// object: nil
// )
// self.perform(#selector(self.performBatchReload), with: indexPath, afterDelay: 0.01)
// // 使用 performBatchUpdates 避免动画跳动
UIView
.
performWithoutAnimation
{
self
.
tableView
.
reloadRows
(
at
:
[
indexPath
],
with
:
.
none
)
}
...
...
@@ -266,12 +261,6 @@ extension YHResourceDetailViewController: UITableViewDataSource, UITableViewDele
}
}
@objc
private
func
performBatchReload
(
indexPath
:
IndexPath
)
{
UIView
.
performWithoutAnimation
{
self
.
tableView
.
reloadRows
(
at
:
[
indexPath
],
with
:
.
none
)
}
}
func
tableView
(
_
tableView
:
UITableView
,
heightForRowAt
indexPath
:
IndexPath
)
->
CGFloat
{
return
UITableView
.
automaticDimension
}
...
...
@@ -292,10 +281,8 @@ extension YHResourceDetailViewController: UITableViewDataSource, UITableViewDele
return
0.01
}
// 关键改动:参照YHMemberCenterViewController的scrollViewDidScroll实现
func
scrollViewDidScroll
(
_
scrollView
:
UIScrollView
)
{
if
scrollView
.
contentOffset
.
y
>
0
{
// 向上滚动
var
alpha
=
scrollView
.
contentOffset
.
y
/
k_Height_NavigationtBarAndStatuBar
if
alpha
>
1.0
{
alpha
=
1.0
...
...
@@ -311,7 +298,11 @@ extension YHResourceDetailViewController: UITableViewDataSource, UITableViewDele
}
private
func
showImageBrowser
(
at
index
:
Int
)
{
guard
let
images
=
resourceModel
?
.
images
else
{
return
}
print
(
"显示图片浏览器,索引:
\(
index
)
,共
\(
images
.
count
)
张"
)
guard
let
companyInformation
=
detailModel
?
.
company_information
else
{
return
}
let
images
=
companyInformation
.
map
{
$0
.
url
}
if
images
.
count
>
index
,
images
.
count
>
0
{
printLog
(
"显示图片浏览器,索引:
\(
index
)
,共
\(
images
.
count
)
张"
)
YHPictureReviewManager
.
shared
.
showNetWorkPicturs
(
curIndex
:
index
,
arrPicturs
:
images
)
}
}
}
galaxy/galaxy/Classes/Modules/Community(社区)/Resource(资源)/C/YHResourceViewController.swift
View file @
4fa16fab
...
...
@@ -3,7 +3,7 @@
// galaxy
//
// Created by alexzzw on 2025/9/24.
// Copyright
Â
© 2025 https://www.galaxy-immi.com. All rights reserved.
// Copyright © 2025 https://www.galaxy-immi.com. All rights reserved.
//
import
UIKit
...
...
@@ -33,6 +33,9 @@ class YHResourceViewController: YHBaseViewController {
// 筛选条件
var
selectedCategories
:
[
YHResourceCategory
]
=
[]
// 行业分类数据
var
allCategories
:
[
YHResourceCategory
]
=
[]
// MARK: - UI Components
// 自定义搜索视图
...
...
@@ -121,7 +124,6 @@ class YHResourceViewController: YHBaseViewController {
}()
// 空状态视图
private
lazy
var
noDataView
:
YHEmptyDataView
=
{
let
view
=
YHEmptyDataView
.
createView
(
"暂无内容"
,
kEmptyOrderBgName
)
view
.
frame
=
CGRect
(
x
:
0
,
y
:
0
,
width
:
KScreenWidth
,
height
:
164
)
...
...
@@ -146,7 +148,8 @@ class YHResourceViewController: YHBaseViewController {
override
func
viewDidLoad
()
{
super
.
viewDidLoad
()
setupUI
()
addDefaultData
()
loadCategories
()
// 先加载分类数据
// addDefaultData()
getData
()
}
...
...
@@ -162,7 +165,8 @@ class YHResourceViewController: YHBaseViewController {
}
func
handleTypeChangeNotification
(
_
userInfo
:
[
AnyHashable
:
Any
])
{
guard
let
selectTypeKey
=
userInfo
[
YHResourceViewController
.
selectTypeKey
]
as?
String
,
let
type
=
YHResourceFilterType
(
rawValue
:
selectTypeKey
)
else
{
guard
let
selectTypeKey
=
userInfo
[
YHResourceViewController
.
selectTypeKey
]
as?
String
,
let
type
=
YHResourceFilterType
(
rawValue
:
selectTypeKey
)
else
{
return
}
setResourceType
(
type
)
...
...
@@ -186,7 +190,7 @@ private extension YHResourceViewController {
view
.
addSubview
(
noDataView
)
view
.
addSubview
(
publishButton
)
// 分类视图要最后添加
,
确保在最上层
// 分类视图要最后添加
,
确保在最上层
view
.
addSubview
(
maskView
)
view
.
addSubview
(
categoryView
)
...
...
@@ -206,6 +210,7 @@ private extension YHResourceViewController {
make
.
left
.
right
.
equalToSuperview
()
make
.
height
.
equalTo
(
44
)
}
serviceButton
.
setContentCompressionResistancePriority
(
.
required
,
for
:
.
horizontal
)
demandButton
.
setContentCompressionResistancePriority
(
.
required
,
for
:
.
horizontal
)
industryButton
.
setContentCompressionResistancePriority
(
.
defaultLow
,
for
:
.
horizontal
)
...
...
@@ -235,7 +240,6 @@ private extension YHResourceViewController {
categoryView
.
snp
.
makeConstraints
{
make
in
make
.
left
.
right
.
equalToSuperview
()
make
.
top
.
equalTo
(
filterContainerView
.
snp
.
bottom
)
// 使用变量保存高度约束的引用
self
.
categoryViewHeightConstraint
=
make
.
height
.
equalTo
(
0
)
.
constraint
}
...
...
@@ -303,6 +307,20 @@ private extension YHResourceViewController {
}
}
/// 加载行业分类数据
func
loadCategories
()
{
viewModel
.
getResourceCategories
{
[
weak
self
]
categories
,
error
in
guard
let
self
=
self
else
{
return
}
if
let
categories
=
categories
{
self
.
allCategories
=
categories
self
.
categoryView
.
setCategories
(
categories
)
}
else
if
let
error
=
error
{
print
(
"加载分类失败:
\(
error
)
"
)
}
}
}
func
getData
()
{
loadFirstData
()
}
...
...
@@ -313,21 +331,22 @@ private extension YHResourceViewController {
YHHUD
.
show
(
.
progress
(
message
:
"加载中..."
))
}
DispatchQueue
.
global
()
.
async
{
self
.
viewModel
.
getResourceList
(
firstFlag
:
true
)
{
[
weak
self
]
success
,
message
in
viewModel
.
getResourceList
(
firstFlag
:
true
)
{
[
weak
self
]
success
,
message
in
guard
let
self
=
self
else
{
return
}
DispatchQueue
.
main
.
async
{
YHHUD
.
hide
()
if
success
,
let
arrData
=
self
.
viewModel
.
arrResourceData
,
arrData
.
count
>
0
{
let
arrString
=
arrData
.
toJSONString
()
UserDefaults
.
standard
.
set
(
arrString
,
forKey
:
"resourceFirstPageData"
)
UserDefaults
.
standard
.
synchronize
()
}
else
if
!
success
,
let
errorMessage
=
message
{
// if success, let arrData = self.viewModel.arrResourceData, arrData.count > 0 {
// let arrString = arrData.toJSONString()
// UserDefaults.standard.set(arrString, forKey: "resourceFirstPageData")
// UserDefaults.standard.synchronize()
// } else if !success, let errorMessage = message {
// YHHUD.flash(message: errorMessage)
// }
if
!
success
,
let
errorMessage
=
message
{
YHHUD
.
flash
(
message
:
errorMessage
)
}
self
.
resourceTableView
.
es
.
stopPullToRefresh
()
if
self
.
viewModel
.
hasMoreForResource
==
false
{
...
...
@@ -339,11 +358,9 @@ private extension YHResourceViewController {
}
}
}
}
func
loadMoreData
()
{
DispatchQueue
.
global
()
.
async
{
self
.
viewModel
.
getResourceList
(
firstFlag
:
false
)
{
[
weak
self
]
_
,
_
in
viewModel
.
getResourceList
(
firstFlag
:
false
)
{
[
weak
self
]
_
,
_
in
guard
let
self
=
self
else
{
return
}
DispatchQueue
.
main
.
asyncAfter
(
wallDeadline
:
.
now
()
+
0.35
,
execute
:
{
...
...
@@ -357,7 +374,6 @@ private extension YHResourceViewController {
})
}
}
}
func
updateUI
()
{
let
hasData
=
viewModel
.
arrResourceData
?
.
count
??
0
>
0
...
...
@@ -454,7 +470,6 @@ private extension YHResourceViewController {
industryButton
.
setImage
(
UIImage
(
named
:
"resource_filter_up"
),
for
:
.
normal
)
}
// 修改隐藏动画方法
@objc
func
hideCategoryView
()
{
// 高度约束动画
UIView
.
animate
(
withDuration
:
0.3
,
delay
:
0
,
options
:
.
curveEaseIn
,
animations
:
{
...
...
@@ -510,10 +525,8 @@ extension YHResourceViewController: YHCustomSearchViewDelegate {
func
searchView
(
_
searchView
:
YHCustomSearchView
,
didSearchWithText
text
:
String
?)
{
viewModel
.
searchKeyword
=
text
if
text
?
.
isEmpty
==
true
{
getData
()
}
}
func
searchViewDidBeginEditing
(
_
searchView
:
YHCustomSearchView
)
{
// 搜索开始编辑时的处理
...
...
@@ -521,7 +534,6 @@ extension YHResourceViewController: YHCustomSearchViewDelegate {
func
searchViewDidEndEditing
(
_
searchView
:
YHCustomSearchView
)
{
// 搜索结束编辑时的处理
getData
()
}
}
...
...
@@ -538,8 +550,9 @@ extension YHResourceViewController: UITableViewDelegate, UITableViewDataSource {
let
cell
=
tableView
.
dequeueReusableCell
(
withIdentifier
:
YHResourceTableViewCell
.
cellReuseIdentifier
,
for
:
indexPath
)
as?
YHResourceTableViewCell
else
{
return
UITableViewCell
()
}
cell
.
resourceModel
=
datas
[
indexPath
.
row
]
let
model
=
datas
[
indexPath
.
row
]
model
.
isService
=
viewModel
.
currentType
==
.
service
cell
.
resourceModel
=
model
return
cell
}
...
...
@@ -552,8 +565,10 @@ extension YHResourceViewController: UITableViewDelegate, UITableViewDataSource {
tableView
.
deselectRow
(
at
:
indexPath
,
animated
:
true
)
guard
let
model
=
viewModel
.
arrResourceData
?[
indexPath
.
row
]
else
{
return
}
// 跳转到详情页
let
vc
=
YHResourceDetailViewController
()
vc
.
resourceModel
=
model
vc
.
companyId
=
model
.
id
navigationController
?
.
pushViewController
(
vc
,
animated
:
true
)
}
}
...
...
@@ -586,15 +601,14 @@ extension YHResourceViewController: YHResourceCategoryViewDelegate {
selectedCategories
=
categories
viewModel
.
selectedCategories
=
categories
updateIndustryButtonTitle
()
if
isSet
{
// 隐藏分类视图
hideCategoryView
()
}
// 重新加载数据
getData
()
}
}
}
// MARK: - 枚举定义
...
...
galaxy/galaxy/Classes/Modules/Community(社区)/Resource(资源)/M/YHResourceListModel.swift
View file @
4fa16fab
...
...
@@ -9,220 +9,190 @@
import
UIKit
import
SmartCodable
// MARK: - 资源列表模型
class
YHResourceListModel
:
SmartCodable
{
// MARK: - 公司列表响应模型
class
YHResourceListResponse
:
SmartCodable
{
required
init
()
{}
var
total
:
Int
=
0
var
list
:
[
YHResourceListModel
]
=
[]
}
// MARK: - 公司头像模型
class
YHCompanyAvatar
:
SmartCodable
{
required
init
()
{}
var
needNewLine
:
Bool
?
var
name
:
String
=
""
var
url
:
String
=
""
}
// MARK: - 基本信息
var
id
:
String
=
""
var
title
:
String
=
""
var
content
:
String
=
""
var
company_name
:
String
=
""
var
company_logo
:
String
=
""
var
contact_name
:
String
=
""
var
contact_phone
:
String
=
""
var
contact_wechat
:
String
=
""
var
category_id
:
String
=
""
var
category_name
:
String
=
""
var
type
:
String
=
""
// service 或 demand
var
status
:
Int
=
0
// 0-待审核 1-已发布 2-已下架
var
is_favorite
:
Bool
=
false
var
favorite_count
:
Int
=
0
var
view_count
:
Int
=
0
var
created_time
:
String
=
""
var
updated_time
:
String
=
""
var
expires_time
:
String
=
""
var
images
:
[
String
]
=
[]
var
tags
:
[
String
]
=
[]
var
location
:
String
=
""
var
price
:
String
=
""
var
price_unit
:
String
=
""
// MARK: - 扩展属性
var
user_id
:
String
=
""
var
user_name
:
String
=
""
var
user_avatar
:
String
=
""
var
certification_status
:
Int
=
0
// 0-未认证 1-已认证
var
priority
:
Int
=
0
// 优先级,用于排序
var
click_count
:
Int
=
0
// 点击量
var
comment_count
:
Int
=
0
// 评论数
var
share_count
:
Int
=
0
// 分享数
var
service_area
:
String
=
""
// 服务区域
var
min_price
:
String
=
""
// 最低价格
var
max_price
:
String
=
""
// 最高价格
var
service_duration
:
String
=
""
// 服务周期
var
qualification
:
String
=
""
// 资质证明
var
business_hours
:
String
=
""
// 营业时间
var
website
:
String
=
""
// 公司网站
var
email
:
String
=
""
// 邮箱
var
address
:
String
=
""
// 详细地址
// MARK: - UI相关属性
var
cell_width
:
CGFloat
=
0
var
cell_height
:
CGFloat
=
0
// MARK: - 公司文档模型
class
YHCompanyDocument
:
SmartCodable
{
required
init
()
{}
// MARK: - 计算属性
var
name
:
String
=
""
var
url
:
String
=
""
}
/// 显示时间(相对时间格式)
var
displayTime
:
String
{
return
created_time
.
toDisplayTime
()
}
// MARK: - 公司详情模型
class
YHResourceDetailModel
:
SmartCodable
{
required
init
()
{}
/// 显示价格
var
displayPrice
:
String
{
if
price
.
isEmpty
{
if
!
min_price
.
isEmpty
&&
!
max_price
.
isEmpty
{
return
"
\(
min_price
)
-
\(
max_price
)
"
+
(
price_unit
.
isEmpty
?
""
:
"/"
+
price_unit
)
}
else
if
!
min_price
.
isEmpty
{
return
"¥
\(
min_price
)
起"
+
(
price_unit
.
isEmpty
?
""
:
"/"
+
price_unit
)
}
return
"面议"
}
return
"¥"
+
price
+
(
price_unit
.
isEmpty
?
""
:
"/"
+
price_unit
)
}
var
contract_avatar
:
YHCompanyAvatar
?
var
id
:
Int
=
0
var
company_name
:
String
=
""
var
company_english_name
:
String
=
""
var
customer_id
:
Int
=
0
var
customer_name
:
String
=
""
var
last_processed_time
:
String
=
""
var
processor_id
:
Int
=
0
var
processor
:
String
=
""
var
settlement_status
:
Int
=
0
var
settlement_status_str
:
String
=
""
var
resource_provided
:
String
=
""
var
demand_published
:
String
=
""
var
settlement_time
:
String
=
""
var
industry_type
:
Int
=
0
var
industry_type_str
:
String
=
""
var
company_introduction
:
String
=
""
// 公司介绍
var
company_business
:
String
=
""
// 主营业务
var
company_information
:
[
YHCompanyDocument
]
=
[]
// 公司资料图片
var
created_at
:
String
=
""
var
updated_at
:
String
=
""
var
yh_id
:
String
=
""
//
/ 类型显示名称
var
typeDisplayName
:
String
{
return
type
==
"service"
?
"企业服务"
:
"企业需求
"
//
计算属性
var
companyLogoUrl
:
String
{
return
contract_avatar
?
.
url
??
"
"
}
/// 状态显示名称
var
statusDisplayName
:
String
{
switch
status
{
case
0
:
return
"待审核"
case
1
:
return
"已发布"
case
2
:
return
"已下架"
default
:
return
"未知"
}
var
displayName
:
String
{
return
company_name
.
isEmpty
?
company_english_name
:
company_name
}
}
/// 认证状态显示
var
certificationDisplayName
:
String
{
return
certification_status
==
1
?
"已认证"
:
"未认证"
}
// MARK: - 资源列表模型(公司信息)
class
YHResourceListModel
:
SmartCodable
{
/// 是否已认证
var
isCertified
:
Bool
{
return
certification_status
==
1
}
required
init
()
{}
var
isService
=
true
/// 是否为服务类型
var
isService
:
Bool
{
return
type
==
"service"
}
// MARK: - 基本信息(匹配列表API)
var
id
:
Int
=
0
var
company_avatar
:
YHCompanyAvatar
?
var
company_name
:
String
=
""
var
company_english_name
:
String
=
""
var
resource_provided
:
String
=
""
// 提供的服务
var
demand_published
:
String
=
""
// 发布的需求
var
industry_type
:
Int
=
0
var
industry_type_str
:
String
=
""
// MARK: - 详情字段(从详情接口获取后填充)
var
company_introduction
:
String
=
""
// 公司介绍
var
company_business
:
String
=
""
// 主营业务
var
company_information
:
[
YHCompanyDocument
]
=
[]
// 公司资料
var
settlement_status
:
Int
=
0
var
settlement_status_str
:
String
=
""
/// 是否为需求类型
var
isDemand
:
Bool
{
return
type
==
"demand"
}
// MARK: - 计算属性
/// 是否已过期
var
isExpired
:
Bool
{
guard
!
expires_time
.
isEmpty
else
{
return
false
}
let
formatter
=
DateFormatter
()
formatter
.
dateFormat
=
"yyyy-MM-dd HH:mm:ss"
guard
let
expireDate
=
formatter
.
date
(
from
:
expires_time
)
else
{
return
false
}
return
Date
()
>
expireDate
/// 公司Logo URL
var
companyLogoUrl
:
String
{
return
company_avatar
?
.
url
??
""
}
/// 剩余天数
var
remainingDays
:
Int
{
guard
!
expires_time
.
isEmpty
else
{
return
-
1
}
let
formatter
=
DateFormatter
()
formatter
.
dateFormat
=
"yyyy-MM-dd HH:mm:ss"
guard
let
expireDate
=
formatter
.
date
(
from
:
expires_time
)
else
{
return
-
1
}
let
calendar
=
Calendar
.
current
let
components
=
calendar
.
dateComponents
([
.
day
],
from
:
Date
(),
to
:
expireDate
)
return
components
.
day
??
-
1
/// 显示名称(优先显示中文名)
var
displayName
:
String
{
return
company_name
.
isEmpty
?
company_english_name
:
company_name
}
///
热度值(综合点击、收藏、分享等)
var
h
otScore
:
Int
{
return
view_count
+
favorite_count
*
2
+
share_count
*
3
+
comment_count
*
1
///
是否有英文名
var
h
asEnglishName
:
Bool
{
return
!
company_english_name
.
isEmpty
}
///
第一张图片URL
var
firstImageUrl
:
String
{
return
i
mages
.
first
??
""
///
行业类型显示文本
var
industryDisplayText
:
String
{
return
i
ndustry_type_str
.
isEmpty
?
"其他"
:
industry_type_str
}
/// 是否
有图片
var
has
Images
:
Bool
{
return
!
images
.
isEmpty
/// 是否
提供服务
var
has
ResourceProvided
:
Bool
{
return
!
resource_provided
.
isEmpty
}
///
标签字符串(用逗号分隔)
var
tagsString
:
String
{
return
tags
.
joined
(
separator
:
", "
)
///
是否有需求
var
hasDemandPublished
:
Bool
{
return
!
demand_published
.
isEmpty
}
// MARK: - 计算Cell高度方法
func
didFinishMapping
()
{
if
needNewLine
==
nil
{
needNewLine
=
calculateNeedNewLine
()
/// 服务和需求显示文本
var
serviceInfoText
:
String
{
var
texts
:
[
String
]
=
[]
if
hasResourceProvided
{
texts
.
append
(
"服务:
\(
resource_provided
)
"
)
}
if
hasDemandPublished
{
texts
.
append
(
"需求:
\(
demand_published
)
"
)
}
return
texts
.
joined
(
separator
:
" | "
)
}
func
calculateNeedNewLine
()
->
Bool
{
let
company
=
company_name
.
count
>
0
?
company_name
:
"-"
let
categoryName
=
category_name
.
count
>
0
?
category_name
:
"-"
let
companyWidth
=
YHResourceTableViewCell
.
getLabelWidth
(
company
)
let
categoryNameWidth
=
YHResourceTableViewCell
.
getLabelWidth
(
categoryName
)
return
companyWidth
+
categoryNameWidth
>=
KScreenWidth
-
YHResourceTableViewCell
.
logoWidth
-
YHResourceTableViewCell
.
logoToRight
-
YHResourceTableViewCell
.
arrowWidth
-
2
*
YHResourceTableViewCell
.
marginX
-
YHResourceTableViewCell
.
widthVLine
-
YHResourceTableViewCell
.
marginBetweenVLine
*
2
/// ID字符串(用于兼容旧代码)
var
idString
:
String
{
return
"
\(
id
)
"
}
// MARK: -
便利方法
// MARK: -
兼容旧字段的计算属性
/// 更新收藏状态
func
updateFavoriteStatus
(
_
isFavorite
:
Bool
)
{
is_favorite
=
isFavorite
if
isFavorite
{
favorite_count
+=
1
}
else
{
favorite_count
=
max
(
0
,
favorite_count
-
1
)
/// 企业介绍(兼容旧字段 content)
var
content
:
String
{
return
company_introduction
.
isEmpty
?
(
resource_provided
.
isEmpty
?
demand_published
:
resource_provided
)
:
company_introduction
}
/// 分类名称(兼容旧字段 category_name)
var
category_name
:
String
{
return
industry_type_str
}
///
增加浏览量
func
incrementViewCount
()
{
view_count
+=
1
///
服务周期(兼容旧字段 service_duration)
var
service_duration
:
String
{
return
company_business
}
///
增加分享数
func
incrementShareCount
()
{
share_count
+=
1
///
图片数组(兼容旧字段 images)
var
images
:
[
String
]
{
return
company_information
.
map
{
$0
.
url
}
}
// MARK: - 便利方法
/// 验证数据完整性
func
isValid
()
->
Bool
{
return
!
id
.
isEmpty
&&
!
title
.
isEmpty
&&
!
content
.
isEmpty
&&
!
company_name
.
isEmpty
&&
!
contact_name
.
isEmpty
&&
!
contact_phone
.
isEmpty
&&
!
category_id
.
isEmpty
return
id
>
0
&&
!
displayName
.
isEmpty
}
/// 获取联系方式字符串
func
getContactInfo
()
->
String
{
var
contactInfo
=
contact_name
if
!
contact_phone
.
isEmpty
{
contactInfo
+=
"
\(
contact_phone
)
"
/// 更新详情数据(从详情接口获取后调用)
func
updateWithDetail
(
_
detail
:
YHResourceDetailModel
)
{
self
.
company_introduction
=
detail
.
company_introduction
self
.
company_business
=
detail
.
company_business
self
.
company_information
=
detail
.
company_information
self
.
settlement_status
=
detail
.
settlement_status
self
.
settlement_status_str
=
detail
.
settlement_status_str
// 如果需要,可以更新其他字段
if
self
.
resource_provided
.
isEmpty
{
self
.
resource_provided
=
detail
.
resource_provided
}
if
self
.
demand_published
.
isEmpty
{
self
.
demand_published
=
detail
.
demand_published
}
if
!
contact_wechat
.
isEmpty
{
contactInfo
+=
" 微信:
\(
contact_wechat
)
"
}
return
contactInfo
/// 增加浏览量(兼容方法)
func
incrementViewCount
()
{
// 如果需要调用接口增加浏览量,在这里实现
print
(
"增加浏览量"
)
}
}
...
...
@@ -251,6 +221,29 @@ class YHResourceCategory: SmartCodable {
}
}
// MARK: - 行业分类响应模型
class
YHIndustryTypeResponse
:
SmartCodable
{
required
init
()
{}
var
industry_type
:
[
YHIndustryTypeModel
]
=
[]
}
// MARK: - 行业类型模型
class
YHIndustryTypeModel
:
SmartCodable
{
required
init
()
{}
var
id
:
String
=
""
var
name
:
String
=
""
/// 转换为YHResourceCategory(用于兼容现有UI)
func
toResourceCategory
()
->
YHResourceCategory
{
let
category
=
YHResourceCategory
()
category
.
id
=
id
category
.
name
=
name
return
category
}
}
// MARK: - String Extension
extension
String
{
func
toDisplayTime
()
->
String
{
...
...
galaxy/galaxy/Classes/Modules/Community(社区)/Resource(资源)/V/YHResourceCategoryView.swift
View file @
4fa16fab
...
...
@@ -40,6 +40,11 @@ class YHResourceCategoryView: UIView {
private
lazy
var
bottomButtonContainer
:
UIView
=
{
let
view
=
UIView
()
view
.
backgroundColor
=
.
white
// 添加顶部阴影
view
.
layer
.
shadowColor
=
UIColor
.
black
.
cgColor
view
.
layer
.
shadowOffset
=
CGSize
(
width
:
0
,
height
:
-
2
)
view
.
layer
.
shadowOpacity
=
0.05
view
.
layer
.
shadowRadius
=
4
return
view
}()
...
...
@@ -81,13 +86,11 @@ class YHResourceCategoryView: UIView {
override
init
(
frame
:
CGRect
)
{
super
.
init
(
frame
:
frame
)
setupUI
()
loadCategories
()
}
required
init
?(
coder
:
NSCoder
)
{
super
.
init
(
coder
:
coder
)
setupUI
()
loadCategories
()
}
// MARK: - Setup
...
...
@@ -130,87 +133,17 @@ class YHResourceCategoryView: UIView {
}
}
private
func
loadCategories
()
{
// 模拟数据,实际使用时从接口获取
let
allCategory
=
YHResourceCategory
()
allCategory
.
id
=
"0"
allCategory
.
name
=
"全部行业"
let
category1
=
YHResourceCategory
()
category1
.
id
=
"1"
category1
.
name
=
"金融会计"
let
category2
=
YHResourceCategory
()
category2
.
id
=
"2"
category2
.
name
=
"资讯科技"
let
category3
=
YHResourceCategory
()
category3
.
id
=
"3"
category3
.
name
=
"业务支持"
let
category4
=
YHResourceCategory
()
category4
.
id
=
"4"
category4
.
name
=
"工业制造"
let
category5
=
YHResourceCategory
()
category5
.
id
=
"5"
category5
.
name
=
"建筑工程"
let
category6
=
YHResourceCategory
()
category6
.
id
=
"6"
category6
.
name
=
"地产开发"
let
category7
=
YHResourceCategory
()
category7
.
id
=
"7"
category7
.
name
=
"法律服务"
let
category8
=
YHResourceCategory
()
category8
.
id
=
"8"
category8
.
name
=
"商业贸易"
let
category9
=
YHResourceCategory
()
category9
.
id
=
"9"
category9
.
name
=
"物流运输"
let
category10
=
YHResourceCategory
()
category10
.
id
=
"10"
category10
.
name
=
"餐饮旅游"
let
category11
=
YHResourceCategory
()
category11
.
id
=
"11"
category11
.
name
=
"广播娱乐"
let
category12
=
YHResourceCategory
()
category12
.
id
=
"12"
category12
.
name
=
"艺术文化"
let
category13
=
YHResourceCategory
()
category13
.
id
=
"13"
category13
.
name
=
"体育运动"
let
category14
=
YHResourceCategory
()
category14
.
id
=
"14"
category14
.
name
=
"医疗健康"
let
category15
=
YHResourceCategory
()
category15
.
id
=
"15"
category15
.
name
=
"学术教育"
let
category16
=
YHResourceCategory
()
category16
.
id
=
"16"
category16
.
name
=
"其他"
categories
=
[
allCategory
,
category1
,
category2
,
category3
,
category4
,
category5
,
category6
,
category7
,
category8
,
category9
,
category10
,
category11
,
category12
,
category13
,
category14
,
category15
,
category16
]
// MARK: - Public Methods
/// 设置分类数据(从外部传入,通常来自API)
/// - Parameter categories: 分类数组
func
setCategories
(
_
categories
:
[
YHResourceCategory
])
{
self
.
categories
=
categories
collectionView
.
reloadData
()
}
//
MARK: - Public Methods
//
/ 设置已选中的分类
/// - Parameter categories: 已选中的分类数组
func
setSelectedCategories
(
_
categories
:
[
YHResourceCategory
])
{
selectedCategories
=
categories
collectionView
.
reloadData
()
...
...
@@ -219,7 +152,7 @@ class YHResourceCategoryView: UIView {
// MARK: - Actions
@objc
private
func
resetButtonClicked
()
{
// 重置
为"全部行业"
// 重置
:清空所有选择
selectedCategories
.
removeAll
()
collectionView
.
reloadData
()
delegate
?
.
categoryView
(
self
,
didSelectCategories
:
selectedCategories
,
isSet
:
false
)
...
...
@@ -238,7 +171,8 @@ extension YHResourceCategoryView: UICollectionViewDataSource, UICollectionViewDe
}
func
collectionView
(
_
collectionView
:
UICollectionView
,
cellForItemAt
indexPath
:
IndexPath
)
->
UICollectionViewCell
{
guard
categories
.
count
>
indexPath
.
item
,
let
cell
=
collectionView
.
dequeueReusableCell
(
withReuseIdentifier
:
"YHResourceCategoryCell"
,
for
:
indexPath
)
as?
YHResourceCategoryCell
else
{
guard
categories
.
count
>
indexPath
.
item
,
let
cell
=
collectionView
.
dequeueReusableCell
(
withReuseIdentifier
:
"YHResourceCategoryCell"
,
for
:
indexPath
)
as?
YHResourceCategoryCell
else
{
return
UICollectionViewCell
()
}
...
...
@@ -252,28 +186,20 @@ extension YHResourceCategoryView: UICollectionViewDataSource, UICollectionViewDe
func
collectionView
(
_
collectionView
:
UICollectionView
,
didSelectItemAt
indexPath
:
IndexPath
)
{
let
category
=
categories
[
indexPath
.
item
]
// 如果是"全部行业",清空其他选择
if
category
.
id
==
"0"
{
selectedCategories
.
removeAll
()
selectedCategories
.
append
(
category
)
}
else
{
// 移除"全部行业"选项
selectedCategories
.
removeAll
{
$0
.
id
==
"0"
}
// 切换选中状态
// 切换选中状态(支持多选)
if
let
index
=
selectedCategories
.
firstIndex
(
where
:
{
$0
.
id
==
category
.
id
})
{
// 如果已选中,则取消选中
selectedCategories
.
remove
(
at
:
index
)
}
else
{
// 如果未选中,则添加到选中列表
selectedCategories
.
append
(
category
)
}
// // 如果没有选中任何分类,自动选中"全部行业"
// if selectedCategories.isEmpty {
// selectedCategories.append(categories.first!)
// }
}
// 刷新UI
collectionView
.
reloadData
()
// 通知代理(不自动关闭,用户需要点击"筛选"按钮)
delegate
?
.
categoryView
(
self
,
didSelectCategories
:
selectedCategories
,
isSet
:
false
)
}
}
...
...
@@ -295,9 +221,16 @@ extension YHResourceCategoryView: UICollectionViewDelegateFlowLayout {
// MARK: - YHResourceCategoryCell
class
YHResourceCategoryCell
:
UICollectionViewCell
{
private
lazy
var
iconLabel
:
UILabel
=
{
let
label
=
UILabel
()
label
.
font
=
UIFont
.
systemFont
(
ofSize
:
18
)
label
.
textAlignment
=
.
center
return
label
}()
private
lazy
var
titleLabel
:
UILabel
=
{
let
label
=
UILabel
()
label
.
font
=
UIFont
.
PFSC_R
(
ofSize
:
1
4
)
label
.
font
=
UIFont
.
PFSC_R
(
ofSize
:
1
3
)
label
.
textAlignment
=
.
center
label
.
textColor
=
.
brandGrayColor8
label
.
numberOfLines
=
1
...
...
@@ -306,6 +239,15 @@ class YHResourceCategoryCell: UICollectionViewCell {
return
label
}()
private
lazy
var
containerStackView
:
UIStackView
=
{
let
stack
=
UIStackView
()
stack
.
axis
=
.
horizontal
stack
.
spacing
=
4
stack
.
alignment
=
.
center
stack
.
distribution
=
.
fill
return
stack
}()
override
init
(
frame
:
CGRect
)
{
super
.
init
(
frame
:
frame
)
setupUI
()
...
...
@@ -318,26 +260,43 @@ class YHResourceCategoryCell: UICollectionViewCell {
private
func
setupUI
()
{
backgroundColor
=
UIColor
.
brandGrayColor2
layer
.
cornerRadius
=
2
// 调整圆角以适应新高度
layer
.
cornerRadius
=
2
layer
.
borderWidth
=
1
layer
.
borderColor
=
UIColor
.
clear
.
cgColor
contentView
.
addSubview
(
titleLabel
)
contentView
.
addSubview
(
containerStackView
)
containerStackView
.
addArrangedSubview
(
iconLabel
)
containerStackView
.
addArrangedSubview
(
titleLabel
)
titleLabel
.
snp
.
makeConstraints
{
make
in
make
.
edges
.
equalToSuperview
()
.
inset
(
UIEdgeInsets
(
top
:
12
,
left
:
4
,
bottom
:
12
,
right
:
4
))
containerStackView
.
snp
.
makeConstraints
{
make
in
make
.
center
.
equalToSuperview
()
make
.
left
.
greaterThanOrEqualToSuperview
()
.
offset
(
8
)
make
.
right
.
lessThanOrEqualToSuperview
()
.
offset
(
-
8
)
}
iconLabel
.
setContentHuggingPriority
(
.
required
,
for
:
.
horizontal
)
titleLabel
.
setContentCompressionResistancePriority
(
.
defaultLow
,
for
:
.
horizontal
)
}
func
configure
(
with
category
:
YHResourceCategory
,
isSelected
:
Bool
)
{
// 设置图标(如果有)
if
!
category
.
icon
.
isEmpty
{
iconLabel
.
text
=
category
.
icon
iconLabel
.
isHidden
=
false
}
else
{
iconLabel
.
isHidden
=
true
}
titleLabel
.
text
=
category
.
name
if
isSelected
{
layer
.
borderColor
=
UIColor
.
brandGrayColor8
.
cgColor
titleLabel
.
font
=
UIFont
.
PFSC_B
(
ofSize
:
14
)
titleLabel
.
font
=
UIFont
.
PFSC_B
(
ofSize
:
13
)
titleLabel
.
textColor
=
UIColor
.
brandGrayColor8
}
else
{
layer
.
borderColor
=
UIColor
.
clear
.
cgColor
titleLabel
.
font
=
UIFont
.
PFSC_R
(
ofSize
:
14
)
titleLabel
.
font
=
UIFont
.
PFSC_R
(
ofSize
:
13
)
titleLabel
.
textColor
=
UIColor
.
brandGrayColor7
}
}
}
galaxy/galaxy/Classes/Modules/Community(社区)/Resource(资源)/V/YHResourceDetailBaseInfoCell.swift
View file @
4fa16fab
...
...
@@ -70,13 +70,19 @@ class YHResourceDetailBaseInfoCell: UITableViewCell {
}
}
func
configure
(
with
model
:
YHResource
List
Model
)
{
func
configure
(
with
model
:
YHResource
Detail
Model
)
{
stackView
.
arrangedSubviews
.
forEach
{
$0
.
removeFromSuperview
()
}
addInfoRow
(
title
:
"企业介绍"
,
content
:
model
.
content
.
isEmpty
?
"未填写"
:
model
.
content
)
addInfoRow
(
title
:
"主营业务"
,
content
:
model
.
category_name
.
isEmpty
?
"未填写"
:
model
.
category_name
)
addInfoRow
(
title
:
"提供服务"
,
content
:
model
.
service_duration
.
isEmpty
?
"未填写"
:
model
.
service_duration
)
addInfoRow
(
title
:
"行业类型"
,
content
:
model
.
category_name
.
isEmpty
?
"未填写"
:
model
.
category_name
)
// 使用详情接口的字段
addInfoRow
(
title
:
"企业介绍"
,
content
:
model
.
company_introduction
.
isEmpty
?
"未填写"
:
model
.
company_introduction
)
addInfoRow
(
title
:
"主营业务"
,
content
:
model
.
company_business
.
isEmpty
?
"未填写"
:
model
.
company_business
)
addInfoRow
(
title
:
"提供服务"
,
content
:
model
.
resource_provided
.
isEmpty
?
"未填写"
:
model
.
resource_provided
)
addInfoRow
(
title
:
"发布需求"
,
content
:
model
.
demand_published
.
isEmpty
?
"未填写"
:
model
.
demand_published
)
addInfoRow
(
title
:
"行业类型"
,
content
:
model
.
industry_type_str
.
isEmpty
?
"未填写"
:
model
.
industry_type_str
)
if
!
model
.
settlement_status_str
.
isEmpty
{
addInfoRow
(
title
:
"入驻状态"
,
content
:
model
.
settlement_status_str
)
}
}
private
func
addInfoRow
(
title
:
String
,
content
:
String
)
{
...
...
@@ -98,7 +104,7 @@ class YHResourceDetailBaseInfoCell: UITableViewCell {
contentLabel
.
font
=
UIFont
.
PFSC_R
(
ofSize
:
13
)
contentLabel
.
textColor
=
UIColor
.
brandGrayColor8
contentLabel
.
text
=
content
contentLabel
.
numberOfLines
=
4
contentLabel
.
numberOfLines
=
0
contentLabel
.
textAlignment
=
.
left
container
.
addSubview
(
titleLabel
)
...
...
@@ -110,7 +116,7 @@ class YHResourceDetailBaseInfoCell: UITableViewCell {
titleLabel
.
snp
.
makeConstraints
{
make
in
make
.
left
.
equalToSuperview
()
make
.
top
.
equalToSuperview
()
make
.
bottom
.
lessThanOrEqualToSuperview
(
)
make
.
width
.
equalTo
(
70
)
}
contentLabel
.
snp
.
makeConstraints
{
make
in
...
...
galaxy/galaxy/Classes/Modules/Community(社区)/Resource(资源)/V/YHResourceDetailDemandCell.swift
View file @
4fa16fab
...
...
@@ -36,7 +36,7 @@ class YHResourceDetailDemandCell: UITableViewCell {
let
label
=
UILabel
()
label
.
font
=
UIFont
.
PFSC_R
(
ofSize
:
13
)
label
.
textColor
=
UIColor
.
brandGrayColor8
label
.
numberOfLines
=
4
label
.
numberOfLines
=
0
return
label
}()
...
...
@@ -66,15 +66,15 @@ class YHResourceDetailDemandCell: UITableViewCell {
}
demandTitleLabel
.
snp
.
makeConstraints
{
make
in
make
.
left
.
equalToSuperview
()
.
offset
(
16
)
make
.
left
.
equalToSuperview
()
.
offset
(
20
)
make
.
top
.
equalTo
(
titleLabel
.
snp
.
bottom
)
.
offset
(
16
)
make
.
width
.
equalTo
(
70
)
}
demandContentLabel
.
snp
.
makeConstraints
{
make
in
make
.
left
.
equalTo
(
demandTitleLabel
.
snp
.
right
)
.
offset
(
12
)
make
.
right
.
equalToSuperview
()
.
offset
(
-
20
)
make
.
top
.
equalTo
(
demandTitleLabel
)
}
dividerView
.
snp
.
makeConstraints
{
make
in
...
...
@@ -85,7 +85,8 @@ class YHResourceDetailDemandCell: UITableViewCell {
}
}
func
configure
(
with
model
:
YHResourceListModel
)
{
demandContentLabel
.
text
=
model
.
title
.
isEmpty
?
"未填写"
:
model
.
title
func
configure
(
with
model
:
YHResourceDetailModel
)
{
// 使用详情接口的 demand_published 字段
demandContentLabel
.
text
=
model
.
demand_published
.
isEmpty
?
"未填写"
:
model
.
demand_published
}
}
galaxy/galaxy/Classes/Modules/Community(社区)/Resource(资源)/V/YHResourceDetailDocumentsCell.swift
View file @
4fa16fab
...
...
@@ -133,7 +133,7 @@ class YHResourceDetailDocumentsCell: UITableViewCell {
}
let
imageWidth
=
KScreenWidth
-
20
*
2
// 左右各16的padding
let
imageHeight
=
imageWidth
*
1.
4
// A4纸张比例
let
imageHeight
=
imageWidth
*
1.
0
// A4纸张比例
for
(
index
,
imageUrl
)
in
images
.
enumerated
()
{
let
imageView
=
UIImageView
()
...
...
galaxy/galaxy/Classes/Modules/Community(社区)/Resource(资源)/V/YHResourceDetailHeaderCell.swift
View file @
4fa16fab
...
...
@@ -7,15 +7,18 @@
//
import
UIKit
import
Kingfisher
class
YHResourceDetailHeaderCell
:
UITableViewCell
{
private
lazy
var
logoImageView
:
UIImageView
=
{
let
imageView
=
UIImageView
()
imageView
.
contentMode
=
.
scaleAspectFi
t
imageView
.
contentMode
=
.
scaleAspectFi
ll
imageView
.
clipsToBounds
=
true
imageView
.
layer
.
cornerRadius
=
4
imageView
.
backgroundColor
=
.
white
imageView
.
layer
.
borderWidth
=
1
imageView
.
layer
.
borderColor
=
UIColor
.
brandGrayColor3
.
cgColor
return
imageView
}()
...
...
@@ -72,11 +75,26 @@ class YHResourceDetailHeaderCell: UITableViewCell {
}
}
func
configure
(
with
model
:
YHResourceListModel
)
{
if
let
url
=
URL
(
string
:
model
.
company_logo
)
{
logoImageView
.
sd_setImage
(
with
:
url
,
placeholderImage
:
UIImage
(
named
:
"people_head_default"
))
func
configure
(
with
model
:
YHResourceDetailModel
)
{
// 设置Logo
if
!
model
.
companyLogoUrl
.
isEmpty
{
logoImageView
.
kf
.
setImage
(
with
:
URL
(
string
:
model
.
companyLogoUrl
),
placeholder
:
UIImage
(
named
:
"global_default_image"
)
)
}
else
{
logoImageView
.
image
=
UIImage
(
named
:
"global_default_image"
)
}
// 设置公司名称
companyNameLabel
.
text
=
model
.
displayName
// 设置英文名称
if
!
model
.
company_english_name
.
isEmpty
{
companyEnglishNameLabel
.
text
=
model
.
company_english_name
companyEnglishNameLabel
.
isHidden
=
false
}
else
{
companyEnglishNameLabel
.
isHidden
=
true
}
companyNameLabel
.
text
=
model
.
company_name
companyEnglishNameLabel
.
text
=
"JUXIN CERTIFIED PUBLIC ACCOUNTANTS FIRM"
}
}
galaxy/galaxy/Classes/Modules/Community(社区)/Resource(资源)/V/YHResourceTableViewCell.swift
View file @
4fa16fab
...
...
@@ -191,83 +191,35 @@ extension YHResourceTableViewCell {
private
func
updateUI
()
{
guard
let
model
=
resourceModel
else
{
return
}
// 设置基本信息
let
title
=
model
.
title
.
count
>
0
?
model
.
title
:
"-"
let
company
=
model
.
company_name
.
count
>
0
?
model
.
company_name
:
"-"
let
categoryName
=
model
.
category_name
.
count
>
0
?
model
.
category_name
:
"-"
titleLabel
.
text
=
title
companyLabel
.
text
=
company
industryLabel
.
text
=
categoryName
var
needNext
=
false
if
let
needNewLine
=
model
.
needNewLine
{
needNext
=
needNewLine
}
else
{
let
needNewLine
=
model
.
calculateNeedNewLine
()
model
.
needNewLine
=
needNewLine
needNext
=
needNewLine
}
if
!
needNext
{
companyLabel
.
snp
.
remakeConstraints
{
make
in
make
.
left
.
equalTo
(
titleLabel
)
make
.
top
.
equalTo
(
titleLabel
.
snp
.
bottom
)
.
offset
(
4
)
}
vSeparatorLine
.
snp
.
remakeConstraints
{
make
in
make
.
left
.
equalTo
(
companyLabel
.
snp
.
right
)
.
offset
(
YHResourceTableViewCell
.
marginBetweenVLine
)
make
.
centerY
.
equalTo
(
companyLabel
)
make
.
width
.
equalTo
(
1
)
make
.
height
.
equalTo
(
8
)
}
// 行业标签约束
industryLabel
.
snp
.
remakeConstraints
{
make
in
make
.
left
.
equalTo
(
vSeparatorLine
.
snp
.
right
)
.
offset
(
YHResourceTableViewCell
.
marginBetweenVLine
)
make
.
right
.
lessThanOrEqualTo
(
rightArrow
.
snp
.
left
)
make
.
top
.
equalTo
(
companyLabel
)
make
.
bottom
.
equalToSuperview
()
.
offset
(
-
32
)
}
}
else
{
companyLabel
.
snp
.
remakeConstraints
{
make
in
make
.
left
.
equalTo
(
titleLabel
)
make
.
right
.
lessThanOrEqualTo
(
rightArrow
.
snp
.
left
)
make
.
top
.
equalTo
(
titleLabel
.
snp
.
bottom
)
.
offset
(
4
)
}
vSeparatorLine
.
snp
.
remakeConstraints
{
make
in
make
.
left
.
equalTo
(
companyLabel
.
snp
.
left
)
make
.
centerY
.
equalTo
(
industryLabel
)
make
.
width
.
equalTo
(
1
)
make
.
height
.
equalTo
(
8
)
}
// 行业标签约束
industryLabel
.
snp
.
remakeConstraints
{
make
in
make
.
left
.
equalTo
(
vSeparatorLine
.
snp
.
right
)
.
offset
(
YHResourceTableViewCell
.
marginBetweenVLine
)
make
.
right
.
lessThanOrEqualTo
(
rightArrow
.
snp
.
left
)
make
.
top
.
equalTo
(
companyLabel
.
snp
.
bottom
)
.
offset
(
4
)
make
.
bottom
.
equalToSuperview
()
.
offset
(
-
32
)
}
}
// 设置基本信息 - 使用新的API字段
titleLabel
.
text
=
getServiceOrDemandText
(
model
:
model
)
// 显示服务或需求信息
companyLabel
.
text
=
model
.
displayName
// 使用 company_name
industryLabel
.
text
=
model
.
industryDisplayText
// 使用 industry_type_str
// 设置Logo
if
!
model
.
company
_logo
.
isEmpty
{
// 设置Logo
- 使用新的API字段
if
!
model
.
company
LogoUrl
.
isEmpty
{
logoImageView
.
kf
.
setImage
(
with
:
URL
(
string
:
model
.
company
_logo
),
with
:
URL
(
string
:
model
.
company
LogoUrl
),
placeholder
:
UIImage
(
named
:
"global_default_image"
)
)
}
else
{
logoImageView
.
image
=
UIImage
(
named
:
"global_default_image"
)
}
// 设置类型标签
if
model
.
type
==
"service"
{
// 设置类型标签
- 根据是服务还是需求
if
model
.
isService
{
typeTagIcon
.
image
=
UIImage
(
named
:
"resource_flag_service"
)
}
else
if
model
.
type
==
"demand"
{
typeTagIcon
.
image
=
UIImage
(
named
:
"resource_flag_demand"
)
}
else
{
typeTagIcon
.
image
=
nil
typeTagIcon
.
image
=
UIImage
(
named
:
"resource_flag_demand"
)
}
}
/// 获取服务或需求文本
private
func
getServiceOrDemandText
(
model
:
YHResourceListModel
)
->
String
{
if
model
.
isService
{
return
model
.
resource_provided
.
isEmpty
?
"-"
:
model
.
resource_provided
}
else
{
return
model
.
demand_published
.
isEmpty
?
"-"
:
model
.
demand_published
}
}
}
galaxy/galaxy/Classes/Modules/Community(社区)/Resource(资源)/VM/YHResourceViewModel.swift
View file @
4fa16fab
...
...
@@ -16,6 +16,7 @@ class YHResourceViewModel: NSObject {
var
currentPage
:
Int
=
1
var
pageSize
:
Int
=
20
var
preloadItemIndex
:
Int
=
10
var
totalCount
:
Int
=
0
// 筛选条件
var
currentType
:
YHResourceFilterType
=
.
service
...
...
@@ -28,7 +29,7 @@ class YHResourceViewModel: NSObject {
// MARK: - 网络请求
/// 获取资源列表
/// 获取资源列表
(公司列表)
/// - Parameters:
/// - firstFlag: 是否首次加载
/// - completion: 完成回调
...
...
@@ -45,16 +46,17 @@ class YHResourceViewModel: NSObject {
}
}
// 构建请求参数
var
params
:
[
String
:
Any
]
=
[
"page"
:
currentPage
,
"page_size"
:
pageSize
,
"type"
:
currentType
==
.
service
?
"service"
:
"demand"
"type"
:
currentType
==
.
service
?
1
:
2
// 1-服务 2-需求
]
// 添加分类筛选(多选)
// 添加分类筛选(多选)
- 转为Int数组
if
!
selectedCategories
.
isEmpty
{
let
categoryIds
=
selectedCategories
.
map
{
$0
.
id
}
params
[
"
category_ids
"
]
=
categoryIds
let
categoryIds
=
selectedCategories
.
compactMap
{
Int
(
$0
.
id
)
}
params
[
"
industry_type
"
]
=
categoryIds
}
// 添加搜索关键词
...
...
@@ -62,229 +64,110 @@ class YHResourceViewModel: NSObject {
params
[
"keyword"
]
=
keyword
}
// 模拟网络延迟
DispatchQueue
.
main
.
asyncAfter
(
deadline
:
.
now
()
+
1.0
)
{
let
mockData
=
self
.
generateMockResourceData
(
page
:
self
.
currentPage
)
// 调用真实API
let
strUrl
=
YHBaseUrlManager
.
shared
.
curURL
()
+
YHAllApiName
.
Resource
.
companyList
_
=
YHNetRequest
.
postRequest
(
url
:
strUrl
,
params
:
params
)
{
[
weak
self
]
json
,
_
in
guard
let
self
=
self
else
{
return
}
if
json
.
code
==
200
{
guard
let
dic
=
json
.
data
?
.
peel
as?
[
String
:
Any
],
let
result
=
YHResourceListResponse
.
deserialize
(
from
:
dic
)
else
{
completion
(
false
,
"数据解析失败"
)
return
}
if
firstFlag
{
self
.
arrResourceData
=
mockData
self
.
totalCount
=
result
.
total
self
.
arrResourceData
=
result
.
list
}
else
{
self
.
arrResourceData
?
.
append
(
contentsOf
:
mockData
)
self
.
arrResourceData
?
.
append
(
contentsOf
:
result
.
list
)
}
self
.
currentPage
+=
1
self
.
hasMoreForResource
=
self
.
currentPage
<=
5
// 模拟5页数据
completion
(
true
,
nil
)
}
// 判断是否还有更多数据
if
(
self
.
arrResourceData
?
.
count
??
0
)
>=
self
.
totalCount
{
self
.
hasMoreForResource
=
false
}
else
{
self
.
hasMoreForResource
=
true
}
/// 切换收藏状态
/// - Parameters:
/// - resourceId: 资源ID
/// - completion: 完成回调
func
toggleFavorite
(
resourceId
:
String
,
completion
:
@escaping
(
Bool
,
String
?)
->
Void
)
{
// 模拟网络延迟
DispatchQueue
.
main
.
asyncAfter
(
deadline
:
.
now
()
+
0.5
)
{
if
let
index
=
self
.
arrResourceData
?
.
firstIndex
(
where
:
{
$0
.
id
==
resourceId
})
{
let
item
=
self
.
arrResourceData
!
[
index
]
item
.
updateFavoriteStatus
(
!
item
.
is_favorite
)
completion
(
true
,
nil
)
}
else
{
completion
(
false
,
"资源不存在"
)
let
errorMsg
=
json
.
msg
.
isEmpty
?
"获取数据失败"
:
json
.
msg
completion
(
false
,
errorMsg
)
}
}
failBlock
:
{
err
in
let
errorMsg
=
err
.
errorMsg
completion
(
false
,
errorMsg
)
}
}
/// 获取资源分类
/// 获取资源分类
(行业类型)
/// - Parameter completion: 完成回调
func
getResourceCategories
(
completion
:
@escaping
([
YHResourceCategory
]?,
String
?)
->
Void
)
{
// 模拟网络延迟
DispatchQueue
.
main
.
asyncAfter
(
deadline
:
.
now
()
+
0.5
)
{
let
categories
=
self
.
generateMockCategories
()
completion
(
categories
,
nil
)
}
}
// MARK: - Mock数据生成
private
func
generateMockResourceData
(
page
:
Int
)
->
[
YHResourceListModel
]
{
let
serviceTitles
=
[
"专业财务咨询服务"
,
"企业IT系统开发"
,
"品牌营销策划方案"
,
"法律顾问服务"
,
"人力资源管理咨询"
,
"企业培训服务"
,
"网站建设与维护"
,
"财务审计服务"
]
let
demandTitles
=
[
"寻找优质供应商"
,
"招聘高级技术人员"
,
"需要市场推广合作"
,
"寻求投资合作伙伴"
,
"需要办公场地租赁"
,
"寻找物流配送服务"
,
"需要设备采购咨询"
,
"寻求技术合作"
]
let
companies
=
[
(
"北京科技有限公司哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈"
,
"https://picsum.photos/60/60?random=1"
),
(
"上海贸易集团"
,
"https://picsum.photos/60/60?random=2"
),
(
"深圳创新科技"
,
"https://picsum.photos/60/60?random=3"
),
(
"杭州电商公司"
,
"https://picsum.photos/60/60?random=4"
),
(
"成都软件开发"
,
"https://picsum.photos/60/60?random=5"
),
(
"广州制造企业"
,
"https://picsum.photos/60/60?random=6"
),
(
"武汉咨询公司"
,
"https://picsum.photos/60/60?random=7"
),
(
"西安技术公司"
,
"https://picsum.photos/60/60?random=8"
)
]
let
categories
=
[
(
"finance"
,
"金融会计哈哈哈哈哈哈"
),
(
"tech"
,
"资讯科技"
),
(
"business"
,
"业务支援"
),
(
"manufacturing"
,
"工业制造"
),
(
"legal"
,
"法律服务"
),
(
"trade"
,
"商业贸易"
),
(
"logistics"
,
"物流运输"
),
(
"other"
,
"其他"
)
]
let
contacts
=
[
(
"张经理"
,
"138****1234"
,
"zhang123"
),
(
"李总监"
,
"139****5678"
,
"li_manager"
),
(
"王助理"
,
"136****9876"
,
"wang_assistant"
),
(
"赵主管"
,
"137****4321"
,
"zhao_supervisor"
),
(
"孙经理"
,
"135****8765"
,
"sun_manager"
),
(
"周总"
,
"134****2468"
,
"zhou_boss"
),
(
"吴主任"
,
"133****1357"
,
"wu_director"
),
(
"郑经理"
,
"132****9753"
,
"zheng_manager"
)
]
let
locations
=
[
"北京·朝阳区"
,
"上海·浦东新区"
,
"深圳·南山区"
,
"杭州·西湖区"
,
"成都·锦江区"
,
"广州·天河区"
,
"武汉·江汉区"
,
"西安·雁塔区"
]
let
contents
=
[
"我们提供专业的财务咨询服务,帮助企业优化财务结构,降低运营成本,提高资金使用效率。团队拥有10年以上行业经验。"
,
"专业的IT系统开发团队,提供定制化解决方案,包括Web应用、移动应用、企业管理系统等。技术栈涵盖主流开发框架。"
,
"专注品牌营销策划,提供全方位的品牌推广方案。从品牌定位到执行落地,一站式服务,已服务500+企业客户。"
,
"资深律师团队提供专业法律顾问服务,涵盖合同审查、法律风险评估、争议解决等。保障企业合规经营。"
,
"人力资源管理专家,提供招聘、培训、绩效管理等全方位HR服务。帮助企业建立完善的人才管理体系。"
,
"企业培训专业机构,提供管理培训、技能培训、团队建设等服务。定制化课程设计,提升员工综合素质。"
,
"专业网站建设团队,提供网站设计、开发、运维一体化服务。响应式设计,SEO优化,提升企业网络形象。"
,
"注册会计师团队提供财务审计服务,确保财务报表真实可靠。严格按照审计准则执行,保障审计质量。"
]
let
strUrl
=
YHBaseUrlManager
.
shared
.
curURL
()
+
YHAllApiName
.
Resource
.
categoryList
// 根据筛选条件过滤数据
var
filteredData
:
[
YHResourceListModel
]
=
[]
for
i
in
0
..<
8
{
let
model
=
YHResourceListModel
()
let
baseId
=
(
page
-
1
)
*
8
+
i
model
.
id
=
"resource_
\(
baseId
)
"
// 根据当前类型选择标题
let
titles
=
currentType
==
.
service
?
serviceTitles
:
demandTitles
model
.
title
=
titles
[
i
%
titles
.
count
]
model
.
content
=
contents
[
i
%
contents
.
count
]
model
.
type
=
currentType
==
.
service
?
"service"
:
"demand"
// 公司信息
let
company
=
companies
[
i
%
companies
.
count
]
model
.
company_name
=
company
.
0
model
.
company_logo
=
company
.
1
// 分类信息
let
category
=
categories
[
i
%
categories
.
count
]
model
.
category_id
=
category
.
0
model
.
category_name
=
category
.
1
// 联系信息
let
contact
=
contacts
[
i
%
contacts
.
count
]
model
.
contact_name
=
contact
.
0
model
.
contact_phone
=
contact
.
1
model
.
contact_wechat
=
contact
.
2
// 其他信息
model
.
location
=
locations
[
i
%
locations
.
count
]
model
.
price
=
i
%
3
==
0
?
""
:
"
\(
Int
.
random
(
in
:
1000
...
9999
)
)
"
model
.
price_unit
=
i
%
3
==
0
?
""
:
[
"小时"
,
"天"
,
"月"
,
"项目"
][
i
%
4
]
model
.
view_count
=
Int
.
random
(
in
:
10
...
999
)
model
.
favorite_count
=
Int
.
random
(
in
:
0
...
50
)
model
.
is_favorite
=
Bool
.
random
()
model
.
status
=
1
// 已发布
model
.
certification_status
=
i
%
2
// 随机认证状态
// 时间
let
daysAgo
=
Int
.
random
(
in
:
0
...
30
)
let
date
=
Calendar
.
current
.
date
(
byAdding
:
.
day
,
value
:
-
daysAgo
,
to
:
Date
())
??
Date
()
let
formatter
=
DateFormatter
()
formatter
.
dateFormat
=
"yyyy-MM-dd HH:mm:ss"
model
.
created_time
=
formatter
.
string
(
from
:
date
)
// 图片(随机添加1-3张图片)
let
imageCount
=
Int
.
random
(
in
:
0
...
3
)
model
.
images
=
(
0
..<
imageCount
)
.
map
{
"https://picsum.photos/300/200?random=
\(
baseId
)
_
\(
$0
)
"
}
// 标签
let
allTags
=
[
"优质服务"
,
"专业团队"
,
"价格优惠"
,
"经验丰富"
,
"快速响应"
,
"全程跟踪"
,
"售后保障"
,
"行业领先"
]
let
tagCount
=
Int
.
random
(
in
:
0
...
3
)
model
.
tags
=
Array
(
allTags
.
shuffled
()
.
prefix
(
tagCount
))
// 应用筛选条件
var
shouldInclude
=
true
// 分类筛选
if
!
selectedCategories
.
isEmpty
{
let
categoryIds
=
selectedCategories
.
map
{
$0
.
id
}
shouldInclude
=
shouldInclude
&&
categoryIds
.
contains
(
model
.
category_id
)
_
=
YHNetRequest
.
getRequest
(
url
:
strUrl
,
params
:
[:])
{
json
,
_
in
if
json
.
code
==
200
{
guard
let
dic
=
json
.
data
?
.
peel
as?
[
String
:
Any
],
let
result
=
YHIndustryTypeResponse
.
deserialize
(
from
:
dic
)
else
{
completion
(
nil
,
"数据解析失败"
)
return
}
// 搜索关键词筛选
if
let
keyword
=
searchKeyword
,
!
keyword
.
isEmpty
{
let
searchText
=
"
\(
model
.
title
)
\(
model
.
content
)
\(
model
.
company_name
)
"
.
lowercased
()
shouldInclude
=
shouldInclude
&&
searchText
.
contains
(
keyword
.
lowercased
())
// 转换为YHResourceCategory数组
let
categories
=
result
.
industry_type
.
map
{
$0
.
toResourceCategory
()
}
completion
(
categories
,
nil
)
}
else
{
let
errorMsg
=
json
.
msg
.
isEmpty
?
"获取分类失败"
:
json
.
msg
completion
(
nil
,
errorMsg
)
}
if
shouldInclude
{
filteredData
.
append
(
model
)
}
failBlock
:
{
err
in
let
errorMsg
=
err
.
errorMsg
completion
(
nil
,
errorMsg
)
}
}
return
filteredData
/// 获取公司详情
/// - Parameters:
/// - companyId: 公司ID
/// - completion: 完成回调
func
getCompanyDetail
(
companyId
:
Int
,
completion
:
@escaping
(
YHResourceDetailModel
?,
String
?)
->
Void
)
{
let
params
:
[
String
:
Any
]
=
[
"id"
:
companyId
]
let
strUrl
=
YHBaseUrlManager
.
shared
.
curURL
()
+
YHAllApiName
.
Resource
.
companyDetail
_
=
YHNetRequest
.
getRequest
(
url
:
strUrl
,
params
:
params
)
{
json
,
_
in
if
json
.
code
==
200
{
guard
let
dic
=
json
.
data
?
.
peel
as?
[
String
:
Any
],
let
result
=
YHResourceDetailModel
.
deserialize
(
from
:
dic
)
else
{
completion
(
nil
,
"数据解析失败"
)
return
}
private
func
generateMockCategories
()
->
[
YHResourceCategory
]
{
let
categoryData
=
[
(
"finance"
,
"金融会计"
,
"💰"
),
(
"tech"
,
"资讯科技"
,
"💻"
),
(
"business"
,
"业务支援"
,
"📊"
),
(
"manufacturing"
,
"工业制造"
,
"🏭"
),
(
"construction"
,
"建筑工程"
,
"🏗️"
),
(
"real_estate"
,
"地产开发"
,
"🏢"
),
(
"legal"
,
"法律服务"
,
"⚖️"
),
(
"trade"
,
"商业贸易"
,
"🛒"
),
(
"logistics"
,
"物流运输"
,
"🚚"
),
(
"food"
,
"餐饮旅游"
,
"🍽️"
),
(
"media"
,
"广播娱乐"
,
"📺"
),
(
"culture"
,
"艺术文化"
,
"🎨"
),
(
"sports"
,
"体育运动"
,
"⚽"
),
(
"health"
,
"医疗健康"
,
"🏥"
),
(
"education"
,
"学术教育"
,
"📚"
),
(
"other"
,
"其他"
,
"📋"
)
]
completion
(
result
,
nil
)
}
else
{
let
errorMsg
=
json
.
msg
.
isEmpty
?
"获取详情失败"
:
json
.
msg
completion
(
nil
,
errorMsg
)
}
return
categoryData
.
map
{
(
id
,
name
,
icon
)
in
let
category
=
YHResourceCategory
()
category
.
id
=
id
category
.
name
=
name
category
.
icon
=
icon
category
.
resource_count
=
Int
.
random
(
in
:
10
...
999
)
category
.
is_hot
=
Int
.
random
(
in
:
0
...
1
)
==
1
return
category
}
failBlock
:
{
err
in
let
errorMsg
=
err
.
errorMsg
completion
(
nil
,
errorMsg
)
}
}
/// 切换收藏状态(如果有收藏功能的话)
/// - Parameters:
/// - resourceId: 资源ID
/// - completion: 完成回调
func
toggleFavorite
(
resourceId
:
String
,
completion
:
@escaping
(
Bool
,
String
?)
->
Void
)
{
// TODO: 如果后端提供收藏接口,在这里实现
// 目前暂时不支持收藏功能
completion
(
false
,
"暂不支持收藏功能"
)
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment