diff --git a/app/src/main/java/com/cheng/bole/common/EventConstants.kt b/app/src/main/java/com/cheng/bole/common/EventConstants.kt index c109381..e8e26e6 100644 --- a/app/src/main/java/com/cheng/bole/common/EventConstants.kt +++ b/app/src/main/java/com/cheng/bole/common/EventConstants.kt @@ -42,6 +42,8 @@ object EventConstants { const val JUMP_TO_SUBSCRIBE = "client.jump.to.subscribe" //跳转到订阅 + const val JUMP_TO_PUBLISH = "client.jump.to.publish" //跳转到发布 + const val JUMP_TO_ABOUT_US = "client.jump.to.about.us" //界面跳转 const val MAIN_CENTER_ENABLE = "client.main.center.enable" //首页跳转个人中心 diff --git a/app/src/main/java/com/cheng/bole/event/BidEvent.kt b/app/src/main/java/com/cheng/bole/event/BidEvent.kt new file mode 100644 index 0000000..fd52c83 --- /dev/null +++ b/app/src/main/java/com/cheng/bole/event/BidEvent.kt @@ -0,0 +1,4 @@ +package com.cheng.bole.event + +class BidEvent { +} \ No newline at end of file diff --git a/app/src/main/java/com/cheng/bole/ui/dialog/PublishBidDialog.kt b/app/src/main/java/com/cheng/bole/ui/dialog/PublishBidDialog.kt new file mode 100644 index 0000000..272d5b1 --- /dev/null +++ b/app/src/main/java/com/cheng/bole/ui/dialog/PublishBidDialog.kt @@ -0,0 +1,103 @@ +package com.cheng.bole.ui.dialog + +import android.app.Dialog +import android.graphics.Color +import android.graphics.drawable.ColorDrawable +import android.os.Bundle +import android.view.Gravity +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.view.ViewOutlineProvider +import android.view.ViewTreeObserver +import androidx.constraintlayout.widget.ConstraintLayout +import androidx.fragment.app.DialogFragment +import com.cheng.bole.R +import com.cheng.bole.common.Constants +import com.cheng.bole.common.EventConstants +import com.cheng.bole.databinding.DialogPublishBidBinding +import com.cheng.bole.manager.EventReportManager +import com.cheng.bole.ui.activity.PublicActivity +import com.cheng.bole.ui.fragment.bid.publish.bid.PublishBidMessageFragment +import com.efs.sdk.memleaksdk.monitor.internal.bi +import com.example.base.extensions.onClick +import com.example.base.utils.ScreenUtils + +class PublishBidDialog : DialogFragment() { + private lateinit var binding: DialogPublishBidBinding + + override fun onStart() { + super.onStart() + val window = dialog?.window + val windowParams = window?.attributes + windowParams?.dimAmount = 0.7f + windowParams?.width = ScreenUtils.getWindowSize().x + windowParams?.gravity = Gravity.BOTTOM + windowParams?.windowAnimations = R.style.dialog_bottom + dialog?.window?.attributes = windowParams + } + + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { + dialog?.window?.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT)) + return super.onCreateView(inflater, container, savedInstanceState) + } + + override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { + val view = layoutInflater.inflate(R.layout.dialog_publish_bid, null) + + binding = DialogPublishBidBinding.bind(view) + + binding.tvTitle.typeface = Constants.pmzdbt + binding.tvBidTitle.typeface = Constants.almmsht + binding.tvGoodsTitle.typeface = Constants.almmsht + + binding.layoutBid.setupWith(binding.root) + .setFrameClearDrawable(binding.layoutBid.background) + .setBlurRadius(5f) + binding.layoutBid.clipToOutline = true + binding.layoutBid.outlineProvider = ViewOutlineProvider.BACKGROUND + + binding.layoutGoods.setupWith(binding.root) + .setFrameClearDrawable(binding.layoutBid.background) + .setBlurRadius(5f) + binding.layoutGoods.clipToOutline = true + binding.layoutGoods.outlineProvider = ViewOutlineProvider.BACKGROUND + + binding.layoutBid.onClick { + PublicActivity.start(requireActivity(), PublishBidMessageFragment::class.java) + EventReportManager.eventReport(EventConstants.JUMP_TO_PUBLISH, "home", "标讯") + dismiss() + } + + binding.layoutGoods.onClick { +// PublicActivity.start(requireActivity(), PublishSupplyMessageFragment::class.java, Pair("from", 1)) + EventReportManager.eventReport(EventConstants.JUMP_TO_PUBLISH, "home", "商品") + dismiss() + } + + binding.ivClose.onClick { dismiss() } + + binding.ivTopBg.viewTreeObserver.addOnGlobalLayoutListener(object : ViewTreeObserver.OnGlobalLayoutListener { + override fun onGlobalLayout() { + val lp = binding.tvTitle.layoutParams as ConstraintLayout.LayoutParams + lp.topMargin = (binding.ivTopBg.height * 55f / 291f).toInt() + binding.tvTitle.layoutParams = lp +// (binding.tvTitle.layoutParams as ConstraintLayout.LayoutParams).topMargin = (binding.ivTopBg.height * 85f / 291f).toInt() + binding.ivTopBg.viewTreeObserver.removeOnGlobalLayoutListener(this) + } + }) + + val dialog = Dialog(requireContext()) + dialog.setContentView(view) + return dialog + } + + companion object { + fun newInstance(): PublishBidDialog { + val arg = Bundle() + val fragment = PublishBidDialog() + fragment.arguments = arg + return fragment + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/cheng/bole/ui/dialog/SelectBidTypeDialog.kt b/app/src/main/java/com/cheng/bole/ui/dialog/SelectBidTypeDialog.kt new file mode 100644 index 0000000..acb0184 --- /dev/null +++ b/app/src/main/java/com/cheng/bole/ui/dialog/SelectBidTypeDialog.kt @@ -0,0 +1,119 @@ +package com.cheng.bole.ui.dialog + +import android.annotation.SuppressLint +import android.app.Dialog +import android.graphics.Color +import android.graphics.Typeface +import android.graphics.drawable.ColorDrawable +import android.os.Build +import android.os.Bundle +import android.view.Gravity +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.TextView +import androidx.fragment.app.DialogFragment +import com.chad.library.adapter.base.BaseQuickAdapter +import com.chad.library.adapter.base.viewholder.BaseViewHolder +import com.cheng.bole.R +import com.cheng.bole.bean.BidTypeBean +import com.cheng.bole.databinding.DialogSelectBidTypeBinding +import com.cheng.bole.manager.UserConfigManager +import com.example.base.extensions.getColor +import com.example.base.extensions.onClick +import com.example.base.extensions.toast +import com.example.base.utils.ScreenUtils + +class SelectBidTypeDialog : DialogFragment() { + private val mAdapter by lazy { BidTypeAdapter() } + + private var bidType: BidTypeBean? = null + + private var mOnBackListener: ((BidTypeBean) -> Unit)? = null //回调事件 + + private lateinit var binding: DialogSelectBidTypeBinding + + override fun onStart() { + super.onStart() + val window = dialog?.window + val windowParams = window?.attributes + windowParams?.dimAmount = 0.7f + windowParams?.width = ScreenUtils.getWindowSize().x + windowParams?.gravity = Gravity.BOTTOM + windowParams?.windowAnimations = R.style.dialog_bottom + dialog?.window?.attributes = windowParams + } + + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { + dialog?.window?.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT)) + return super.onCreateView(inflater, container, savedInstanceState) + } + + @SuppressLint("NotifyDataSetChanged") + override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { + val view = layoutInflater.inflate(R.layout.dialog_select_bid_type, null) + + binding = DialogSelectBidTypeBinding.bind(view) + + bidType = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { + arguments?.getSerializable("type", BidTypeBean::class.java) + } else { + arguments?.getSerializable("type") as? BidTypeBean + } + + binding.mRecyclerView.adapter = mAdapter + val typeList = UserConfigManager.getBidTypes() + if (bidType != null) { + typeList.find { it.id == bidType!!.id }?.isChecked = true + } + mAdapter.setList(typeList) + + mAdapter.setOnItemClickListener { _, _, i -> + val item = mAdapter.getItem(i) + mAdapter.data.find { it.isChecked }?.isChecked = false + item.isChecked = true + bidType = item + mAdapter.notifyDataSetChanged() + } + + binding.btnNext.onClick { + if (bidType == null) { + toast("请选择类别") + return@onClick + } + mOnBackListener?.invoke(bidType!!) + dismiss() + } + + binding.ivClose.onClick { dismiss() } + + val dialog = Dialog(requireContext()) + dialog.setContentView(view) + return dialog + } + + fun setOnSelectListener(listener: ((BidTypeBean) -> Unit)) { + mOnBackListener = listener + } + + companion object { + fun newInstance(type: BidTypeBean?): SelectBidTypeDialog { + val arg = Bundle() + arg.putSerializable("type", type) + val fragment = SelectBidTypeDialog() + fragment.arguments = arg + return fragment + } + } + + class BidTypeAdapter : BaseQuickAdapter(R.layout.listitem_bid_type) { + override fun convert(holder: BaseViewHolder, item: BidTypeBean) { + holder.setText(R.id.tv_name, item.name) + holder.setTextColor(R.id.tv_name, if (item.isChecked) getColor(R.color.color_ff493c) else getColor(R.color.color_666666)) + holder.getView(R.id.tv_name).typeface = if (item.isChecked) Typeface.DEFAULT_BOLD else Typeface.DEFAULT + + holder.itemView.setBackgroundResource(if (item.isChecked) R.drawable.shape_f1f6f_cor4 else 0) + } + + } +} \ No newline at end of file diff --git a/app/src/main/java/com/cheng/bole/ui/fragment/bid/publish/bid/AddBidContactsAdapter.kt b/app/src/main/java/com/cheng/bole/ui/fragment/bid/publish/bid/AddBidContactsAdapter.kt new file mode 100644 index 0000000..46dd372 --- /dev/null +++ b/app/src/main/java/com/cheng/bole/ui/fragment/bid/publish/bid/AddBidContactsAdapter.kt @@ -0,0 +1,18 @@ +package com.cheng.bole.ui.fragment.bid.publish.bid + +import com.chad.library.adapter.base.BaseQuickAdapter +import com.chad.library.adapter.base.viewholder.BaseViewHolder +import com.cheng.bole.R +import com.cheng.bole.bean.ContactsInfoBean + +class AddBidContactsAdapter: BaseQuickAdapter(R.layout.listitem_publish_bid_contacts) { + + init { + addChildClickViewIds(R.id.iv_edit) + } + + override fun convert(holder: BaseViewHolder, item: ContactsInfoBean) { + holder.setText(R.id.tv_name, item.name) + holder.setText(R.id.tv_phone, item.phone) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/cheng/bole/ui/fragment/bid/publish/bid/AddBidFileAdapter.kt b/app/src/main/java/com/cheng/bole/ui/fragment/bid/publish/bid/AddBidFileAdapter.kt new file mode 100644 index 0000000..756bc8c --- /dev/null +++ b/app/src/main/java/com/cheng/bole/ui/fragment/bid/publish/bid/AddBidFileAdapter.kt @@ -0,0 +1,18 @@ +package com.cheng.bole.ui.fragment.bid.publish.bid + +import com.chad.library.adapter.base.BaseQuickAdapter +import com.chad.library.adapter.base.viewholder.BaseViewHolder +import com.cheng.bole.R +import com.cheng.bole.bean.AttachmentBean + +class AddBidFileAdapter : BaseQuickAdapter(R.layout.listitem_publish_bid_file) { + + init { + addChildClickViewIds(R.id.iv_delete) + } + + override fun convert(holder: BaseViewHolder, item: AttachmentBean) { + holder.setText(R.id.tv_name, item.title) + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/cheng/bole/ui/fragment/bid/publish/bid/AddBidImageAdapter.kt b/app/src/main/java/com/cheng/bole/ui/fragment/bid/publish/bid/AddBidImageAdapter.kt new file mode 100644 index 0000000..4c5ec73 --- /dev/null +++ b/app/src/main/java/com/cheng/bole/ui/fragment/bid/publish/bid/AddBidImageAdapter.kt @@ -0,0 +1,118 @@ +package com.cheng.bole.ui.fragment.bid.publish.bid + +import android.annotation.SuppressLint +import android.content.Context +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.ImageView +import androidx.recyclerview.widget.RecyclerView +import coil.load +import coil.transform.RoundedCornersTransformation +import com.cheng.bole.R +import com.cheng.bole.bean.UploadFileEntity +import com.example.base.utils.DensityUtils +import org.jetbrains.anko.find +import org.jetbrains.anko.sdk27.listeners.onClick + +class AddBidImageAdapter(private val context: Context, val data: MutableList) : RecyclerView.Adapter() { + + var selectMax = 10 + private val TYPE_ADD_IMAGE = 1001 + private val TYPE_PICTURE = 1002 + + companion object { + val TYPE_ADD = 10001 + val TYPE_RELOAD = 10002 + val TYPE_DELETE = 10003 + } + + class ViewHolder(view: View) : RecyclerView.ViewHolder(view) { + val ivImg = view.find(R.id.iv_image) + val ivAddImg = view.find(R.id.iv_add_image) + val ivDeleteImg = view.find(R.id.iv_delete) + } + + override fun getItemCount(): Int { + return if (data.size < selectMax) { + data.size + 1 + } else { + data.size + } + } + + override fun getItemViewType(position: Int): Int { + return if (isAddItem(position)) { + TYPE_ADD_IMAGE + } else { + TYPE_PICTURE + } + } + + @SuppressLint("NotifyDataSetChanged") + fun removeAll() { + data.clear() + notifyDataSetChanged() + } + + /** + * 删除 + */ + fun remove(position: Int) { + try { + if (position != RecyclerView.NO_POSITION && data.size > position) { + data.removeAt(position) + notifyItemRemoved(position) + notifyItemRangeChanged(position, data.size) + } + } catch (e: Exception) { + e.printStackTrace() + } + } + + /** + * 创建ViewHolder + */ + override fun onCreateViewHolder(viewGroup: ViewGroup, i: Int): ViewHolder { + val view = LayoutInflater.from(context).inflate(R.layout.listitem_add_bid_img, viewGroup, false) + return ViewHolder(view) + } + + private fun isAddItem(position: Int): Boolean { + return position == data.size + } + + /** + * 设置值 + */ + override fun onBindViewHolder(viewHolder: ViewHolder, position: Int) { + if (viewHolder.itemViewType == TYPE_ADD_IMAGE) { + viewHolder.ivDeleteImg.visibility = View.GONE + viewHolder.ivAddImg.visibility = View.VISIBLE + } else { + viewHolder.ivAddImg.visibility = View.GONE + viewHolder.ivDeleteImg.visibility = View.VISIBLE + viewHolder.ivImg.load(data[position].url) { + transformations(RoundedCornersTransformation(DensityUtils.dp2px(8f).toFloat())) + } + } + viewHolder.ivAddImg.onClick { + onItemClick?.invoke(TYPE_ADD, position) + } + + viewHolder.ivDeleteImg.onClick { + onItemClick?.invoke(TYPE_DELETE, position) + } + viewHolder.ivImg.onClick { + if (viewHolder.itemViewType == TYPE_PICTURE) { + onItemClick?.invoke(TYPE_RELOAD, position) + } + } + } + + private var onItemClick: ((Int, Int) -> Unit)? = null + + fun setOnItemClick(onClick: ((Int, Int) -> Unit)?) { + onItemClick = onClick + } +} \ No newline at end of file diff --git a/app/src/main/java/com/cheng/bole/ui/fragment/bid/publish/bid/PublishBidMessageFragment.kt b/app/src/main/java/com/cheng/bole/ui/fragment/bid/publish/bid/PublishBidMessageFragment.kt new file mode 100644 index 0000000..089f789 --- /dev/null +++ b/app/src/main/java/com/cheng/bole/ui/fragment/bid/publish/bid/PublishBidMessageFragment.kt @@ -0,0 +1,417 @@ +package com.cheng.bole.ui.fragment.bid.publish.bid + +import android.annotation.SuppressLint +import android.os.Build +import android.text.TextUtils +import androidx.activity.result.contract.ActivityResultContracts +import com.cheng.bole.R +import com.cheng.bole.bean.AreaBean +import com.cheng.bole.bean.AttachmentBean +import com.cheng.bole.bean.BidDetailBean +import com.cheng.bole.bean.BidTypeBean +import com.cheng.bole.bean.UploadFileEntity +import com.cheng.bole.common.Constants +import com.cheng.bole.databinding.FragmentPublishBidMessageBinding +import com.cheng.bole.impl.TextWatcherImpl +import com.cheng.bole.manager.UserConfigManager +import com.cheng.bole.ui.dialog.SelectAreaDialog +import com.cheng.bole.ui.dialog.SelectBidTypeDialog +import com.cheng.bole.utils.FileProviderUtils +import com.cheng.bole.utils.GlideEngine +import com.cheng.bole.utils.PermissionUtils +import com.example.base.extensions.getColor +import com.example.base.extensions.gone +import com.example.base.extensions.onClick +import com.example.base.extensions.toast +import com.example.base.extensions.visible +import com.example.base.ui.BaseFragment +import com.example.base.utils.SpanUtils +import com.google.gson.Gson +import com.google.gson.JsonArray +import com.google.gson.JsonObject +import com.google.gson.reflect.TypeToken +import com.huantansheng.easyphotos.EasyPhotos +import com.huantansheng.easyphotos.callback.SelectCallback +import com.huantansheng.easyphotos.models.album.entity.Photo +import okhttp3.RequestBody.Companion.toRequestBody +import java.io.File + +class PublishBidMessageFragment : BaseFragment() { + private var bidDetail: BidDetailBean? = null + + private val imageAdapter by lazy { AddBidImageAdapter(requireContext(), uploadedImgList) } + private var uploadedImgList: ArrayList = ArrayList() + + private val fileAdapter by lazy { AddBidFileAdapter() } + private val selectedFileList = ArrayList() + + private val deletedList = mutableListOf() + + private val contactsAdapter by lazy { AddBidContactsAdapter() } + + private var contentType: Int = 1 //1 文字 2 图片 + + private var city: AreaBean? = null + private var bidType: BidTypeBean? = null + + private val textWatcher = object : TextWatcherImpl() { + override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) { + super.onTextChanged(s, start, before, count) + SpanUtils.with(binding.tvTextCount) + .append("${s?.length ?: 0}") + .setForegroundColor(getColor(R.color.color_1a1a1a)) + .append("/20000") + .create() + } + } + + override fun initView() { + super.initView() + + binding.rvImages.adapter = imageAdapter + binding.rvFiles.adapter = fileAdapter + binding.rvContacts.adapter = contactsAdapter + } + + override fun initData() { + super.initData() + bidDetail = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { + arguments?.getSerializable("item", BidDetailBean::class.java) + } else { + arguments?.getSerializable("item") as? BidDetailBean + } + if (bidDetail != null) { + setData(bidDetail!!) + } + } + + @SuppressLint("NotifyDataSetChanged") + override fun initListener() { + super.initListener() + binding.etProjectInfo.addTextChangedListener(textWatcher) + + binding.tvProjectType.onClick { + val f = SelectBidTypeDialog.newInstance(bidType) + f.setOnSelectListener { + bidType = it + binding.tvProjectType.text = it.name + } + f.show(childFragmentManager, SelectBidTypeDialog::class.java.simpleName) + } + + binding.tvProjectArea.onClick { + val f = SelectAreaDialog.newInstance(if (city != null) listOf(city!!) else emptyList(), true) + f.setOnSelectListener { + city = it[0] + binding.tvProjectArea.text = city!!.name + } + f.show(childFragmentManager, SelectAreaDialog::class.java.simpleName) + } + + binding.tvUploadFile.onClick { + fileLauncher.launch("application/pdf") + } + + binding.tvAddContacts.onClick { + /*val f = AddContactsDialog.newInstance(null) + f.setOnSelectListener { + contactsAdapter.addData(it) + if (contactsAdapter.data.size == 5) { + binding.tvAddContacts.gone() + } + } + f.show(childFragmentManager, AddContactsDialog::class.java.simpleName)*/ + } + + binding.rgProjectInfoType.setOnCheckedChangeListener { _, checkedId -> + when (checkedId) { + R.id.rb1 -> { + contentType = 1 + binding.etProjectInfo.visible() + binding.tvTextCount.visible() + binding.tvImageCount.gone() + binding.tvImageLimitTip.gone() + binding.rvImages.gone() + } + + R.id.rb2 -> { + contentType = 2 + binding.etProjectInfo.gone() + binding.tvTextCount.gone() + binding.tvImageCount.visible() + binding.tvImageLimitTip.visible() + binding.rvImages.visible() + } + } + } + + imageAdapter.setOnItemClick { type, position -> + when (type) { + AddBidImageAdapter.TYPE_ADD -> { + PermissionUtils.checkPhotoPermission(requireActivity(), childFragmentManager, true) { isGranted -> + if (isGranted) selectPhoto() + } + } + + AddBidImageAdapter.TYPE_DELETE -> { + if (uploadedImgList.isNotEmpty()) { + if (bidDetail == null) { + mViewModel.deleteFile(uploadedImgList[position].id) + } + deletedList.add(uploadedImgList[position].id) + uploadedImgList.removeAt(position) + imageAdapter.notifyDataSetChanged() + SpanUtils.with(binding.tvImageCount) + .append("(") + .append("${uploadedImgList.size}") + .setForegroundColor(getColor(R.color.color_ff493c)) + .append("/10)") + .create() + } + } + } + } + + fileAdapter.setOnItemChildClickListener { _, _, i -> + if (bidDetail == null) { + mViewModel.deleteFile(fileAdapter.getItem(i).id) + } + deletedList.add(fileAdapter.getItem(i).id ) + fileAdapter.removeAt(i) + SpanUtils.with(binding.tvFileCount) + .append("(") + .append("${fileAdapter.data.size}") + .setForegroundColor(getColor(R.color.color_ff493c)) + .append("/5)") + .create() + } + + contactsAdapter.setOnItemChildClickListener { _, _, i -> + /*val f = AddContactsDialog.newInstance(contactsAdapter.getItem(i)) + f.setOnSelectListener { + contactsAdapter.removeAt(i) + contactsAdapter.addData(i, it) + } + f.show(childFragmentManager, AddContactsDialog::class.java.simpleName)*/ + } + + binding.btnNext.onClick { + val name = binding.etProjectName.text.toString().trim() + val price = binding.etProjectPrice.text.toString().trim() + val contentText = binding.etProjectInfo.text.toString().trim() + if (bidType == null) { + toast("请选择项目类型") + return@onClick + } + if (TextUtils.isEmpty(name)) { + toast("请输入项目名称") + return@onClick + } + if (TextUtils.isEmpty(price)) { + toast("请输入项目价格") + return@onClick + } + if (city == null) { + toast("请选择发布地区") + return@onClick + } + if (contentType == 1 && TextUtils.isEmpty(contentText)) { + toast("请输入项目文本信息") + return@onClick + } + if (contentType == 2 && imageAdapter.data.isEmpty()) { + toast("请上传项目图片信息") + return@onClick + } + if (fileAdapter.data.isEmpty()) { + toast("请上传项目文件") + return@onClick + } + if (contactsAdapter.data.isEmpty()) { + toast("请添加联系人") + return@onClick + } + commit() + } + } + + @SuppressLint("NotifyDataSetChanged") + override fun initObserve() { + super.initObserve() + mViewModel.addLiveData.observe(this) { + /*toast("提交成功") + RxBus.defaultInstance.post(BidEvent()) + PublicActivity.start(requireContext(), MyBiddingDocFragment::class.java) + requireActivity().finish()*/ + } + + mViewModel.imageLiveData.observe(this) { + uploadedImgList.addAll(it) + imageAdapter.notifyDataSetChanged() + SpanUtils.with(binding.tvImageCount) + .append("(") + .append("${uploadedImgList.size}") + .setForegroundColor(getColor(R.color.color_ff493c)) + .append("/10)") + .create() + } + + mViewModel.fileLiveData.observe(this) { list -> + list.forEachIndexed { index, file -> + fileAdapter.addData(AttachmentBean(file.id, file.url, "pdf", selectedFileList[index].name)) + } + SpanUtils.with(binding.tvFileCount) + .append("(") + .append("${fileAdapter.data.size}") + .setForegroundColor(getColor(R.color.color_ff493c)) + .append("/5)") + .create() + if (fileAdapter.data.size == 5) { + binding.tvUploadFile.gone() + } else { + binding.tvUploadFile.visible() + } + } + } + + private fun commit() { + val name = binding.etProjectName.text.toString().trim() + val price = binding.etProjectPrice.text.toString().trim() + val contentText = binding.etProjectInfo.text.toString().trim() + + val jsonObject = JsonObject() + jsonObject.addProperty("origin_title", name) + jsonObject.addProperty("city_id", "${city!!.id}") + jsonObject.addProperty("type_id", bidType!!.id) + jsonObject.addProperty("project_amount", price) + jsonObject.addProperty("content_type", if (contentType == 1) "1" else "2") + + if (contentType == 1) { + jsonObject.addProperty("origin_content", contentText) + } else { + val imageArray = JsonArray() + uploadedImgList.forEach { + imageArray.add(it.id) + } + jsonObject.add("origin_content", imageArray) + } + + val attachArray = JsonArray() + fileAdapter.data.forEach { + val attachObj = JsonObject() + attachObj.addProperty("title", it.title) + attachObj.addProperty("type", "pdf") + attachObj.addProperty("url", it.url) + attachArray.add(attachObj) + } + jsonObject.add("origin_attachment", attachArray) + + val contactArray = JsonArray() + contactsAdapter.data.forEach { + val contactObj = JsonObject() + contactObj.addProperty("name", it.name) + contactObj.addProperty("phone", it.phone) + contactObj.addProperty("job", it.job) + contactArray.add(contactObj) + } + jsonObject.add("contact", contactArray) + + if (bidDetail == null) { + mViewModel.addBid(jsonObject.toString().toRequestBody()) + } else { + jsonObject.addProperty("id", bidDetail!!.id) + mViewModel.updateBid(jsonObject.toString().toRequestBody()) + } + } + + @SuppressLint("SetTextI18n", "NotifyDataSetChanged") + private fun setData(detail: BidDetailBean) { + if (detail.status == "3") { + binding.tvReason.text = "理由:${detail.review_remark}" + binding.tvTime.text = detail.review_time + binding.layoutRejectReason.visible() + } + binding.etProjectName.setText(detail.origin_title) + binding.etProjectPrice.setText(detail.project_amount) + + city = UserConfigManager.getCityList().find { it.id == detail.city_id.toInt() } + if (city != null) binding.tvProjectArea.text = city!!.name + + bidType = UserConfigManager.getBidTypes().find { it.id == detail.type_id } + if (bidType != null) binding.tvProjectType.text = bidType!!.name + + if (detail.content_type == "1") { + binding.etProjectInfo.setText(detail.origin_content.toString()) + binding.rb1.isChecked = true + } else { + val imageList = Gson().fromJson>(Gson().toJson(detail.origin_content), object : TypeToken>(){}.type) + uploadedImgList.addAll(imageList) + imageAdapter.notifyDataSetChanged() + SpanUtils.with(binding.tvImageCount) + .append("(") + .append("${uploadedImgList.size}") + .setForegroundColor(getColor(R.color.color_ff493c)) + .append("/10)") + .create() + binding.rb2.isChecked = true + } + + fileAdapter.setList(detail.origin_attachment) + if (fileAdapter.data.size == 5) { + binding.tvUploadFile.gone() + } + + contactsAdapter.setList(detail.contact) + if (contactsAdapter.data.size == 5) { + binding.tvAddContacts.gone() + } + } + + private val fileLauncher = registerForActivityResult(ActivityResultContracts.GetMultipleContents()) { + if (it.isEmpty()) return@registerForActivityResult + if (fileAdapter.data.size + it.size > 5) { + toast("最多上传5个文件") + return@registerForActivityResult + } + val files = arrayListOf() + it.forEach { uri -> + val path = FileProviderUtils.getFileAbsolutePath(requireContext(), uri) + if (!TextUtils.isEmpty(path)) { + files.add(File(path!!)) + } + } + if (files.find { file -> file.length() > 5 * 1024 * 1024 } != null) { + toast("单个文件大小不能超过5M") + return@registerForActivityResult + } + selectedFileList.clear() + selectedFileList.addAll(files) + mViewModel.fileList.clear() + mViewModel.uploadFiles(files) + } + + private fun selectPhoto() { + EasyPhotos.createAlbum(this, true, false, GlideEngine.getInstance()) + .setFileProviderAuthority(Constants.AppFilter) + .setCount(imageAdapter.selectMax - uploadedImgList.size) + .start(object : SelectCallback() { + @SuppressLint("NotifyDataSetChanged") + override fun onResult(photos: ArrayList, isOriginal: Boolean) { + if (photos.find { it.size > 10 * 1024 * 1024 } != null) { + toast("单张图片大小不能超过10M") + return + } + mViewModel.imgList.clear() + mViewModel.uploadImages(requireContext(), photos) + } + + override fun onCancel() { + } + }) + } + + override fun onDestroyView() { + binding.etProjectInfo.removeTextChangedListener(textWatcher) + super.onDestroyView() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/cheng/bole/ui/fragment/bid/publish/bid/PublishBidMessageViewModel.kt b/app/src/main/java/com/cheng/bole/ui/fragment/bid/publish/bid/PublishBidMessageViewModel.kt new file mode 100644 index 0000000..62b7a8b --- /dev/null +++ b/app/src/main/java/com/cheng/bole/ui/fragment/bid/publish/bid/PublishBidMessageViewModel.kt @@ -0,0 +1,136 @@ +package com.cheng.bole.ui.fragment.bid.publish.bid + +import android.content.Context +import androidx.lifecycle.MutableLiveData +import com.cheng.bole.bean.UploadFileEntity +import com.cheng.bole.net.ApiFactory +import com.cheng.bole.utils.BitmapUtils +import com.example.base.extensions.toast +import com.example.base.utils.L +import com.example.base.viewmodel.BaseViewModel +import com.huantansheng.easyphotos.models.album.entity.Photo +import okhttp3.MediaType.Companion.toMediaTypeOrNull +import okhttp3.MultipartBody +import okhttp3.RequestBody +import java.io.File + +class PublishBidMessageViewModel : BaseViewModel() { + val addLiveData = MutableLiveData() + + val imageLiveData = MutableLiveData>() + val imgList = ArrayList() + + val fileLiveData = MutableLiveData>() + val fileList = ArrayList() + + fun addBid(requestBody: RequestBody) { + showDialog() + launchOnUiTryCatch({ + val response = ApiFactory.apiService.addBidInfo(requestBody) + if (response.status) { + addLiveData.postValue(Any()) + } else toast(response.message, true) + dismissDialog() + }, { + dismissDialog() + setError(it) + L.d(it) + }) + } + + fun updateBid(requestBody: RequestBody) { + showDialog() + launchOnUiTryCatch({ + val response = ApiFactory.apiService.updateBidInfo(requestBody) + if (response.status) { + addLiveData.postValue(Any()) + } else toast(response.message, true) + dismissDialog() + }, { + dismissDialog() + setError(it) + L.d(it) + }) + } + + //删除文件 + fun deleteFile(id: String) { + launchOnUiTryCatch({ + ApiFactory.apiService.delUserFile(id) + }, { + L.d(it) + }) + } + + fun uploadImages(context: Context, list: ArrayList) { + showDialog() + list.forEachIndexed { index, photo -> + if (index == 0) { + uploadImg(context, photo) { + list.remove(photo) + if (list.isNotEmpty()) { + uploadImages(context, list) + } else { + imageLiveData.postValue(imgList) + dismissDialog() + } + } + } + } + } + + fun uploadFiles(list: ArrayList) { + showDialog() + list.forEachIndexed { index, file -> + if (index == 0) { + uploadFile(file) { + list.remove(file) + if (list.size > 0) { + uploadFiles(list) + } else { + fileLiveData.postValue(fileList) + dismissDialog() + } + } + } + } + } + + private fun uploadImg(context: Context, photo: Photo, clickFun: () -> Unit) { + BitmapUtils.compressImg(context, photo.path) { + launchOnUiTryCatch({ + val requestFile = RequestBody.create("multipart/form-data".toMediaTypeOrNull(), it) + val filePart = MultipartBody.Part.createFormData("file", it.getName(), requestFile) + val response = ApiFactory.apiService.upload(filePart, "supply") + if (response.status) { + imgList.add(response.data) + clickFun.invoke() + } else { + toast(response.message, true) + dismissDialog() + } + }, { + dismissDialog() + L.d(it) + }) + } + } + + private fun uploadFile(file: File, clickFun: () -> Unit) { + launchOnUiTryCatch({ + val requestFile = RequestBody.create("multipart/form-data".toMediaTypeOrNull(), file) + val filePart = MultipartBody.Part.createFormData("file", file.getName(), requestFile) + val response = ApiFactory.apiService.upload(filePart, "supply") + if (response.status) { + fileList.add(response.data) + clickFun.invoke() + } else { + toast(response.message, true) + dismissDialog() + } + }, { + dismissDialog() + L.d(it) + }) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/cheng/bole/ui/fragment/main/MainFragment.kt b/app/src/main/java/com/cheng/bole/ui/fragment/main/MainFragment.kt index bd23787..933be00 100644 --- a/app/src/main/java/com/cheng/bole/ui/fragment/main/MainFragment.kt +++ b/app/src/main/java/com/cheng/bole/ui/fragment/main/MainFragment.kt @@ -16,6 +16,7 @@ import com.cheng.bole.manager.UserConfigManager import com.cheng.bole.ui.activity.LoginActivity import com.cheng.bole.ui.activity.PublicActivity import com.cheng.bole.ui.base.BasePageAdapter +import com.cheng.bole.ui.dialog.PublishBidDialog import com.cheng.bole.ui.dialog.VipLoginTipDialog import com.cheng.bole.ui.fragment.home.HomeFragment import com.cheng.bole.ui.fragment.merchant.MerchantFragment @@ -24,6 +25,7 @@ import com.cheng.bole.ui.fragment.mine.coupon.CouponFragment import com.cheng.bole.ui.fragment.mine.vip.VipFragment import com.cheng.bole.ui.fragment.push.PushFragment import com.example.base.common.RxBus +import com.example.base.extensions.onClick import com.example.base.extensions.toast import com.example.base.ui.BaseFragment import com.google.gson.Gson @@ -87,6 +89,10 @@ class MainFragment : BaseFragment() { EventReportManager.eventReport(EventConstants.HOME_BOTTOM_TAB_CHECK, tabText[currentPosition], "") } + + binding.ivPublish.onClick { + PublishBidDialog().show(childFragmentManager, "") + } } override fun initData() { diff --git a/app/src/main/res/drawable/selector_project_info_tab_bg.xml b/app/src/main/res/drawable/selector_project_info_tab_bg.xml new file mode 100644 index 0000000..ef9826d --- /dev/null +++ b/app/src/main/res/drawable/selector_project_info_tab_bg.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/selector_project_info_tab_text_color.xml b/app/src/main/res/drawable/selector_project_info_tab_text_color.xml new file mode 100644 index 0000000..642e303 --- /dev/null +++ b/app/src/main/res/drawable/selector_project_info_tab_text_color.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/shape_125ffe_cor25.xml b/app/src/main/res/drawable/shape_125ffe_cor25.xml new file mode 100644 index 0000000..6dc00f5 --- /dev/null +++ b/app/src/main/res/drawable/shape_125ffe_cor25.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/shape_f1f6f_cor4.xml b/app/src/main/res/drawable/shape_f1f6f_cor4.xml new file mode 100644 index 0000000..acf354e --- /dev/null +++ b/app/src/main/res/drawable/shape_f1f6f_cor4.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/shape_f3f7ff_cor25.xml b/app/src/main/res/drawable/shape_f3f7ff_cor25.xml new file mode 100644 index 0000000..166ade3 --- /dev/null +++ b/app/src/main/res/drawable/shape_f3f7ff_cor25.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/shape_publish_dialog_option_bg.xml b/app/src/main/res/drawable/shape_publish_dialog_option_bg.xml new file mode 100644 index 0000000..de77a42 --- /dev/null +++ b/app/src/main/res/drawable/shape_publish_dialog_option_bg.xml @@ -0,0 +1,8 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/dialog_publish_bid.xml b/app/src/main/res/layout/dialog_publish_bid.xml new file mode 100644 index 0000000..888bd39 --- /dev/null +++ b/app/src/main/res/layout/dialog_publish_bid.xml @@ -0,0 +1,155 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/dialog_select_bid_type.xml b/app/src/main/res/layout/dialog_select_bid_type.xml new file mode 100644 index 0000000..c17acef --- /dev/null +++ b/app/src/main/res/layout/dialog_select_bid_type.xml @@ -0,0 +1,74 @@ + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_add_subscribe.xml b/app/src/main/res/layout/fragment_add_subscribe.xml index 26e4186..06a2ab3 100644 --- a/app/src/main/res/layout/fragment_add_subscribe.xml +++ b/app/src/main/res/layout/fragment_add_subscribe.xml @@ -491,6 +491,7 @@ android:layout_height="@dimen/dp_36" android:drawableStart="@mipmap/ic_add_subscribe_keyword" android:text="添加" + android:textSize="@dimen/sp_14" android:textColor="@color/white" app:csb_cornerRadius="@dimen/dp_10" app:csb_drawablePosition="left" diff --git a/app/src/main/res/layout/fragment_publish_bid_message.xml b/app/src/main/res/layout/fragment_publish_bid_message.xml new file mode 100644 index 0000000..31bd93a --- /dev/null +++ b/app/src/main/res/layout/fragment_publish_bid_message.xml @@ -0,0 +1,666 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/listitem_add_bid_img.xml b/app/src/main/res/layout/listitem_add_bid_img.xml new file mode 100644 index 0000000..f45b5d2 --- /dev/null +++ b/app/src/main/res/layout/listitem_add_bid_img.xml @@ -0,0 +1,34 @@ + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/listitem_bid_type.xml b/app/src/main/res/layout/listitem_bid_type.xml new file mode 100644 index 0000000..6101e4f --- /dev/null +++ b/app/src/main/res/layout/listitem_bid_type.xml @@ -0,0 +1,21 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/listitem_publish_bid_contacts.xml b/app/src/main/res/layout/listitem_publish_bid_contacts.xml new file mode 100644 index 0000000..e78db57 --- /dev/null +++ b/app/src/main/res/layout/listitem_publish_bid_contacts.xml @@ -0,0 +1,34 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/listitem_publish_bid_file.xml b/app/src/main/res/layout/listitem_publish_bid_file.xml new file mode 100644 index 0000000..c38a9dc --- /dev/null +++ b/app/src/main/res/layout/listitem_publish_bid_file.xml @@ -0,0 +1,43 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/mipmap-xxhdpi/ic_add_bid_image.png b/app/src/main/res/mipmap-xxhdpi/ic_add_bid_image.png new file mode 100644 index 0000000..2e73ca2 Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/ic_add_bid_image.png differ diff --git a/app/src/main/res/mipmap-xxhdpi/ic_add_contacts.png b/app/src/main/res/mipmap-xxhdpi/ic_add_contacts.png new file mode 100644 index 0000000..a8b5bb9 Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/ic_add_contacts.png differ diff --git a/app/src/main/res/mipmap-xxhdpi/ic_arrow_dp18.png b/app/src/main/res/mipmap-xxhdpi/ic_arrow_dp18.png new file mode 100644 index 0000000..c7ad36c Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/ic_arrow_dp18.png differ diff --git a/app/src/main/res/mipmap-xxhdpi/ic_delete_bid_image.png b/app/src/main/res/mipmap-xxhdpi/ic_delete_bid_image.png new file mode 100644 index 0000000..086f2b8 Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/ic_delete_bid_image.png differ diff --git a/app/src/main/res/mipmap-xxhdpi/ic_edit_contacts.png b/app/src/main/res/mipmap-xxhdpi/ic_edit_contacts.png new file mode 100644 index 0000000..715bb12 Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/ic_edit_contacts.png differ diff --git a/app/src/main/res/mipmap-xxhdpi/ic_publish_bid_top_bg.png b/app/src/main/res/mipmap-xxhdpi/ic_publish_bid_top_bg.png new file mode 100644 index 0000000..16c5ceb Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/ic_publish_bid_top_bg.png differ diff --git a/app/src/main/res/mipmap-xxhdpi/ic_publish_dialog_close.png b/app/src/main/res/mipmap-xxhdpi/ic_publish_dialog_close.png new file mode 100644 index 0000000..8a9731d Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/ic_publish_dialog_close.png differ diff --git a/app/src/main/res/mipmap-xxhdpi/ic_publish_dialog_icon1.png b/app/src/main/res/mipmap-xxhdpi/ic_publish_dialog_icon1.png new file mode 100644 index 0000000..f2946d7 Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/ic_publish_dialog_icon1.png differ diff --git a/app/src/main/res/mipmap-xxhdpi/ic_publish_dialog_icon2.png b/app/src/main/res/mipmap-xxhdpi/ic_publish_dialog_icon2.png new file mode 100644 index 0000000..9e1d6e1 Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/ic_publish_dialog_icon2.png differ diff --git a/app/src/main/res/mipmap-xxhdpi/ic_publish_dialog_top_bg.png b/app/src/main/res/mipmap-xxhdpi/ic_publish_dialog_top_bg.png new file mode 100644 index 0000000..485096c Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/ic_publish_dialog_top_bg.png differ diff --git a/app/src/main/res/mipmap-xxhdpi/ic_upload_file.png b/app/src/main/res/mipmap-xxhdpi/ic_upload_file.png new file mode 100644 index 0000000..ed5abdf Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/ic_upload_file.png differ diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index 03bd433..0b4fd38 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -84,4 +84,5 @@ #2A80FC #F8F9FA #3BBF0F + #707A89 \ No newline at end of file