uni-app:实现分页功能,单击行获取此行指定数据,更改行样式

news2025/1/11 20:51:11

 效果:

分段解析代码

分页功能实现:

一、标签

1、搜索栏-模糊查询
<!-- 搜索框-->
		<form action="" @submit="search_wip_name">
			<view class="search_position">
				<view class="search">
					<view class="search_left">
						工单名称:
					</view>
					<view class="search_right">
						<input name="wip_entity_name" type="text" />
					</view>
				</view>
			</view>
			<view class="search_position">
				<view class="search">
					<view class="search_left">
						料号:
					</view>
					<view class="search_right">
						<input name="ItemNo" type="text" />
					</view>
				</view>
			</view>
			<view class="search_position">
				<view class="search">
					<view class="search_left">
						名称:
					</view>
					<view class="search_right">
						<input name="ItemName" type="text" />
					</view>
				</view>
			</view>
			<view class="search_position">
				<view class="btn_position">
					<button class="button" form-type="submit">查询</button>
					<button class="button1">确认</button>
				</view>
			</view>
		</form>

<form action="" @submit="search_wip_name"> : 为表单信息,@submit = "search_wip_name"表单提交的方法

name="wip_entity_name"设置name的值,方便js端获取数据

<button class="button" form-type="submit">查询</button>,设置form-type="submit",绑定表单的提交按钮

2、表格信息
<!-- 表格 -->
		<scroll-view scroll-x="true" style="overflow-x: scroll; white-space: nowrap;">
			<view class="table">
				<view class="table-tr">
					<view class="table-th1">工单名称</view>
					<view class="table-th1">料号</view>
					<view class="table-th1">料号名称</view>
					<view class="table-th1">规格型号</view>
					<view class="table-th1">预计开工日</view>
					<view class="table-th1">开工量</view>
				</view>
				<!-- :class="{ selected: selectedIndex === index,'selected-row':selectedRow ===index }" -->
				<view class="table-tr" v-for="(item, index) in dataList" :key="index"
					:class="{ selected: item.selectedIndex === index, 'selected-row': item.selectedRow }"
					@click="selectRow(index,item.wip_entity_name)">
					<view class="table-td1">{{item.wip_entity_name}}</view>
					<view class="table-td2">{{item.primary_item}}</view>
					<view class="table-td2">{{item.item_name}}</view>
					<view class="table-td2">{{item.item_desc}}</view>
					<view class="table-td2">{{item.plan_start_date}}</view>
					<view class="table-td2">{{item.start_quantity}}</view>
				</view>
			</view>
		</scroll-view>

scroll-view 实现可滚动的视图区域。在这个代码中,scroll-view 组件被用来实现横向滚动的效果,即可以水平滚动。

  • scroll-x="true":设置 scroll-view 组件为横向滚动模式。

  • style="overflow-x: scroll; white-space: nowrap;":添加样式,设置横向滚动条可见,并且内容不换行。

  • v-for="(item, index) in dataList" :key="index":通过 v-for 指令,遍历 dataList 数组生成多个行,每一行对应数组中的一个数据项。 :key="index" 用于指定每个行的唯一标识。

  • :class="{ selected: item.selectedIndex === index, 'selected-row': item.selectedRow }":当 item.selectedIndex 和 index 相等时,为当前行添加 selected 样式类;当 item.selectedRow 为真时,为当前行添加 selected-row 样式类。(这里是为了实现单击获取数据的代码,以及单击行样式改变的代码)

3、分页实现
<!-- 分页 -->
<view class="pagination">
	<view class="up_page" :class="{ 'first-page': isFirstPage }" :disabled="currentPage === 1"
		@click="prevPage"><</view>
			<view class="now_page">
				<text style="color:#2979ff">{{ currentPage }} </text><text
					style="color:#4b4b4b">/{{ totalPage }}</text>
			</view>
			<view class="down_page" :class="{ 'last-page': isLastPage }" :disabled="currentPage === totalPage"
				@click="nextPage">></view>
	</view>
</view>

<view class="up_page" :class="{ 'first-page': isFirstPage }" :disabled="currentPage === 1" @click="prevPage"><</view>:这是一个显示上一页按钮的视图元素。

  • :class="{ 'first-page': isFirstPage }"绑定的类名条件判断,如果当前页码为第一页,则添加first-page类名,可以用于自定义样式。根据 isFirstPage 变量的值来判断是否添加 first-page 类名。当 isFirstPage 的值为 true 时,会添加 class="first-page"
  • :disabled="currentPage === 1"通过判断当前页码是否为1来决定按钮是否可点击,从而达到禁用按钮的效果。这句话表示当currentPage的值===1时,disabled="true"那么就被禁用,反之则反
  • @click="prevPage"绑定了点击事件,当点击按钮时会执行prevPage方法。

<text style="color:#2979ff">{{ currentPage }} </text><text style="color:#4b4b4b">/{{ totalPage }}</text>:使用两个<text>标签来分别显示当前页码和总页数。

  • {{ currentPage }}是一个插值表达式,用于渲染当前页码。

  • {{ totalPage }}同样是一个插值表达式,用于渲染总页数。通过设置style属性来给文本设置样式,如颜色。

<view class="down_page" :class="{ 'last-page': isLastPage }" :disabled="currentPage === totalPage" @click="nextPage">></view>:这是一个显示下一页按钮的视图元素,与上一页按钮类似。

  • :class="{ 'last-page': isLastPage }"绑定的类名条件判断,如果当前页码为最后一页,则添加last-page类名,可以用于自定义样式。

  • :disabled="currentPage === totalPage"通过判断当前页码是否等于总页数来决定按钮是否可点击,从而达到禁用按钮的效果。

  • @click="nextPage"绑定了点击事件,当点击按钮时会执行nextPage方法。

 二、JS

1、变量设置
data() {
			return {
				dataList: [],//查询出的数据
				currentPage: 1,//当前页码
				pageSize: 10,//每页显示数量
				totalPage: 0,//总页数默认值
				selectedIndex: -1,//selectedIndex 默认为 -1 是为了表示列表项未被选中的状态。
				isFirstPage: '',//是否是第一页
				isLastPage: '',//是否是最后一页
				selectedRow: '',//选择行
				wip_entity_name: '',//工单(模糊查询使用)
				ItemNo: '',//料号
				ItemName: '',//料号名称
			};
		},
2、 自动计算当前页信息
computed: {
			getCurrentPageData() {
				const startIndex = (this.currentPage - 1) * this.pageSize;
				const endIndex = startIndex + this.pageSize;
				return this.dataList.slice(startIndex, endIndex);
			}
		},

computed 是 vue.js框架提供的一个计算属性特性。使用 computed 可以在 Vue 组件中定义一些根据数据的变化而自动计算得出的属性。

在给定的代码中,getCurrentPageData 就是一个计算属性。它依赖于 currentPagepageSize 这两个数据属性,当这两个属性发生变化时,getCurrentPageData 会自动重新计算并返回当前页的数据。

  1. getCurrentPageData 是一个计算属性的名称。
  2. 计算属性的定义由使用 computed 关键字开始。
  3. 计算属性里的代码逻辑会在相关的响应式依赖发生变化时自动执行。
  4. const startIndex = (this.currentPage - 1) * this.pageSize;:计算当前页的起始索引,使用了 currentPage 和 pageSize 这两个响应式数据。
    • currentPage 表示当前所在的页数。
    • pageSize 表示每页显示的数据条数。
    • 起始索引计算公式为 (当前页数 - 1) * 每页数据条数
  5. const endIndex = startIndex + this.pageSize;:计算当前页的结束索引。
    • 结束索引计算公式为 起始索引 + 每页数据条数
  6. return this.dataList.slice(startIndex, endIndex);:根据起始索引和结束索引,使用 slice() 方法从 dataList 数组中截取出当前页的数据,并将其作为计算属性的返回值。
 3、点击搜索按钮获取模糊查询的值
//模糊查询
			search_wip_name(e) {
				this.wip_entity_name = e.detail.value.wip_entity_name //工单号
				this.ItemNo = e.detail.value.ItemNo //料号
				this.ItemName = e.detail.value.ItemName //料号名称
				this.getData(1); // 调用getData方法重新获取数据
			},
 4、选择行功能
//选择行
			selectRow(index, wipEntityName) {
				const selectedItem = this.dataList[index];
				if (selectedItem.selectedIndex === index && selectedItem.selectedRow) {
					// 取消选中状态并清空wip_entity_name的值
					this.dataList = this.dataList.map(item => ({
						...item,
						selectedIndex: -1,
						selectedRow: false
					}));
					this.wip_entity_name = '';
				} else {
					// 选中当前行并获取wip_entity_name的值
					this.dataList = this.dataList.map((item, i) => ({
						...item,
						selectedIndex: i === index ? index : -1,
						selectedRow: i === index ? !item.selectedRow : false
					}));
					this.wip_entity_name = wipEntityName;
				}
			},

selectRow(index, wipEntityName)方法接受两个参数 index 和 wipEntityName,分别表示被选中行的索引和对应的 wip_entity_name 属性值。

const selectedItem = this.dataList[index];:根据索引获取被选中的行的数据项对象,存储在 selectedItem 变量中。

if (selectedItem.selectedIndex === index && selectedItem.selectedRow) { ... }:判断当前被选中的行是否已经处于选中状态。

  • 如果是,表示用户要取消选中该行,进入 if 代码块内部。
  • 否则,表示用户要选中该行,进入 else 代码块内部。

如果进入了 else 代码块:

        this.dataList = this.dataList.map(item => ({
                        ...item,
                        selectedIndex: -1,
                        selectedRow: false
               }));

        this.wip_entity_name = '';

  • 使用 map() 方法遍历 dataList 数组,将每一行的 selectedIndex 设置为 -1(表示未选中),selectedRow 设置为 false(表示非选中状态)。
  • 将更新后的 dataList 赋值回原来的 dataList 数组,以更新数据。
  • 将 wip_entity_name 属性设置为空字符串,清空其值。

如果进入了 else 代码块:

        // 选中当前行并获取wip_entity_name的值
        this.dataList = this.dataList.map((item, i) => ({
                        ...item,
                        selectedIndex: i === index ? index : -1,
                        selectedRow: i === index ? !item.selectedRow : false
               }));
        this.wip_entity_name = wipEntityName;

  • 使用 map() 方法遍历 dataList 数组,将每一行的 selectedIndex 设置为当前行的索引(表示选中的行),selectedRow 设置为 true(表示选中状态)。
  • 将更新后的 dataList 赋值回原来的 dataList 数组,以更新数据。
  • 将 wip_entity_name 属性设置为参数 wipEntityName 的值,即被选中行对应的 wip_entity_name 值。
5、 上一页,下一页功能实现
//上一页
			prevPage() {
				if (this.currentPage > 1) {
					this.currentPage--;
					this.getData(this.currentPage); // 调用getData方法获取上一页数据
				}
			},
			//下一页
			nextPage() {
				if (this.currentPage < this.totalPage) {
					this.currentPage++;
					this.getData(this.currentPage); // 调用getData方法获取下一页数据
				}
			},

 prevPage 是一个方法的名称,用于获取上一页的数据。

if (this.currentPage > 1) 确保当前页码大于 1,即当前不是第一页。

如果满足条件,则执行以下操作:

  • 将当前页码 currentPage 减一,即跳转到上一页。
  • 调用 getData 方法,并传入更新后的 currentPage 作为参数,获取上一页的数据。

nextPage 是一个方法的名称,用于获取下一页的数据。

if (this.currentPage < this.totalPage) 确保当前页码小于总页数,即当前不是最后一页。

  • 将当前页码 currentPage 加一,即跳转到下一页。
  • 调用 getData 方法,并传入更新后的 currentPage 作为参数,获取下一页的数据。
 6、获取数据
前端代码
//获取数据
			getData(page) {
				uni.request({
					url: getApp().globalData.position + 'Produce/search_wip_name',
					data: {
						page: page,
						pageSize: this.pageSize,
						wip_entity_name: this.wip_entity_name, // 添加工单号参数
						ItemNo: this.ItemNo, // 添加料号参数
						ItemName: this.ItemName, // 添加料号名称参数
					},
					header: {
						"Content-Type": "application/x-www-form-urlencoded"
					},
					method: 'POST',
					dataType: 'json',
					success: res => {
						// this.dataList = res.data.info;
						this.dataList = res.data.info.map(item => ({
							...item,
							selectedIndex: -1,
							selectedRow: false
						}));
						this.totalPage = Math.ceil(parseInt(res.data.total) / this.pageSize);
						this.currentPage = page;
						// 更新 isFirstPage 和 isLastPage 的值
						this.isFirstPage = (page === 1);
						this.isLastPage = (page === this.totalPage);
					},
					fail(res) {
						console.log("查询失败");
					}
				});
			}
		},

使用 uni.request 方法发送请求,传入以下参数:

  • url:请求的地址,getApp().globalData.position + 'Produce/search_wip_name' 表示全局数据中的 position 属性值拼接上 'Produce/search_wip_name'
  • data:请求的参数对象,包括 pagepageSizewip_entity_nameItemNo 和 ItemName
  • header:请求头信息,设置 "Content-Type": "application/x-www-form-urlencoded"
  • method:请求方法,设置为 'POST',表示使用 POST 方法发送请求。
  • dataType:响应的数据类型,设置为 'json',表示期望返回 JSON 格式的数据。
  • success:请求成功时的回调函数,执行操作:
    • 将响应数据 res.data.info 赋值给 this.dataList(设置页面需要展示的数据),并通过 map() 方法给每个数据项添加属性 selectedIndex 和 selectedRow,并初始化为 -1 和 false
    • 根据总数据量 res.data.total 和每页显示数量 this.pageSize 计算出总页数,并赋值给 this.totalPage
    • 将当前页码 page 赋值给 this.currentPage
    • 更新 this.isFirstPage 和 this.isLastPage 的值,根据当前页码和总页数判断是否为第一页或最后一页。
  • fail:请求失败时的回调函数,打印出 "查询失败"
 后端代码(thinkphp)
  public function search_wip_name()
{
    //从前端传入当前页码和每页总数
    $page = input('post.page', 1); // 当前页码,默认为1
    $pageSize = input('post.pageSize', 10); // 每页显示的数据条数,默认为10
    //从前端传入模糊查询的条件
    $wip_entity_name = input('post.wip_entity_name', '');
    $ItemNo = input('post.ItemNo', '');
    $ItemName = input('post.ItemName', '');
    //进行数据库查询
    $data['info'] = Db::table('wip_jobs_all')
        ->alias('a')
        ->join(['sf_item_no' => 'b'], 'a.primary_item=b.item_no')
        ->field('a.plan_start_date, a.start_quantity, a.wip_entity_name, a.quantity_completed, a.primary_item, b.item_desc, b.item_name, a.creation_date')
        ->where([
            'a.status_type' => ['<>', '关闭'],
            'a.wip_entity_name' => ['not in', function ($query) {
                $query->table('wip_material_requierments')->where('quantity_issued', '>', 0)->field('wip_entity_name');
            }]
        ])
        //模糊查询条件
        ->where([
            'a.wip_entity_name' => ['like', '%' . $wip_entity_name . '%'],
            'a.primary_item' => ['like', '%' . $ItemNo . '%'],
            'b.item_name' => ['like', '%' . $ItemName . '%'],
        ])
        ->order('a.wip_entity_name DESC')
        //加入页码和每页数量的限制
        ->limit(($page - 1) * $pageSize, $pageSize)
        ->select();
    // 格式化时间
    foreach ($data['info'] as &$item) {
        $item['creation_date'] = date('Y-m-d H:i:s', $item['creation_date']);
    }
    //计算查询总数
    $total = Db::table('wip_jobs_all')
        ->alias('a')
        ->join(['sf_item_no' => 'b'], 'a.primary_item=b.item_no')
        ->where([
            'a.status_type' => ['<>', '关闭'],
            'a.wip_entity_name' => ['not in', function ($query) {
                $query->table('wip_material_requierments')->where('quantity_issued', '>', 0)->field('wip_entity_name');
            }]
        ])
        ->where([
            'a.wip_entity_name' => ['like', '%' . $wip_entity_name . '%'],
            'a.primary_item' => ['like', '%' . $ItemNo . '%'],
            'b.item_name' => ['like', '%' . $ItemName . '%'],
        ])
        ->count();
    $data['total'] = strval($total); // 将总数转换为字符串类型
    //输出数据
    echo json_encode($data);
}
 7、 组件已经被挂载到 DOM 中
mounted() {
			this.getData(1);
		}

mounted :"组件已经被挂载到 DOM 中" 表示 Vue 组件的实例已经被创建并成功插入到了页面的 DOM 结构中,此时组件的模板内容已经被渲染到页面上。

mounted 钩子函数中,调用了 getData 方法,并传入参数 1。具体解析如下:

  1. mounted 是一个生命周期钩子函数,表示组件已经被挂载到 DOM 中。
  2. 在该函数中,调用了 this.getData(1),即调用了名为 getData 的方法,并传入参数 1
  3. 这表示在组件挂载后,会立即调用 getData 方法,参数为 1,以获取第一页的数据。
  4. 通过这段代码,在组件加载完毕后将立即执行获取数据的操作,获取第一页的数据并进行展示

完整代码

 前端

<template>
	<view>
		<!-- 搜索框-->
		<form action="" @submit="search_wip_name">
			<view class="search_position">
				<view class="search">
					<view class="search_left">
						工单名称:
					</view>
					<view class="search_right">
						<input name="wip_entity_name" type="text" />
					</view>
				</view>
			</view>
			<view class="search_position">
				<view class="search">
					<view class="search_left">
						料号:
					</view>
					<view class="search_right">
						<input name="ItemNo" type="text" />
					</view>
				</view>
			</view>
			<view class="search_position">
				<view class="search">
					<view class="search_left">
						名称:
					</view>
					<view class="search_right">
						<input name="ItemName" type="text" />
					</view>
				</view>
			</view>
			<view class="search_position">
				<view class="btn_position">
					<button class="button" form-type="submit">查询</button>
					<button class="button1" >确认</button>
				</view>
			</view>
		</form>
		<!-- 表格 -->
		<scroll-view scroll-x="true" style="overflow-x: scroll; white-space: nowrap;" lower-threshold="50">
			<view class="table">
				<view class="table-tr">
					<view class="table-th1">工单名称</view>
					<view class="table-th1">料号</view>
					<view class="table-th1">料号名称</view>
					<view class="table-th1">规格型号</view>
					<view class="table-th1">预计开工日</view>
					<view class="table-th1">开工量</view>
				</view>
				<!-- :class="{ selected: selectedIndex === index,'selected-row':selectedRow ===index }" -->
				<view class="table-tr" v-for="(item, index) in dataList" :key="index"
					:class="{ selected: item.selectedIndex === index, 'selected-row': item.selectedRow }"
					@click="selectRow(index,item.wip_entity_name)">
					<view class="table-td1">{{item.wip_entity_name}}</view>
					<view class="table-td2">{{item.primary_item}}</view>
					<view class="table-td2">{{item.item_name}}</view>
					<view class="table-td2">{{item.item_desc}}</view>
					<view class="table-td2">{{item.plan_start_date}}</view>
					<view class="table-td2">{{item.start_quantity}}</view>
				</view>
			</view>
		</scroll-view>

		<!-- 分页 -->
		<view class="pagination">
			<view class="up_page" :class="{ 'first-page': isFirstPage }" :disabled="currentPage === 1"
				@click="prevPage">
				<</view>
					<view class="now_page">
						<text style="color:#2979ff">{{ currentPage }} </text><text
							style="color:#4b4b4b">/{{ totalPage }}</text>
					</view>
					<view class="down_page" :class="{ 'last-page': isLastPage }" :disabled="currentPage === totalPage"
						@click="nextPage">></view>
			</view>
		</view>
	</view>
</template>

<script>
	export default {
		data() {
			return {
				dataList: [],
				currentPage: 1,
				pageSize: 10,
				totalPage: 0,
				selectedIndex: -1,
				isFirstPage: '',
				isLastPage: '',
				selectedRow: '',
				wip_entity_name: '',
				ItemNo: '',
				ItemName: '',
			};
		},
		computed: {
			getCurrentPageData() {
				const startIndex = (this.currentPage - 1) * this.pageSize;
				const endIndex = startIndex + this.pageSize;
				return this.dataList.slice(startIndex, endIndex);
			}
		},
		methods: {
			//模糊查询
			search_wip_name(e) {
				this.wip_entity_name = e.detail.value.wip_entity_name //工单号
				this.ItemNo = e.detail.value.ItemNo //料号
				this.ItemName = e.detail.value.ItemName //料号名称
				this.getData(1); // 调用getData方法重新获取数据
			},
			//选择行
			selectRow(index, wipEntityName) {
			  const selectedItem = this.dataList[index];
			  if (selectedItem.selectedIndex === index && selectedItem.selectedRow) {
			    // 取消选中状态并清空wip_entity_name的值
			    this.dataList = this.dataList.map(item => ({
			      ...item,
			      selectedIndex: -1,
			      selectedRow: false
			    }));
			    this.wip_entity_name = '';
			  } else {
			    // 选中当前行并获取wip_entity_name的值
			    this.dataList = this.dataList.map((item, i) => ({
			      ...item,
			      selectedIndex: i === index ? index : -1,
			      selectedRow: i === index ? !item.selectedRow : false
			    }));
			    this.wip_entity_name = wipEntityName;
			  }
			},
			//上一页
			prevPage() {
				if (this.currentPage > 1) {
					this.currentPage--;
					this.getData(this.currentPage); // 调用getData方法获取上一页数据
				}
			},
			//下一页
			nextPage() {
				if (this.currentPage < this.totalPage) {
					this.currentPage++;
					this.getData(this.currentPage); // 调用getData方法获取下一页数据
				}
			},
			//获取数据
			getData(page) {
				uni.request({
					url: getApp().globalData.position + 'Produce/search_wip_name',
					data: {
						page: page,
						pageSize: this.pageSize,
						wip_entity_name: this.wip_entity_name, // 添加工单号参数
						ItemNo: this.ItemNo, // 添加料号参数
						ItemName: this.ItemName, // 添加料号名称参数
					},
					header: {
						"Content-Type": "application/x-www-form-urlencoded"
					},
					method: 'POST',
					dataType: 'json',
					success: res => {
						// this.dataList = res.data.info;
						this.dataList = res.data.info.map(item => ({
							...item,
							selectedIndex: -1,
							selectedRow: false
						}));
						this.totalPage = Math.ceil(parseInt(res.data.total) / this.pageSize);
						this.currentPage = page;
						// 更新 isFirstPage 和 isLastPage 的值
						this.isFirstPage = (page === 1);
						this.isLastPage = (page === this.totalPage);
					},
					fail(res) {
						console.log("查询失败");
					}
				});
			}
		},
		mounted() {
			this.getData(1);
		}
	};
</script>
<style>
	/* 行选择样式 */
	.selected-row {
		background-color: #74bfe7;
	}

	/* 第一页和最后一页,按钮的样式 */
	.up_page.first-page {
		color: #afafaf;
	}

	.down_page.last-page {
		color: #afafaf;
	}

	/* 翻页样式 */
	.pagination {
		display: flex;
		width: 100%;
		background-color: #f5f5f5;
		align-items: center;
		justify-items: center;
		justify-content: center;
		height: 60rpx;
		border: 1rpx solid gray;
		border-top: none;
	}

	.up_page {
		width: 10%;
		text-align: center;
		color: #4b4b4b;
	}

	.down_page {
		width: 10%;
		text-align: center;
		color: #4b4b4b;
	}

	.now_page {
		width: 80%;
		text-align: center;
	}

	/* 表格样式 */
	.table {
		margin-top: 5%;
		font-size: 85%;
		display: table;
		width: 200%;
		border-collapse: collapse;
		box-sizing: border-box;
	}

	.table-tr {
		display: table-row;
	}

	.table-th1 {
		width: 20%;
		display: table-cell;
		font-weight: bold;
		border: 1rpx solid gray;
		background-color: #51aad6;
		text-align: center;
		vertical-align: middle;
		padding: 10rpx 0;
		overflow: hidden;
		text-overflow: ellipsis;
		word-break: break-all;
	}

	.table-th2 {
		width: 30%;
		display: table-cell;
		font-weight: bold;
		border: 1rpx solid gray;
		background-color: #51aad6;
		text-align: center;
		vertical-align: middle;
		padding: 10rpx 0;
		overflow: hidden;
		text-overflow: ellipsis;
		word-break: break-all;
	}

	.table-th3 {
		width: 50%;
		display: table-cell;
		font-weight: bold;
		border: 1rpx solid gray;
		background-color: #51aad6;
		text-align: center;
		vertical-align: middle;
		padding: 10rpx 0;
		overflow: hidden;
		text-overflow: ellipsis;
		word-break: break-all;
	}

	.table-td1 {
		width: 20%;
		display: table-cell;
		border: 1rpx solid gray;
		text-align: center;
		vertical-align: middle;
		padding: 10rpx 0;
		overflow: hidden;
		text-overflow: ellipsis;
		word-break: break-all;
	}

	.table-td2 {
		width: 30%;
		display: table-cell;
		border: 1rpx solid gray;
		text-align: center;
		vertical-align: middle;
		padding: 10rpx 0;
		overflow: hidden;
		text-overflow: ellipsis;
		word-break: break-all;
	}

	.table-td3 {
		width: 50%;
		display: table-cell;
		border: 1rpx solid gray;
		text-align: center;
		vertical-align: middle;
		overflow: hidden;
		text-overflow: ellipsis;
		word-break: break-all;
		/* padding: 5px 0; */
	}

	/* 搜索框 */
	.search_position {
		display: flex;
		align-items: center;
		justify-content: center;
		width: 100%;
		margin: 5% 0;
		/* border:1px solid black; */
	}

	.search {
		width: 90%;
		/* border:1px solid black; */
		display: flex;
	}

	.search_left {
		font-size: 105%;
		font-weight: bold;
		color: rgb(90, 90, 90);
		width: 30%;
	}

	.search_right {
		border-bottom: 1px solid rgb(95, 95, 95);
		width: 70%;
	}

	.btn_position {
		display: flex;
		align-items: center;
		justify-content: center;
		width: 60%;
		margin: 2% 0;
		/* border: 1px solid black; */
	}

	.button {
		margin-top: 5%;
		background-color: #40A4D6;
		color: #fff;
		font-size: 30rpx;
		/* border: 1px solid black; */
	}

	.button1 {
		margin-top: 5%;
		background-color: #fff ;
		color: #40A4D6;
		font-size: 30rpx;
		border: 1px solid #40A4D6;
	}
</style>

 后端

  //模糊查询工单
  public function search_wip_name()
{
//获取前台传来的页码和每页显示数
    $page = input('post.page', 1); // 当前页码,默认为1
    $pageSize = input('post.pageSize', 10); // 每页显示的数据条数,默认为10
//获取模糊查询的条件
    $wip_entity_name = input('post.wip_entity_name', '');//工单
    $ItemNo = input('post.ItemNo', '');//料号
    $ItemName = input('post.ItemName', ''); //料号名称
//查询数据,代入分页的限制条件->limit(($page - 1) * $pageSize, $pageSize)  
    $data['info'] = Db::table('wip_jobs_all')
        ->alias('a')
        ->join(['sf_item_no' => 'b'], 'a.primary_item=b.item_no')
        ->field('a.plan_start_date, a.start_quantity, a.wip_entity_name, a.quantity_completed, a.primary_item, b.item_desc, b.item_name, a.creation_date')
        ->where([
            'a.status_type' => ['<>', '关闭'],
            'a.wip_entity_name' => ['not in', function ($query) {
                $query->table('wip_material_requierments')->where('quantity_issued', '>', 0)->field('wip_entity_name');
            }]
        ])
        ->where([
            'a.wip_entity_name' => ['like', '%' . $wip_entity_name . '%'],
            'a.primary_item' => ['like', '%' . $ItemNo . '%'],
            'b.item_name' => ['like', '%' . $ItemName . '%'],
        ])
        ->order('a.wip_entity_name DESC')
        ->limit(($page - 1) * $pageSize, $pageSize)
        ->select();
    // 格式化时间
    foreach ($data['info'] as &$item) {
        $item['creation_date'] = date('Y-m-d H:i:s', $item['creation_date']);
    }
//计算总条数
    $total = Db::table('wip_jobs_all')
        ->alias('a')
        ->join(['sf_item_no' => 'b'], 'a.primary_item=b.item_no')
        ->where([
            'a.status_type' => ['<>', '关闭'],
            'a.wip_entity_name' => ['not in', function ($query) {
                $query->table('wip_material_requierments')->where('quantity_issued', '>', 0)->field('wip_entity_name');
            }]
        ])
        ->where([
            'a.wip_entity_name' => ['like', '%' . $wip_entity_name . '%'],
            'a.primary_item' => ['like', '%' . $ItemNo . '%'],
            'b.item_name' => ['like', '%' . $ItemName . '%'],
        ])
        ->count();
    $data['total'] = strval($total); // 将总数转换为字符串类型
//输出数据
    echo json_encode($data);
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/819407.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【AGC】Publishing API调用问题汇总

【问题背景】 开发者可以通过Publishing API完成几乎所有应用的管理和发布工作&#xff0c;自己制定自动发布接口。Publishing API有很多接口&#xff0c;包括了查询应用信息、更新应用信息、上传文件、提交发布等主要接口。下面总结了一些开发者在使用Publishing API过程中容…

构建高效物理计划:从逻辑查询到算子实现

​一、前言 本文主要介绍内容一条查询语句如何实现由逻辑计划生成物理计划。查询语句要执行的操作、涉及的表信息等存放于逻辑计划的 PlanNode 中&#xff0c;物理计划的构建就是通过解析逻辑计划的 PlanNode&#xff0c;将对应的 PlanNode 转换为对应算子&#xff08;Process…

springboot整合tio-websocket方案实现简易聊天

写在最前&#xff1a; 常用的http协议是无状态的&#xff0c;且不能主动响应到客户端。最初想实现状态动态跟踪只能用轮询或者其他效率低下的方式&#xff0c;所以引入了websocket协议&#xff0c;允许服务端主动向客户端推送数据。在WebSocket API中&#xff0c;浏览器和服务…

富士通“Actlyzer”提供基于AI的基于视频的行为分析

想象一下这样的场景&#xff1a;一个男人走近一个家的前门&#xff0c;蹲下并检查钥匙孔。这是丢失房屋钥匙的居民还是客人&#xff1f;还是寻找入口点的窃贼&#xff1f;“Actlyzer”是一种新的人工智能安全系统&#xff0c;旨在区分这种情况。富士通实验室和研发中心的行为分…

经典文献阅读之--Online Extrinsic Calibration(激光雷达,视觉和惯导外参在线标定)

0. 简介 为了实现精确定位&#xff0c;自动驾驶车辆通常依靠围绕移动平台的多传感器感知系统。校准是一个耗时的过程&#xff0c;机械畸变会导致外部校准误差。因此&#xff0c;《Lidar-Visual-Inertial Odometry with Online Extrinsic Calibration》提出了一种激光雷达-视觉…

安卓手机怎样录屏?手机录屏小技巧分享

如果你需要在安卓手机上录制一段视频或者教程&#xff0c;录屏功能是一个非常有用的工具。在这篇文章中&#xff0c;我们将会介绍安卓手机如何录屏&#xff0c;并分享一些小技巧。 在安卓手机上录屏的方法有很多种&#xff0c;这里我们介绍两种比较常用的方法。 方法一&#x…

Nodejs 爬虫 第二章(通过掘金 userId 抓取到所有文章)!HTML to Markdown

前言 就在昨天晚上&#xff0c;做了一个通过掘金文章链接进行解析html转化为markdown文档&#xff0c;并且把图片进行下载和替换&#xff0c;但是最后也留了个伏笔&#xff08;我一定会回来的&#xff5e;&#xff09;就是通过用户id&#xff0c;把所有的文章都转化出来&#x…

安卓嵌入h5页面方法笔记

<?xml version"1.0" encoding"utf-8"?> <manifest xmlns:android"http://schemas.android.com/apk/res/android"xmlns:tools"http://schemas.android.com/tools"><uses-featureandroid:name"android.hardware.t…

2023年的深度学习入门指南(24) - 处理音频的大模型 OpenAI Whisper

2023年的深度学习入门指南(24) - 处理音频的大模型 OpenAI Whisper 在这一讲之前&#xff0c;我们所用的大模型都是针对文本的。这一讲我们增加一个新的领域&#xff0c;即音频。我们将介绍OpenAI的Whisper模型&#xff0c;它是一个处理音频的大模型。 Whisper模型的用法 Wh…

万界星空/推出生产制造执行MES系统/开源MES/免费下载

免费MES系统介绍 什么是MES系统呢&#xff1f;MES系统主要功能就是解决“如何生产”的问题。通过实施MES系统&#xff0c;一站式解决您所困扰的所有生产制作流程问题。 普通的免费MES系统只提供简单的基本功能让客户体验&#xff0c;而万界星空MES系统运用低代码的形式开发&a…

Python初刷题笔记

目录 保留小数的方法&#xff1a;​编辑 进制问题如何转换&#xff1a; 大小写如何转换&#xff1a; 删除空格问题&#xff1a; 循环输入的简便方法&#xff1a; 截取某一部分所需要的函数&#xff1a; 字符串处理常用函数小汇总&#xff1a; sort和sorted函数的区别&am…

【Python】数据分析+数据挖掘——掌握Python和Pandas中的单元格替换操作

1. 前言 数据处理和清洗是数据分析和机器学习中至关重要的步骤。在数据处理过程中&#xff0c;我们经常需要对数据集进行清洗和转换&#xff0c;其中单元格替换是一个常用的技术。Python作为一种功能强大且灵活的编程语言&#xff0c;为数据处理提供了丰富的工具和库。Pandas库…

《你不知道的 Chrome 调试技巧》-- 学习笔记

截全屏 ctrl shift p &#xff1a;调出command 然后输入screen 效果 引用上次结果 在console中&#xff0c;想要引用上次的计算结果 使用$_ 添加有条件的断点 右击行号&#xff0c;选择 Add conditional breakpoint...(添加条件断点) 或者右击一个已经设置的断点并且选择…

GC垃圾回收器【学习笔记】

GC&#xff1a;Garbage Collectors 垃圾回收器 C/C&#xff0c;手动回收内存&#xff1b;难调试、门槛高。忘记回收、多次回收等问题 Java、Golang等&#xff0c;有垃圾回收器&#xff1a;自动回收&#xff0c;技术门槛降低 一、如何定位垃圾&#xff1f; https://www.infoq.c…

24考研数据结构-串的定义和基本实现

目录 第四章&#xff1a;串概论数据结构之串&#xff1a;定义、实现与存储结构1. 串的定义2. 串的实现方式2.1 顺序存储2.2 链式存储 3. 串的基本操作4. 串的应用结论 4.1串的定义和实现4.1.1串的定义4.1.2串的基本操作字符集编码 4.1.3串的存储结构1. 定长顺序存储表示基本操作…

海外ASO优化之通过应用商店优化来获得自然用户

应用商店优化需要我们跟踪关键词的数据&#xff0c;从而评估我们的ASO策略有效性。跟踪我们选择的时间段和国家/地区的重要搜索查询的历史排名和应用程序的最佳位置。根据我们关注的每个应用的关键词&#xff0c;位置&#xff0c;特色&#xff0c;评论和更新&#xff0c;立即了…

性能压力测试的重要性与实施方法

性能压力测试是在软件开发过程中评估系统在不同负载条件下的表现和稳定性的关键步骤。这种测试是为了确定系统在正常和峰值负载下的性能表现&#xff0c;以验证系统是否能够满足用户需求&#xff0c;同时发现潜在的性能问题并加以解决。 首先&#xff0c;性能压力测试对于确保系…

【HMS Core】融合搜索无法打开搜索服务连接问题

【关键字】 HMS、搜索服务、融合搜索 【问题描述】 有开发者反馈在集成搜索服务-融合搜索时&#xff0c;出现了无法打开搜索服务连接的问题。 严格按照官方文档集成&#xff0c;配置&#xff0c;权限已添加 searchServiceAbility .connect(new ServiceConnectCallback() { …

牛客网Verilog刷题——VL46

牛客网Verilog刷题——VL46 题目解析答案 题目 根据题目提供的双口RAM代码和接口描述&#xff0c;实现同步FIFO&#xff0c;要求FIFO位宽和深度参数化可配置。电路的接口如下图所示。   双口RAM端口说明&#xff1a; 同步FIFO端口说明&#xff1a; 双口RAM代码如下&#xff…

1、Tomcat

java介绍 Java语言和平台由以下几个主要部分组成&#xff1a; 1、Java编程语言(Java Language)&#xff1a;这是Java的核心部分&#xff0c;包括Java语法、关键字、数据类型、运算符、控制结构等。程序员使用Java语言来编写应用程序的源代码。 2、Java开发工具包(Java Developm…