agri-app/pages/mine/subpages/require/index.vue

642 lines
20 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<template>
<view class="container">
<view class="form-container">
<uni-section title="基础卡片" type="line">
<!-- 基础表单校验缩小字体+一行两列布局 -->
<uni-forms
ref="valiForm"
label-position="left"
:modelValue="form"
style="font-size: 10px;"
>
<!-- 一行两列布局容器 -->
<view class="form-row">
<uni-forms-item label="标题:" name="title" class="form-item">
<uni-easyinput
v-model="form.title"
placeholder="请输入标题搜索"
/>
</uni-forms-item>
<uni-forms-item label="详情:" name="detail" class="form-item">
<uni-easyinput
v-model="form.detail"
placeholder="请输入详情搜索"
/>
</uni-forms-item>
</view>
<!-- 第二行两列 -->
<view class="form-row">
<uni-forms-item label="优先级:" name="priority" class="form-item">
<uni-data-select
v-model="form.priority"
:localdata="priorityList"
/>
</uni-forms-item>
<uni-forms-item label="进度:" name="progress" class="form-item">
<uni-data-select
v-model="form.progress"
:localdata="progressList"
/>
</uni-forms-item>
</view>
</uni-forms>
<view class="btn-group">
<view class="btn-left">
<!-- 新增按钮:点击打开弹窗 -->
<button
class="iconfont icon-add mini-btn add-btn"
@click="openDialog('add')"
hover-class="is-hover"
type="default"
size="mini"
> 新增</button>
<!-- 删除按钮:未选中数据时禁用 -->
<button
class="iconfont icon-ashbin mini-btn del-btn"
hover-class="is-hover"
type="default"
size="mini"
:disabled="selectedIndexs.length === 0"
@click="batchDel"
> 删除</button>
<!-- 编辑按钮:未选中数据时禁用 -->
<button
class="iconfont icon-edit mini-btn edit-btn"
hover-class="is-hover"
type="default"
size="mini"
:disabled="selectedIndexs.length === 0"
@click="openDialog('edit')"
> 编辑</button>
</view>
<view class="btn-right">
<button
class="iconfont icon-search mini-btn"
hover-class="is-hover"
type="default"
size="mini"
@click="search"
> 查询</button>
</view>
</view>
</uni-section>
</view>
<view class="uni-container">
<!-- 表格区域:保持原有紧凑样式并优化 -->
<uni-table
ref="table"
:loading="loading"
border
stripe
type="selection"
emptyText="暂无更多数据"
@selection-change="selectionChange"
style="width: 100%;"
:border-width="1"
>
<uni-tr>
<uni-th align="center" class="ui-th" sortable width="200rpx" @sort-change="idSort">需求单号</uni-th>
<uni-th align="center" width="300rpx" class="ui-th">需求标题</uni-th>
<uni-th align="center" width="240rpx" class="ui-th">需求详情</uni-th>
<uni-th align="center" width="140rpx" @sort-change="prioritySort" sortable class="ui-th">优先级</uni-th>
<uni-th align="center" width="140rpx" class="ui-th">进度</uni-th>
<uni-th align="center" width="200rpx" class="ui-th">需求类型</uni-th>
<uni-th align="center" width="200rpx" class="ui-th">经办人名称</uni-th>
<uni-th align="center" width="300rpx" class="ui-th">操作</uni-th>
</uni-tr>
<uni-tr v-for="(item, index) in tableData" :key="index" style="height: 30px; line-height: 30px;">
<uni-td style="padding: 1px 0; font-size: 13px;">{{ item.id }}</uni-td>
<uni-td style="padding: 1px 0; font-size: 13px;">{{ item.title }}</uni-td>
<uni-td style="padding: 1px 0; font-size: 13px;">
<view class="name">{{ item.detail }}</view>
</uni-td>
<uni-td align="center" style=" padding: 1px 0; font-size: 13px;">{{ item.priority }}</uni-td>
<uni-td align="center" style=" padding: 1px 0; font-size: 13px;">{{ item.progress }}</uni-td>
<uni-td align="center" style=" padding: 1px 0; font-size: 13px;">{{ item.reqType }}</uni-td>
<uni-td align="center" style=" padding: 1px 0; font-size: 13px;">{{ item.assigneeName }}</uni-td>
<uni-td style="width: auto; padding: 1px 0; font-size: 13px;">
<view class="uni-group">
<!-- 行内修改按钮:点击打开编辑弹窗 -->
<button size="mini" type="primary" style="padding: 1px 6px; font-size: 10px;" @click="openDialog('edit', item)">修改</button>
<!-- 行内删除按钮:点击单行删除 -->
<button size="mini" type="warn" style="padding: 1px 6px; font-size: 10px;" @click="delSingle(item)">删除</button>
</view>
</uni-td>
</uni-tr>
</uni-table>
<view class="uni-pagination-box" style="margin-top: 8px;">
<uni-pagination
show-icon
:page-size="form.pageSize"
:current="form.pageNum"
:total="total"
@change="change"
style="font-size: 11px;"
/>
</view>
</view>
<!-- 新增/修改弹窗 -->
<uni-popup ref="formDialog" type="center" :mask-click="false">
<view class="dialog-container">
<view class="dialog-title">{{ dialogType === 'add' ? '新增需求' : '编辑需求' }}</view>
<!-- 弹窗表单 -->
<uni-forms
ref="dialogForm"
label-width="65px"
label-position="left"
:modelValue="dialogFormData"
:rules="formRules"
style="padding: 10rpx;"
>
<!-- 需求标题(必填) -->
<uni-forms-item label="需求标题:" name="title" required>
<uni-easyinput
v-model="dialogFormData.title"
placeholder="请输入需求标题"
style="font-size: 12px;"
/>
</uni-forms-item>
<!-- 详情(必填) -->
<uni-forms-item label="详情:" name="detail" required>
<uni-easyinput
v-model="dialogFormData.detail"
type="textarea"
placeholder="请输入需求详情"
style="font-size: 12px; height: 100px;"
/>
</uni-forms-item>
<!-- 优先级(下拉框,默认高) -->
<uni-forms-item label="优先级:" name="priority">
<uni-data-select
v-model="dialogFormData.priority"
:localdata="priorityList"
style="font-size: 12px;"
/>
</uni-forms-item>
<!-- 进度(下拉框) -->
<uni-forms-item label="进度:" name="progress">
<uni-data-select
v-model="dialogFormData.progress"
:localdata="progressList"
style="font-size: 12px;"
/>
</uni-forms-item>
<!-- 需求类型(下拉框) -->
<uni-forms-item label="需求类型:" name="reqType">
<uni-data-select
v-model="dialogFormData.reqType"
:localdata="reqTypeList"
style="font-size: 12px;"
/>
</uni-forms-item>
<!-- 经办人(可选输入框) -->
<uni-forms-item label="经办人:" name="assigneeName">
<uni-easyinput
v-model="dialogFormData.assigneeName"
placeholder="请输入经办人名称"
style="font-size: 12px;"
/>
</uni-forms-item>
</uni-forms>
<!-- 弹窗按钮 -->
<view class="dialog-btn-group">
<button class="cancel-btn" @click="closeDialog">取消</button>
<button class="confirm-btn" @click="submitDialog"></button>
</view>
</view>
</uni-popup>
</view>
</template>
<script>
import UniTh from "../../../../uni_modules/uni-table/components/uni-th/uni-th.vue";
import UniTr from "../../../../uni_modules/uni-table/components/uni-tr/uni-tr.vue";
import UniTd from "../../../../uni_modules/uni-table/components/uni-td/uni-td.vue";
import {addRequire, delRequire, delRequires, listRequire, updateRequire} from "../../../../api/system/require";
import UniTable from "../../../../uni_modules/uni-table/components/uni-table/uni-table.vue";
import UniPopup from "../../../../uni_modules/uni-popup/components/uni-popup/uni-popup.vue";
import UniForms from "../../../../uni_modules/uni-forms/components/uni-forms/uni-forms.vue";
import UniFormsItem from "../../../../uni_modules/uni-forms/components/uni-forms-item/uni-forms-item.vue";
import UniEasyinput from "../../../../uni_modules/uni-easyinput/components/uni-easyinput/uni-easyinput.vue";
import UniDataSelect from "../../../../uni_modules/uni-data-select/components/uni-data-select/uni-data-select.vue";
export default {
components: {
UniTable, UniTd, UniTr, UniTh,
UniPopup, UniForms, UniFormsItem, UniEasyinput, UniDataSelect
},
data() {
return {
searchVal: '',
tableData: [],
total: 0,
// 优先级下拉选项
priorityList: [
{ value: 0, text: '高' },
{ value: 1, text: '中' },
{ value: 2, text: '低' }
],
// 进度下拉选项
progressList: [
{ value: 0, text: '未完成' },
{ value: 1, text: '进行中' },
{ value: 2, text: '已完成' }
],
// 需求类型下拉选项(可根据实际需求补充)
reqTypeList: [
{ value: 0, text: '功能需求' },
{ value: 1, text: '优化需求' },
{ value: 2, text: 'BUG修复' }
],
form: {
title: null,
detail: null,
priority: null,
progress: null,
pageNum: 1,
pageSize: 10
},
loading: false,
selectIds:[],
selectedIndexs: [], // 已选择的行索引
// 弹窗相关
dialogType: 'add', // add-新增 edit-编辑
dialogFormData: {
title: '',
detail: '',
priority: 0, // 默认高
progress: 0,
reqType: '',
assigneeName: ''
},
// 表单校验规则
formRules: {
title: {
rules: [{ required: true, errorMessage: '请输入需求标题' }]
},
detail: {
rules: [{ required: true, errorMessage: '请输入需求详情' }]
}
},
currentEditItem: null // 当前编辑的行数据
}
},
onLoad() {
this.getData()
},
methods: {
// 多选处理
selectedItems() {
this.selectIds = this.selectedIndexs.map(i => this.tableData[i].id);
return this.selectedIndexs.map(i => this.tableData[i])
},
// 补充selection-change事件
selectionChange(e) {
this.selectedIndexs = e.detail.index
console.info(e)
},
idSort(e) {
if (e["order"] === 'descending') {
this.tableData.sort((a, b) => b.id - a.id);
return;
}
this.tableData.sort((a, b) => a.id - b.id);
},
prioritySort(e) {
if (e.order === 'descending') {
this.tableData.sort((a, b) => b.priority - a.priority);
return;
}
this.tableData.sort((a, b) => a.priority - b.priority);
},
// ========== 删除相关方法 ==========
// 批量删除
batchDel() {
const data = this.tableData.filter(item => !this.selectIds.includes(item.id));
console.info(`${this.selectIds}选中的数据:${JSON.stringify(data)} `)
// todo 多选删除 有bug 第二次删除之前第一次删除还在的索引还在
const selectedItems = this.selectedItems()
if (selectedItems.length === 0) {
uni.showToast({ title: '请选择要删除的数据', icon: 'none' })
return
}
const selectedIds = selectedItems.map(item => Number(item.id))
.filter(id => id !== undefined && id !== null && id !== '');
uni.showModal({
title: '提示',
content: `确定要删除选中的${selectedItems.length}条数据吗?`,
success: (res) => {
if (res.confirm) {
delRequires(selectedIds).then((response) => {
if (response.code === 200) {
uni.showToast({ title: '批量删除成功', icon: 'success' })
} else {
uni.showToast({ title: '批量删除失败', icon: 'error' })
}
this.getData()
this.selectedIndexs=[]
})
}
}
})
},
// 分页触发
change(e) {
this.selectedIndexs = []
this.getData(e.current)
},
// 搜索
search() {
this.getData()
},
// 获取数据
getData(pageNum) {
this.loading = true
this.form.pageNum = pageNum || this.form.pageNum
listRequire(this.form).then(response => {
if (response.code === 200 && response.rows) {
this.tableData = response.rows
this.total = response.total
}
this.loading = false
}).catch(error => {
console.error('获取数据失败:', error)
this.loading = false
})
},
// ========== 弹窗相关方法 ==========
// 打开弹窗
openDialog(type, item = null) {
this.dialogType = type
// 重置表单
this.dialogFormData = {
title: '',
detail: '',
priority: 0,
progress: 0,
reqType: '',
assigneeName: ''
}
// 编辑模式:回显数据
if (type === 'edit') {
// 批量编辑取第一个选中项行内编辑取传入的item
const editItem = item || this.selectedItems()[0]
if (editItem) {
this.currentEditItem = editItem
this.dialogFormData = { ...editItem }
} else {
uni.showToast({ title: '请选择要编辑的数据', icon: 'none' })
return
}
}
// 打开弹窗
this.$refs.formDialog.open()
},
// 关闭弹窗
closeDialog() {
this.$refs.formDialog.close()
// 重置表单校验
this.$refs.dialogForm.clearValidate()
},
// 提交弹窗表单
submitDialog() {
// 表单校验
this.$refs.dialogForm.validate().then(() => {
if (this.dialogType === 'add') {
addRequire(this.dialogFormData).then(response => {
if (response.code===200) {
this.$modal.msgSuccess("新增成功")
} else {
this.$modal.msgError("新增失败")
}
this.getData()
})
} else {
updateRequire(this.dialogFormData).then(response => {
if (response.code===200) {
this.$modal.msgSuccess("修改成功")
} else {
this.$modal.msgError("修改失败")
}
this.getData()
})
}
// 关闭弹窗并刷新数据
this.closeDialog()
}).catch(err => {
console.error('表单校验失败:', err)
})
},
// 单行删除
delSingle(item) {
uni.showModal({
title: '提示',
content: '确定要删除这条数据吗?',
success: (res) => {
if (res.confirm) {
delRequire(item.id).then(response => {
if (response.code === 200) {
uni.showToast({title: '删除成功', icon: 'success'})
} else {
uni.showToast({title: '删除失败', icon: 'success'})
}
})
this.getData()
this.selectedIndexs=[]
}
}
})
}
}
}
</script>
<style scoped>
/* 页面基础样式重置 */
page {
padding-top: 20rpx !important;
padding-bottom: 20rpx !important;
font-size: 12px;
}
/* 整体容器样式 */
.container {
margin: 20rpx;
border-radius: 20rpx;
background: #fff;
font-size: 12px;
}
.form-container {
margin: 20rpx 0 0 0;
padding: 15rpx;
border-radius: 20rpx;
background: #fff;
}
/* 表单一行两列布局核心样式 - 优化版 */
.form-row {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
margin: 0 10rpx 10rpx 10rpx;
width: 100%;
/* 新增清除flex布局默认的基线对齐避免垂直错位 */
align-items: flex-start;
/* 新增:计算宽度时包含内边距/边框,避免溢出 */
box-sizing: border-box;
}
.form-item {
display: flex;
align-items: center;
width: 48%; /* 保留你的48%宽度留2%间距 */
box-sizing: border-box;
margin: 0 !important; /* 保留清除默认间距 */
/* 新增适配uni-forms-item的关键样式 */
padding: 0; /* 清除组件默认内边距 */
min-height: auto; /* 取消组件默认最小高度,避免高度不一致 */
}
/* 新增适配uni-data-select组件防止下拉框溢出 */
.form-item .uni-data-select {
width: 100%; /* 下拉选择器占满form-item宽度 */
flex: 1; /* 让选择器自适应剩余空间 */
}
/* 新增统一label标签样式避免文字错位 */
.form-item .uni-forms-item__label {
/* 根据你的需求调整label宽度比如固定120rpx */
flex: 0 0 120rpx;
padding: 0; /* 清除默认内边距 */
margin-right: 10rpx; /* label和选择器之间留间距 */
}
/* 新增:统一表单项内容区域样式 */
.form-item .uni-forms-item__content {
flex: 1; /* 内容区域占满剩余宽度 */
padding: 0; /* 清除默认内边距 */
}
/* 核心父容器flex布局通过justify-content: space-between实现左右分布 */
.btn-group {
display: flex;
justify-content: space-between; /* 关键:左右元素分别靠两端 */
align-items: center; /* 垂直居中,保证按钮对齐 */
width: 100%; /* 占满父容器宽度,确保分布效果 */
padding: 20rpx 10rpx 0; /* 左右留间距,避免贴边 */
box-sizing: border-box;
}
/* 左侧按钮容器:横向排列,靠左 */
.btn-left {
display: flex;
align-items: center;
}
/* 右侧按钮容器:横向排列,靠右 */
.btn-right {
display: flex;
align-items: center;
}
/* 表格容器样式 */
.uni-container {
padding: 10px;
box-sizing: border-box;
}
.uni-group {
display: flex;
align-items: center;
justify-content: center;
}
/* 需求详情文字样式 */
.name {
line-height: 18px;
font-size: 11px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
/* 分页区域样式 */
.uni-pagination-box {
text-align: center;
}
/deep/ .uni-forms-item__label {
font-size: 12px !important;
padding: 0 !important;
}
/deep/ .uni-select, /deep/.uni-easyinput__content-input {
font-size: 12px !important;
height: 30px;
}
/* 弹窗样式 */
.dialog-container {
background: #fff;
border-radius: 10rpx;
padding: 20rpx;
width: 600rpx;
}
.dialog-title {
font-size: 16px;
font-weight: bold;
text-align: center;
padding: 10rpx 0;
border-bottom: 1px solid #eee;
margin-bottom: 10rpx;
}
.dialog-btn-group {
display: flex;
justify-content: flex-end;
margin-top: 20rpx;
gap: 10rpx;
}
/* 禁用按钮样式 */
/deep/ button[disabled] {
background-color: #e5e5e5 !important;
color: #999 !important;
border-color: #ddd !important;
}
/deep/ .uni-forms-item {
margin-bottom: 12rpx;
}
/deep/ .uni-table-td {
text-align: center !important;
}
.ui-th {
width: auto;
height: 18px;
line-height: 18px;
font-size: 13px;
}
.ui-th:last-child {
width: 160rpx;
}
/deep/ .uni-table-th {
padding: 16rpx 5rpx;
}
.uni-group button:last-child {
margin-left: 0;
}
</style>