模糊查询安卓端使用

后端使用Springboot 前端通过无线网路接口与后端相连
以下是具体代码实现
后端:
PolicyController

点击查看代码
package com.example.demo.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.demo.entity.Policy;
import com.example.demo.service.PolicyService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/policy")
public class PolicyController {

    @Autowired
    private PolicyService policyService;

    @GetMapping("/search")
    public Page<Policy> search(
            @RequestParam(defaultValue = "") String keyword,
            @RequestParam(defaultValue = "1") Integer current,
            @RequestParam(defaultValue = "10") Integer size) {
        
        Page<Policy> page = new Page<>(current, size);
        LambdaQueryWrapper<Policy> wrapper = new LambdaQueryWrapper<>();
        
        // 模糊匹配名称、关键词或政策文本
        wrapper.like(Policy::getName, keyword)
                .or()
                .like(Policy::getKeyword, keyword)
                .or()
                .like(Policy::getText, keyword);
        
        return policyService.page(page, wrapper);
    }

    @GetMapping("/{id}")
    public Policy getById(@PathVariable Long id) {
        return policyService.getById(id);
    }
}

Policy
点击查看代码
package com.example.demo.entity;

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import lombok.Data;

import java.util.Date;

@Data
public class Policy {
    @TableId(type = IdType.AUTO)
    private Long id;
    private String name;
    private String type;
    private String category;
    @TableField("`range`")
    private String range;
    private String document;
    private String form;
    private String organ;
    private Date viadata;
    private Date pubdata;
    private Date perdata;
    @TableField("`field`")
    private String field;
    private String theme;
    private String keyword;
    private String superior;
    private String precursor;
    private String succeed;
    private String state;
    private String text;
    private String pdf;
    private String redundancy;
    @TableField("`rank`")
    private String rank;
    private String policykey;
    private String newrank;
    @TableField("`year`")
    private String year;
    private String newkey;
    private String secondtheme;
    private Integer allsum;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

    public String getCategory() {
        return category;
    }

    public void setCategory(String category) {
        this.category = category;
    }

    public String getRange() {
        return range;
    }

    public void setRange(String range) {
        this.range = range;
    }

    public String getDocument() {
        return document;
    }

    public void setDocument(String document) {
        this.document = document;
    }

    public String getForm() {
        return form;
    }

    public void setForm(String form) {
        this.form = form;
    }

    public String getOrgan() {
        return organ;
    }

    public void setOrgan(String organ) {
        this.organ = organ;
    }

    public Date getViadata() {
        return viadata;
    }

    public void setViadata(Date viadata) {
        this.viadata = viadata;
    }

    public Date getPubdata() {
        return pubdata;
    }

    public void setPubdata(Date pubdata) {
        this.pubdata = pubdata;
    }

    public Date getPerdata() {
        return perdata;
    }

    public void setPerdata(Date perdata) {
        this.perdata = perdata;
    }

    public String getField() {
        return field;
    }

    public void setField(String field) {
        this.field = field;
    }

    public String getTheme() {
        return theme;
    }

    public void setTheme(String theme) {
        this.theme = theme;
    }

    public String getKeyword() {
        return keyword;
    }

    public void setKeyword(String keyword) {
        this.keyword = keyword;
    }

    public String getSuperior() {
        return superior;
    }

    public void setSuperior(String superior) {
        this.superior = superior;
    }

    public String getPrecursor() {
        return precursor;
    }

    public void setPrecursor(String precursor) {
        this.precursor = precursor;
    }

    public String getSucceed() {
        return succeed;
    }

    public void setSucceed(String succeed) {
        this.succeed = succeed;
    }

    public String getState() {
        return state;
    }

    public void setState(String state) {
        this.state = state;
    }

    public String getText() {
        return text;
    }

    public void setText(String text) {
        this.text = text;
    }

    public String getPdf() {
        return pdf;
    }

    public void setPdf(String pdf) {
        this.pdf = pdf;
    }

    public String getRedundancy() {
        return redundancy;
    }

    public void setRedundancy(String redundancy) {
        this.redundancy = redundancy;
    }

    public String getRank() {
        return rank;
    }

    public void setRank(String rank) {
        this.rank = rank;
    }

    public String getPolicykey() {
        return policykey;
    }

    public void setPolicykey(String policykey) {
        this.policykey = policykey;
    }

    public String getNewrank() {
        return newrank;
    }

    public void setNewrank(String newrank) {
        this.newrank = newrank;
    }

    public String getYear() {
        return year;
    }

    public void setYear(String year) {
        this.year = year;
    }

    public String getNewkey() {
        return newkey;
    }

    public void setNewkey(String newkey) {
        this.newkey = newkey;
    }

    public String getSecondtheme() {
        return secondtheme;
    }

    public void setSecondtheme(String secondtheme) {
        this.secondtheme = secondtheme;
    }

    public Integer getAllsum() {
        return allsum;
    }

    public void setAllsum(Integer allsum) {
        this.allsum = allsum;
    }
}

PolicyMapper
点击查看代码
package com.example.demo.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.example.demo.entity.Policy;
import org.apache.ibatis.annotations.Mapper;

@Mapper
public interface PolicyMapper extends BaseMapper<Policy> {
}

PolicyServiceImpl
点击查看代码
package com.example.demo.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.demo.entity.Policy;
import com.example.demo.mapper.PolicyMapper;
import com.example.demo.service.PolicyService;
import org.springframework.stereotype.Service;

@Service
public class PolicyServiceImpl extends ServiceImpl<PolicyMapper, Policy> implements PolicyService {
}

PolicyService
点击查看代码
package com.example.demo.service;

import com.baomidou.mybatisplus.extension.service.IService;
import com.example.demo.entity.Policy;

public interface PolicyService extends IService<Policy> {
}

application.yml
点击查看代码
package com.example.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class DemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }

}

前端
Policy

点击查看代码
package com.qi.demo.entity

import java.util.Date

data class Policy(
    val id: Long,
    val name: String?,
    val type: String?,
    val category: String?,
    val range: String?,
    val document: String?,
    val form: String?,
    val organ: String?,
    val viadata: Date?,
    val pubdata: Date?,
    val perdata: Date?,
    val field: String?,
    val theme: String?,
    val keyword: String?,
    val text: String?,
    val pdf: String?
)

ServiceCreator
点击查看代码
package com.qi.demo.network

import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory

object ServiceCreator {
    private const val BASE_URL = "http://172.20.10.4:8090/"
    
    private val retrofit = Retrofit.Builder()
        .baseUrl(BASE_URL)
        .addConverterFactory(GsonConverterFactory.create())
        .build()

    fun <T> create(serviceClass: Class<T>): T = retrofit.create(serviceClass)
    
    inline fun <reified T> create(): T = create(T::class.java)
}
PolicyService.kt
点击查看代码
package com.qi.demo.service

import com.qi.demo.entity.Policy
import retrofit2.Call
import retrofit2.http.GET
import retrofit2.http.Path
import retrofit2.http.Query

interface PolicyService {
    @GET("policy/search")
    fun search(
        @Query("keyword") keyword: String,
        @Query("current") current: Int = 1,
        @Query("size") size: Int = 10
    ): Call<Page<Policy>>

    @GET("policy/{id}")
    fun getById(@Path("id") id: Long): Call<Policy>
}

data class Page<T>(
    val records: List<T>,
    val total: Long,
    val size: Int,
    val current: Int
)
MainActivity
点击查看代码
package com.qi.demo

import android.content.Intent
import android.net.Uri
import android.os.Bundle
import android.util.Log
import android.widget.EditText
import android.widget.ImageButton
import android.widget.Toast
import androidx.activity.enableEdgeToEdge
import androidx.appcompat.app.AppCompatActivity
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.qi.demo.entity.Policy
import com.qi.demo.network.ServiceCreator
import com.qi.demo.service.Page
import com.qi.demo.service.PolicyService
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response

class MainActivity : AppCompatActivity() {
    private lateinit var searchInput: EditText
    private lateinit var searchButton: ImageButton
    private lateinit var recyclerView: RecyclerView
    private lateinit var adapter: PolicyAdapter
    private val policyService = ServiceCreator.create<PolicyService>()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        enableEdgeToEdge()
        setContentView(R.layout.activity_main)
        
        initViews()
        setupRecyclerView()
        setupSearchButton()
    }

    private fun initViews() {
        searchInput = findViewById(R.id.searchInput)
        searchButton = findViewById(R.id.searchButton)
        recyclerView = findViewById(R.id.recyclerView)
    }

    private fun setupRecyclerView() {
        adapter = PolicyAdapter { policy ->
            // 点击政策项时打开详情
            openPolicyDetail(policy.id)
        }
        recyclerView.layoutManager = LinearLayoutManager(this)
        recyclerView.adapter = adapter
    }

    private fun setupSearchButton() {
        searchButton.setOnClickListener {
            val keyword = searchInput.text.toString()
            searchPolicies(keyword)
        }
    }

    private fun searchPolicies(keyword: String) {
        policyService.search(keyword).enqueue(object : Callback<Page<Policy>> {
            override fun onResponse(call: Call<Page<Policy>>, response: Response<Page<Policy>>) {
                response.body()?.let { page ->
                    adapter.submitList(page.records)
                }
            }

            override fun onFailure(call: Call<Page<Policy>>, t: Throwable) {
                Toast.makeText(this@MainActivity, "搜索失败:${t.message}", Toast.LENGTH_SHORT).show()
                Log.e("MainActivity", "搜索失败", t)
            }
        })
    }

    private fun openPolicyDetail(id: Long) {
        policyService.getById(id).enqueue(object : Callback<Policy> {
            override fun onResponse(call: Call<Policy>, response: Response<Policy>) {
                response.body()?.let { policy ->
                    // 如果有PDF链接,打开PDF
                    policy.pdf?.let { pdfUrl ->
                        val intent = Intent(Intent.ACTION_VIEW, Uri.parse(pdfUrl))
                        startActivity(intent)
                    } ?: run {
                        // 否则显示文本内容
                        val intent = Intent(this@MainActivity, PolicyDetailActivity::class.java)
                        intent.putExtra("policyText", policy.text)
                        intent.putExtra("policyName", policy.name)
                        startActivity(intent)
                    }
                }
            }

            override fun onFailure(call: Call<Policy>, t: Throwable) {
                Toast.makeText(this@MainActivity, "获取详情失败:${t.message}", Toast.LENGTH_SHORT).show()
                Log.e("MainActivity", "获取详情失败", t)
            }
        })
    }
}
PolicyAdapter.kt
点击查看代码
package com.qi.demo

import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView
import com.qi.demo.entity.Policy

class PolicyAdapter(private val onItemClick: (Policy) -> Unit) :
    ListAdapter<Policy, PolicyAdapter.ViewHolder>(PolicyDiffCallback()) {

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
        val view = LayoutInflater.from(parent.context)
            .inflate(R.layout.item_policy, parent, false)
        return ViewHolder(view, onItemClick)
    }

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        holder.bind(getItem(position))
    }

    class ViewHolder(view: View, private val onItemClick: (Policy) -> Unit) :
        RecyclerView.ViewHolder(view) {
        private val nameText: TextView = view.findViewById(R.id.policyName)
        private val organText: TextView = view.findViewById(R.id.policyOrgan)
        private val dateText: TextView = view.findViewById(R.id.policyDate)

        fun bind(policy: Policy) {
            nameText.text = policy.name
            organText.text = policy.organ
            dateText.text = policy.pubdata?.toString() ?: ""
            itemView.setOnClickListener { onItemClick(policy) }
        }
    }
}

class PolicyDiffCallback : DiffUtil.ItemCallback<Policy>() {
    override fun areItemsTheSame(oldItem: Policy, newItem: Policy): Boolean {
        return oldItem.id == newItem.id
    }

    override fun areContentsTheSame(oldItem: Policy, newItem: Policy): Boolean {
        return oldItem == newItem
    }
}
PolicyDetailActivity
点击查看代码
package com.qi.demo

import android.os.Bundle
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity

class PolicyDetailActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_policy_detail)

        val policyText = intent.getStringExtra("policyText") ?: ""
        val policyName = intent.getStringExtra("policyName") ?: ""

        findViewById<TextView>(R.id.policyTitle).text = policyName
        findViewById<TextView>(R.id.policyContent).text = policyText
    }
}
activity_main.xml
点击查看代码
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:padding="16dp">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

        <EditText
            android:id="@+id/searchInput"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:hint="请输入政策关键词"
            android:padding="12dp"
            android:background="@drawable/search_background"
            android:layout_marginEnd="8dp"/>

        <ImageButton
            android:id="@+id/searchButton"
            android:layout_width="48dp"
            android:layout_height="48dp"
            android:src="@drawable/ic_search"
            android:background="?attr/selectableItemBackgroundBorderless"
            android:contentDescription="搜索"/>
    </LinearLayout>

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recyclerView"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:layout_marginTop="16dp"/>

</LinearLayout>
activity_policy_detail.xml
点击查看代码
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:padding="16dp">

        <TextView
            android:id="@+id/policyTitle"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:textSize="20sp"
            android:textStyle="bold"
            android:textColor="@color/black"
            android:gravity="center"
            android:layout_marginBottom="16dp"/>

        <TextView
            android:id="@+id/policyContent"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:textSize="16sp"
            android:lineSpacingMultiplier="1.2"/>

    </LinearLayout>
</ScrollView>
item_policy.xml
点击查看代码
<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginHorizontal="8dp"
    android:layout_marginVertical="4dp"
    app:cardCornerRadius="8dp"
    app:cardElevation="2dp">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:padding="16dp">

        <TextView
            android:id="@+id/policyName"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:textSize="16sp"
            android:textColor="@color/black"
            android:textStyle="bold"/>

        <TextView
            android:id="@+id/policyOrgan"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="8dp"
            android:textSize="14sp"/>

        <TextView
            android:id="@+id/policyDate"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="4dp"
            android:textSize="12sp"
            android:textColor="@android:color/darker_gray"/>
    </LinearLayout>

</androidx.cardview.widget.CardView>
posted @ 2025-03-24 08:38  QixunQiu  阅读(37)  评论(0)    收藏  举报