You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

582 lines
12 KiB
Vue

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="page-container">
<view class="header-section">
<view class="back-btn" @click="goBack">
<text class="back-icon"></text>
<text class="back-text">返回</text>
</view>
<text class="header-title">仓库信息</text>
</view>
<view class="search-section">
<view class="search-wrapper">
<view class="search-icon">
<text class="iconfont icon-search"></text>
</view>
<input
v-model="searchKeyword"
class="search-input"
type="text"
placeholder="请输入仓库编码或名称"
placeholder-class="input-placeholder"
@input="handleSearch"
/>
<view v-if="searchKeyword" class="clear-btn" @click="clearSearch">
<text class="clear-icon">×</text>
</view>
</view>
</view>
<scroll-view scroll-y class="content-scroll">
<view class="warehouse-list">
<view
v-for="(item, index) in warehouseList"
:key="index"
class="warehouse-card"
>
<view class="card-header">
<view class="header-left">
<text class="warehouse-name">{{ item.name }}</text>
<text class="warehouse-code">编码: {{ item.code }}</text>
</view>
<view class="card-actions">
<view class="action-btn edit-btn" @click.stop="handleEdit(item)">
<text class="action-icon">✎</text>
</view>
<view class="action-btn delete-btn" @click.stop="handleDelete(item)">
<text class="action-icon">🗑</text>
</view>
</view>
</view>
<view class="card-body">
<view class="card-row">
<text class="card-label">仓库地址</text>
<text class="card-value">{{ item.address }}</text>
</view>
<view class="card-row">
<text class="card-label">仓库负责人</text>
<text class="card-value">{{ item.manager }}</text>
</view>
<view class="card-row">
<text class="card-label">备注</text>
<text class="card-value">{{ item.remark || '-' }}</text>
</view>
</view>
</view>
</view>
</scroll-view>
<view class="add-btn" @click="showAddForm">
<text class="add-icon">+</text>
</view>
<uni-popup ref="addPopup" type="center" background-color="#fff">
<view class="popup-content">
<view class="popup-header">
<text class="popup-title">新增仓库</text>
<view class="popup-close" @click="hideAddForm">
<text class="close-icon">×</text>
</view>
</view>
<view class="form-content">
<view class="form-item">
<text class="form-label">仓库名称 <text class="required">*</text></text>
<input
v-model="formData.name"
class="form-input"
type="text"
placeholder="请输入仓库名称"
/>
</view>
<view class="form-item">
<text class="form-label">仓库编码 <text class="required">*</text></text>
<input
v-model="formData.code"
class="form-input"
type="text"
placeholder="请输入仓库编码"
/>
</view>
<view class="form-item">
<text class="form-label">仓库地址</text>
<input
v-model="formData.address"
class="form-input"
type="text"
placeholder="请输入仓库地址"
/>
</view>
<view class="form-item">
<text class="form-label">仓库负责人</text>
<input
v-model="formData.manager"
class="form-input"
type="text"
placeholder="请输入负责人"
/>
</view>
<view class="form-item">
<text class="form-label">备注</text>
<textarea
v-model="formData.remark"
class="form-textarea"
placeholder="请输入备注"
:maxlength="200"
/>
</view>
</view>
<view class="form-footer">
<view class="footer-btn cancel-btn" @click="hideAddForm">
<text class="btn-text">取消</text>
</view>
<view class="footer-btn confirm-btn" @click="handleSave">
<text class="btn-text"></text>
</view>
</view>
</view>
</uni-popup>
</view>
</template>
<script setup>
import { ref, reactive } from 'vue';
const addPopup = ref(null);
const searchKeyword = ref('');
const formData = reactive({
name: '',
code: '',
address: '',
manager: '',
remark: ''
});
const warehouseList = reactive([
{ code: 'WH001', name: '一号仓库', address: '工业园区A栋1楼', manager: '张三', remark: '主要原材料仓库' },
{ code: 'WH002', name: '二号仓库', address: '工业园区A栋2楼', manager: '李四', remark: '半成品仓库' },
{ code: 'WH003', name: '三号仓库', address: '工业园区B栋1楼', manager: '王五', remark: '成品仓库' },
{ code: 'WH004', name: '四号仓库', address: '工业园区B栋2楼', manager: '赵六', remark: '备件仓库' },
{ code: 'WH005', name: '五号仓库', address: '工业园区C栋1楼', manager: '孙七', remark: '周转仓库' }
]);
function goBack() {
uni.navigateBack();
}
function handleSearch() {
console.log('搜索:', searchKeyword.value);
}
function clearSearch() {
searchKeyword.value = '';
}
function handleEdit(item) {
uni.showToast({
title: `编辑${item.name}`,
icon: 'none'
});
}
function handleDelete(item) {
uni.showModal({
title: '确认删除',
content: `确定要删除"${item.name}"吗?`,
success: () => {
uni.showToast({
title: '删除成功',
icon: 'success'
});
}
});
}
function showAddForm() {
addPopup.value.open();
}
function hideAddForm() {
addPopup.value.close();
resetForm();
}
function resetForm() {
formData.name = '';
formData.code = '';
formData.address = '';
formData.manager = '';
formData.remark = '';
}
function handleSave() {
if (!formData.name || !formData.code) {
uni.showToast({
title: '请填写必填项',
icon: 'none'
});
return;
}
uni.showToast({
title: '保存成功',
icon: 'success'
});
hideAddForm();
resetForm();
}
</script>
<style lang="scss" scoped>
.page-container {
min-height: 100vh;
background-color: #f0f2f5;
}
.header-section {
background: linear-gradient(135deg, #1a3a5c 0%, #2d5a87 100%);
padding: 60rpx 40rpx 40rpx 30rpx;
display: flex;
justify-content: center;
align-items: center;
position: relative;
}
.back-btn {
display: flex;
align-items: center;
position: absolute;
left: 30rpx;
top: 50%;
transform: translateY(-50%);
&:active {
opacity: 0.7;
}
.back-icon {
font-size: 48rpx;
color: #ffffff;
margin-right: 8rpx;
}
.back-text {
font-size: 28rpx;
color: #ffffff;
}
}
.header-title {
font-size: 34rpx;
font-weight: bold;
color: #ffffff;
}
.search-section {
background: #ffffff;
padding: 24rpx 30rpx;
margin-bottom: 20rpx;
}
.search-wrapper {
display: flex;
align-items: center;
background: #f5f7fa;
border-radius: 48rpx;
padding: 0 24rpx;
}
.search-icon {
margin-right: 20rpx;
.iconfont {
font-size: 36rpx;
color: #666666;
}
}
.search-input {
flex: 1;
height: 72rpx;
font-size: 28rpx;
color: #333333;
background: transparent;
}
.input-placeholder {
color: #999999;
}
.clear-btn {
width: 48rpx;
height: 48rpx;
display: flex;
align-items: center;
justify-content: center;
&:active {
opacity: 0.7;
}
.clear-icon {
font-size: 36rpx;
color: #999999;
}
}
.content-scroll {
flex: 1;
height: calc(100vh - 260rpx);
}
.warehouse-list {
display: flex;
flex-direction: column;
align-items: center;
padding: 0 24rpx;
}
.warehouse-card {
width: 100%;
background: #ffffff;
border-radius: 20rpx;
padding: 28rpx;
margin-bottom: 20rpx;
box-sizing: border-box;
box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.05);
}
.card-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 20rpx;
padding-bottom: 20rpx;
border-bottom: 2rpx solid #f0f2f5;
}
.header-left {
display: flex;
flex-direction: column;
}
.warehouse-name {
font-size: 32rpx;
font-weight: 600;
color: #1a3a5c;
margin-bottom: 8rpx;
}
.warehouse-code {
font-size: 24rpx;
color: #999999;
}
.card-actions {
display: flex;
gap: 16rpx;
}
.action-btn {
width: 64rpx;
height: 64rpx;
border-radius: 12rpx;
display: flex;
align-items: center;
justify-content: center;
&:active {
opacity: 0.7;
transform: scale(0.95);
}
.action-icon {
font-size: 32rpx;
color: #ffffff;
}
}
.edit-btn {
background: #1a3a5c;
}
.delete-btn {
background: #ff4d4f;
}
.card-body {
display: flex;
flex-direction: column;
}
.card-row {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 16rpx;
&:last-child {
margin-bottom: 0;
}
}
.card-label {
font-size: 26rpx;
color: #999999;
}
.card-value {
font-size: 28rpx;
color: #333333;
flex: 1;
text-align: right;
}
.add-btn {
position: fixed;
bottom: 120rpx;
right: 30rpx;
width: 100rpx;
height: 100rpx;
background: linear-gradient(135deg, #1a3a5c 0%, #2d5a87 100%);
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
box-shadow: 0 8rpx 24rpx rgba(26, 58, 92, 0.3);
z-index: 999;
&:active {
transform: scale(0.95);
}
.add-icon {
font-size: 60rpx;
color: #ffffff;
font-weight: bold;
}
}
.popup-content {
width: 600rpx;
background: #ffffff;
border-radius: 20rpx;
overflow: hidden;
}
.popup-header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 32rpx;
background: linear-gradient(135deg, #1a3a5c 0%, #2d5a87 100%);
}
.popup-title {
font-size: 32rpx;
font-weight: 600;
color: #ffffff;
}
.popup-close {
width: 48rpx;
height: 48rpx;
display: flex;
align-items: center;
justify-content: center;
&:active {
opacity: 0.7;
}
.close-icon {
font-size: 36rpx;
color: #ffffff;
}
}
.form-content {
padding: 32rpx;
}
.form-item {
margin-bottom: 24rpx;
}
.form-label {
display: block;
font-size: 28rpx;
color: #333333;
margin-bottom: 12rpx;
}
.required {
color: #ff4d4f;
margin-left: 4rpx;
}
.form-input {
width: 100%;
height: 80rpx;
padding: 0 24rpx;
font-size: 28rpx;
background: #f5f7fa;
border-radius: 12rpx;
border: 2rpx solid #e8eaed;
box-sizing: border-box;
}
.form-textarea {
width: 100%;
min-height: 120rpx;
padding: 16rpx 24rpx;
font-size: 28rpx;
background: #f5f7fa;
border-radius: 12rpx;
border: 2rpx solid #e8eaed;
box-sizing: border-box;
resize: none;
}
.form-footer {
display: flex;
gap: 16rpx;
margin-top: 32rpx;
}
.footer-btn {
flex: 1;
height: 88rpx;
border-radius: 12rpx;
display: flex;
align-items: center;
justify-content: center;
&:active {
opacity: 0.8;
}
.btn-text {
font-size: 28rpx;
font-weight: 500;
}
}
.cancel-btn {
background: #f5f7fa;
.btn-text {
color: #666666;
}
}
.confirm-btn {
background: linear-gradient(135deg, #1a3a5c 0%, #2d5a87 100%);
.btn-text {
color: #ffffff;
}
}
</style>