Explorar o código

配件申请记录新增修改

jingshuyong hai 11 meses
pai
achega
92ce06d53b

+ 18 - 0
api/salesServiceManagement/accessory/index.js

@@ -28,3 +28,21 @@ export async function recyclePage(data) {
 	}
 	return Promise.reject(new Error(res.message));
 }
+
+// 配件申请记录 表格 新增
+export async function accessorySave(data) {
+	const res = await postJ(Vue.prototype.apiUrl + `/eom/sparePartsApply/saveOrUpdate`, data);
+	if (res.code == 0) {
+		return res.data;
+	}
+	return Promise.reject(new Error(res.message));
+}
+
+// 配件申请记录 表格 修改
+export async function accessoryUpdate(data) {
+	const res = await putJ(Vue.prototype.apiUrl + `/eom/sparePartsApply/update`, data);
+	if (res.code == 0) {
+		return res.data;
+	}
+	return Promise.reject(new Error(res.message));
+}

+ 170 - 8
pages/salesServiceManagement/accessory/accessoryAdd.vue

@@ -20,25 +20,27 @@
 			</u-cell>
 			<u-cell title="领用部门" arrow-direction="down">
 				<view slot="value" style="display: flex;align-items: center;width: 100%;">
-					<u--input :disabled="!isDisable" style="flex:1" border="surround" v-model="form.contactName">
+					<u--input disabled style="flex:1" border="surround" v-model="form.receivingDeptName">
 					</u--input>
 				</view>
 			</u-cell>
 			<u-cell title="领用人" arrow-direction="down">
 				<view slot="value" style="display: flex;align-items: center;width: 100%;">
-					<u--input :disabled="!isDisable" style="flex:1" border="surround" v-model="form.contactName">
+					<u--input disabled style="flex:1" border="surround" v-model="form.recipientName">
 					</u--input>
 				</view>
 			</u-cell>
 			<u-cell title="使用部门" arrow-direction="down">
 				<view slot="value" style="display: flex;align-items: center;width: 100%;">
-					<u--input :disabled="!isDisable" style="flex:1" border="surround" v-model="form.contactName">
+					<u--input @click.native="classification" :disabled="!isDisable" style="flex:1" border="surround"
+						placeholder="请选择使用部门" v-model="form.useDeptName">
 					</u--input>
 				</view>
 			</u-cell>
 			<u-cell title="使用人" arrow-direction="down">
 				<view slot="value" style="display: flex;align-items: center;width: 100%;">
-					<u--input :disabled="!isDisable" style="flex:1" border="surround" v-model="form.contactName">
+					<u--input :disabled="!isDisable" style="flex:1" border="surround" v-model="form.userName"
+						placeholder="请选择使用人" @click.native="openSelector">
 					</u--input>
 				</view>
 			</u-cell>
@@ -53,15 +55,41 @@
 				</view>
 			</u-cell>
 		</u-cell-group>
+		<accessoryList ref="accessoryRef" v-show="current == 1" />
 		<view class="footerButton" v-if="isDisable">
 			<u-button type="default" text="返回" @click="back"></u-button>
 			<u-button type="primary" @click="save" text="保存"></u-button>
 		</view>
+		<ba-tree-picker ref="treePicker" key="verify" :multiple="false" @select-change="confirm" title="选择部门"
+			:selectedData="selectedData" :localdata="classificationList" valueKey="id" textKey="name"
+			childrenKey="children" />
+		<search-select ref="selector" v-model="form.userId" :data-list="executorList" title="选择使用人"
+			@change="onClose"></search-select>
+		<u-toast ref="uToast"></u-toast>
 	</view>
 </template>
 
 <script>
+	import accessoryList from '@/pages/salesServiceManagement/workOrder/components/accessoryList.vue';
+	import searchSelect from '../accessory/components/searchSelect.vue';
+	import {
+		listOrganizations
+	} from '@/api/salesServiceManagement/workOrder/index.js';
+	import {
+		getUserPage
+	} from '@/api/common.js';
+	import {
+		toTreeData
+	} from '@/utils/utils.js';
+	import {
+		accessorySave,
+		accessoryUpdate
+	} from '@/api/salesServiceManagement/accessory/index.js'
 	export default {
+		components: {
+			searchSelect,
+			accessoryList
+		},
 		computed: {
 			isDisable() {
 				let flag = this.type != 'view'
@@ -74,28 +102,148 @@
 				list: ['基本信息', '配件信息'],
 				title: '',
 				type: '',
-				form: {}
+				form: {
+					repairId: '', // 工单Id
+					name: '', // 工单名称
+					recipientName: '', // 领用人名称
+					recipientId: '', // 领用人id
+					receivingDeptId: '', // 领用人部门Id
+					receivingDeptName: '', // 领用人部门名称
+					useDeptId: '', // 使用部门Id
+					useDeptName: '', // 使用部门名称
+					userId: '', // 使用人Id
+					userName: '', // 使用人名称
+					usageTime: '', // 使用时间
+					purpose: '' // 用途
+				},
+				selectedData: [], // 使用部门绑定值
+				classificationList: [], // 使用部门数据
+				executorList: [], // 选择人数据
 			}
 		},
 		onLoad(params) {
 			this.title = params.type == 'view' ? '配件申请详情' : params.type == 'edit' ? '配件申请修改' : '配件申请新增';
 			this.type = params.type;
-			console.log(params, 'params --')
+			this.getData();
 		},
 		created() {
 			uni.$off('updateWorkData')
 			uni.$on('updateWorkData', ({
 				data
 			}) => {
-				console.log(data, 'data');
+				this.form.name = data.name;
+				this.form.repairId = data.id;
 			})
 		},
 		methods: {
 			sectionChange(index) {
 				this.current = index;
 			},
-			save() {
+			getData() {
+				let userInfo = uni.getStorageSync('userInfo');
+				this.form.receivingDeptName = userInfo.groupName;
+				this.form.receivingDeptId = userInfo.groupId;
+				this.form.recipientName = userInfo.name;
+				this.form.recipientId = userInfo.roleId[0];
+				this.getTreeList();
+			},
+			// 获取使用部门数据
+			async getTreeList() {
+				const data = await listOrganizations({});
+				let treeList = toTreeData({
+					data: data || [],
+					idField: 'id',
+					parentIdField: 'parentId'
+				});
+				this.classificationList = treeList;
+			},
+			// 打开部门弹窗
+			classification() {
+				this.$refs.treePicker._show();
+			},
+			// 使用部门选择
+			confirm(id, name) {
+				this.form.useDeptName = name;
+				this.form.useDeptId = id[0];
+				this.getUserList(id[0])
+			},
+			// 打开使用人弹窗
+			openSelector() {
+				this.$refs.selector.open();
+			},
+			// 获取使用人数据
+			async getUserList(id) {
+				let params = {
+					pageNum: 1,
+					size: -1,
+					groupId: id
+				}
+				try {
+					const res = await getUserPage(params);
+					let list = res.list && res.list.map((el) => {
+						return {
+							text: el.name,
+							value: el.id
+						}
+					})
+					this.executorList = list;
+				} catch (error) {
 
+				}
+			},
+			// 使用人选择
+			onClose(item) {
+				this.form.userName = item.text;
+				console.log(item, 'item')
+				console.log(this.form, 'form')
+			},
+			save() {
+				if (!this.form.name) {
+					this.$refs.uToast.show({
+						type: "warning",
+						message: "请选择工单",
+					})
+				};
+				if (!this.form.useDeptName) {
+					this.$refs.uToast.show({
+						type: "warning",
+						message: "请选择使用部门",
+					})
+				};
+				if (!this.form.userName) {
+					this.$refs.uToast.show({
+						type: "warning",
+						message: "请选择使用人",
+					})
+				};
+				let details = this.$refs.accessoryRef.getTabData() || [];
+				if (details.length == 0) {
+					this.$refs.uToast.show({
+						type: "warning",
+						message: "请添加一条配件信息",
+					})
+					this.current = 1;
+					return
+				}
+				let data = {
+					...this.form,
+					details
+				};
+				if (data.usageTime) {
+					data.usageTime = data.usageTime + ' 00:00:00'
+				}
+				let api = this.type == 'edit' ? accessoryUpdate : accessorySave;
+				api(data).then((res) => {
+					this.$refs.uToast.show({
+						type: "success",
+						message: "操作成功",
+					})
+					uni.redirectTo({
+						url: '/pages/login/login'
+					});
+				}).catch((err) => {
+					console.log(err, 'err --')
+				})
 			},
 			selectWorkOrder() {
 				uni.navigateTo({
@@ -134,4 +282,18 @@
 
 		}
 	}
+
+	.selected-value {
+		height: 80rpx;
+		line-height: 80rpx;
+		padding: 0 20rpx;
+		border: 1rpx solid #e5e5e5;
+		border-radius: 8rpx;
+		font-size: 28rpx;
+		color: #333;
+		display: flex;
+		justify-content: space-between;
+		align-items: center;
+		background-color: #fff;
+	}
 </style>

+ 260 - 0
pages/salesServiceManagement/accessory/components/searchSelect.vue

@@ -0,0 +1,260 @@
+<template>
+	<uni-popup ref="popup" type="bottom" :mask-click="true" @maskClick="close">
+		<view class="bottom-selector">
+			<!-- 标题 -->
+			<view class="selector-title">{{ title }}</view>
+
+			<!-- 搜索框 -->
+			<view class="search-box">
+				<uni-icons type="search" size="20" color="#999"></uni-icons>
+				<input v-model="searchText" placeholder="请输入姓名搜索" class="search-input" placeholder-class="placeholder"
+					@input="filterData" />
+			</view>
+
+			<!-- 列表数据 -->
+			<scroll-view scroll-y class="list-container">
+				<view v-for="(item, index) in filteredData" :key="item.value" class="list-item"
+					:class="{ selected: innerValue === item.value }" @click="selectItem(item)">
+					<view class="item-text">{{ item.text }}</view>
+					<uni-icons v-if="innerValue === item.value" type="checkmarkempty" size="20"
+						color="#2979ff"></uni-icons>
+				</view>
+
+				<!-- 空状态提示 -->
+				<view v-if="filteredData.length === 0" class="empty-tip">
+					<uni-icons type="search" size="40" color="#ccc"></uni-icons>
+					<text>未找到匹配的使用人</text>
+				</view>
+			</scroll-view>
+
+			<!-- 底部按钮 -->
+			<view class="footer">
+				<button class="btn cancel" @click="close">取消</button>
+				<!-- <button class="btn confirm" @click="confirm">确定</button> -->
+			</view>
+		</view>
+	</uni-popup>
+</template>
+
+<script>
+	export default {
+		name: 'BottomSelector',
+		props: {
+			// 标题
+			title: {
+				type: String,
+				default: '选择使用人'
+			},
+			// 原始数据
+			dataList: {
+				type: Array,
+				default: () => []
+			},
+			// 选中的值(v-model)
+			value: {
+				type: [String, Number],
+				default: ''
+			}
+		},
+		data() {
+			return {
+				searchText: '',
+				// 过滤后的数据
+				filteredData: [],
+				// 内部选中的值(用于临时存储,确定后更新)
+				innerValue: this.value,
+				// 当前选中的对象
+				// selectedItem: null
+			}
+		},
+		watch: {
+			dataList: {
+				immediate: true,
+				handler(newList) {
+					// 初始化显示所有数据
+					this.filteredData = [...newList];
+				}
+			},
+			value(newVal) {
+				this.innerValue = newVal;
+			}
+		},
+		methods: {
+			// 打开弹窗
+			open() {
+				this.$refs.popup.open();
+				// 打开时重置搜索状态
+				// this.searchText = '';
+				// this.filteredData = [...this.dataList];
+				// 同步当前值到innerValue(因为可能外部修改了value)
+				this.innerValue = this.value;
+				// this.selectedItem = null;
+			},
+
+			// 关闭弹窗
+			close() {
+				this.$refs.popup.close();
+				// this.$emit('close', this.selectedItem);
+			},
+
+			// 过滤数据
+			filterData() {
+				if (this.searchText.trim() === '') {
+					this.filteredData = [...this.dataList];
+					return;
+				}
+
+				const keyword = this.searchText.toLowerCase();
+				this.filteredData = this.dataList.filter(item =>
+					item.text.toLowerCase().includes(keyword)
+				);
+			},
+
+			// 选择项目
+			selectItem(item) {
+				this.innerValue = item.value;
+				// this.selectedItem = item;
+				this.$emit('input', this.innerValue);
+				this.$emit('change', item);
+				this.close();
+			},
+
+			// 确定选择
+			confirm() {
+				console.log(this.innerValue,'123')
+				if (this.innerValue) {
+					// 更新父组件v-model绑定的值
+					this.$emit('input', this.innerValue);
+				}
+				this.close();
+			}
+		}
+	}
+</script>
+
+<style scoped>
+	.bottom-selector {
+		width: 100%;
+		background-color: #ffffff;
+		border-top-left-radius: 24rpx;
+		border-top-right-radius: 24rpx;
+		overflow: hidden;
+		box-shadow: 0 -4rpx 24rpx rgba(0, 0, 0, 0.08);
+		padding-bottom: env(safe-area-inset-bottom);
+	}
+
+	/* 标题样式 */
+	.selector-title {
+		padding: 36rpx 32rpx 24rpx;
+		font-size: 36rpx;
+		font-weight: 600;
+		color: #333;
+		text-align: center;
+	}
+
+	/* 搜索框样式 */
+	.search-box {
+		display: flex;
+		align-items: center;
+		padding: 0 32rpx 24rpx;
+		margin: 0 32rpx;
+		border-bottom: 1rpx solid #f0f0f0;
+	}
+
+	.search-input {
+		flex: 1;
+		height: 80rpx;
+		padding: 0 20rpx;
+		background-color: #f8f8f8;
+		border-radius: 40rpx;
+		margin-left: 16rpx;
+		font-size: 30rpx;
+		color: #333;
+	}
+
+	.placeholder {
+		color: #999;
+		font-size: 30rpx;
+	}
+
+	/* 列表容器 */
+	.list-container {
+		max-height: 60vh;
+		min-height: 45vh;
+		padding: 0 32rpx;
+		box-sizing: border-box;
+	}
+
+	/* 列表项样式 */
+	.list-item {
+		display: flex;
+		justify-content: space-between;
+		align-items: center;
+		padding: 28rpx 0;
+		font-size: 32rpx;
+		color: #333;
+		border-bottom: 1rpx solid #f5f5f5;
+	}
+
+	.list-item:last-child {
+		border-bottom: none;
+	}
+
+	.list-item.selected {
+		color: #2979ff;
+		font-weight: 500;
+	}
+
+	.list-item:active {
+		background-color: #f9f9f9;
+	}
+
+	.item-text {
+		flex: 1;
+	}
+
+	/* 空状态提示 */
+	.empty-tip {
+		display: flex;
+		flex-direction: column;
+		align-items: center;
+		justify-content: center;
+		padding: 100rpx 0;
+		color: #999;
+		font-size: 28rpx;
+	}
+
+	.empty-tip text {
+		margin-top: 20rpx;
+	}
+
+	/* 底部按钮 */
+	.footer {
+		display: flex;
+		padding: 24rpx 32rpx;
+		background-color: #fff;
+		border-top: 1rpx solid #f0f0f0;
+	}
+
+	.btn {
+		flex: 1;
+		height: 88rpx;
+		line-height: 88rpx;
+		border-radius: 44rpx;
+		font-size: 34rpx;
+		margin: 0 16rpx;
+		display: flex;
+		align-items: center;
+		justify-content: center;
+	}
+
+	.cancel {
+		background-color: #f5f5f5;
+		color: #333;
+	}
+
+	.confirm {
+		background-color: #2979ff;
+		color: white;
+	}
+</style>

+ 16 - 1
pages/salesServiceManagement/accessory/components/selectWork.vue

@@ -53,7 +53,7 @@
 									</view>
 									<view>
 										<text>状态:</text>
-										<text class="value">已完成</text>
+										<text class="value">{{ workerData(item) }}</text>
 									</view>
 								</view>
 							</view>
@@ -76,6 +76,16 @@
 	import {
 		getSalesWorkOrder
 	} from '@/api/salesServiceManagement/workOrder/index.js'
+	let workOrderStatus = {
+		0: '待接收',
+		1: '已接收',
+		2: '执行中',
+		3: '待验收',
+		4: '待评价',
+		5: '已完成',
+		6: '验收不通过',
+	}
+
 	export default {
 		data() {
 			return {
@@ -91,6 +101,11 @@
 					return 1;
 				}
 				return 0;
+			},
+			workerData() {
+				return (row) => {
+					return workOrderStatus[row.orderStatus]
+				}
 			}
 		},
 		onLoad() {

+ 1 - 1
pages/salesServiceManagement/accessory/index.vue

@@ -20,7 +20,7 @@
 				</view>
 			</u-list>
 		</view>
-		<view class="add" @click="add('add','')">
+		<view class="add" @click="add('','add')">
 			<u-icon name="plus" color="#fff"></u-icon>
 		</view>
 	</view>