/* 文件路径: webapp/pages/bancai/bancai.js */
// pages/bancai/bancai.js
const app = getApp();
Page({
data: {
bancais: [],
filteredBancais: [],
searchText: '',
sortState: {
column: null,
direction: 'asc'
},
currentBancai: null,
currentKucun: null,
showDetailModal: false,
showEditModal: false,
stockInput: 0,
noteInput: '',
viewMode: 'orders',
relatedOrders: [],
relatedProducts: []
},
onLoad: function(options) {
if (!app.globalData.dataManager) {
// 如果数据管理器未初始化,等待初始化完成
const checkDataManager = () => {
if (app.globalData.dataManager) {
this.loadBancaiData();
} else {
setTimeout(checkDataManager, 100);
}
};
checkDataManager();
return;
}
this.loadBancaiData();
},
onShow: function() {
if (app.globalData.dataManager) {
this.loadBancaiData();
}
},
/**
* 加载板材数据并合并库存信息
* 将全局数据中的板材列表与库存数据进行关联,为每个板材对象添加库存数量和库存ID字段
* 结果会同时更新到页面的bancais和filteredBancais数据中
*/
// 修改 loadBancaiData 方法
loadBancaiData: function() {
const dataManager = app.globalData.dataManager;
// 确保数据存在
if (!dataManager.data.bancais || !dataManager.data.kucuns) {
console.error('数据源不存在');
return;
}
const bancaisWithStock = dataManager.data.bancais.map(bancai => {
const kucun = dataManager.data.kucuns.find(k =>
k.bancai && k.bancai.id === bancai.id
);
return {
...bancai,
// 确保所有必要字段存在
id: bancai.id || Math.random().toString(36).substring(2, 9),
caizhi: bancai.caizhi || { name: '' },
mupi1: bancai.mupi1 || null,
mupi2: bancai.mupi2 || null,
stock: kucun ? kucun.shuliang : 0,
kucunId: kucun ? kucun.id : null
};
});
console.log('合并后的板材数据:', bancaisWithStock);
// 强制刷新视图
this.setData({
bancais: bancaisWithStock,
filteredBancais: bancaisWithStock
}, () => {
console.log('视图已更新,记录数:', this.data.filteredBancais.length);
// 添加临时调试视图
this.setData({
debugData: bancaisWithStock.slice(0, 3) // 显示前3条数据用于调试
});
});
},
/**
* 处理搜索输入事件
* @param {Object} e - 事件对象,包含输入值(e.detail.value)
* @description 将搜索文本转为小写并更新到data,然后触发板材筛选
*/
onSearch: function(e) {
this.setData({ searchText: e.detail.value.toLowerCase() });
this.filterBancais();
},
/**
* 确认搜索 - 触发板材筛选操作
*/
confirmSearch: function() {
this.filterBancais();
},
/**
* 过滤并排序板材数据
* 根据搜索文本筛选板材列表,并按指定列和方向排序
* @function filterBancais
* @description
* - 当有搜索文本时,会匹配板材的材质、木皮1、木皮2、厚度和库存信息
* - 无搜索文本时返回所有板材
* - 最后调用sortBancais方法进行排序
* @returns {void} 通过setData更新filteredBancais数据
*/
filterBancais: function() {
const { bancais, searchText, sortState } = this.data;
const filteredBancais = searchText ? bancais.filter(b => {
const searchStr = `${b.caizhi?.name || ''} ${b.mupi1?.name || ''} ${b.mupi2?.name || ''} ${b.houdu} ${b.stock}`.toLowerCase();
return searchStr.includes(searchText.toLowerCase());
}) : bancais;
const sortedBancais = this.sortBancais(filteredBancais, sortState.column, sortState.direction);
this.setData({ filteredBancais: sortedBancais });
},
/**
* 对板材数组进行排序
* @param {Array} bancais - 要排序的板材数组
* @param {string} column - 排序字段(id/caizhi/mupi1/mupi2/houdu/stock)
* @param {string} direction - 排序方向(asc/desc)
* @returns {Array} 排序后的新数组
*/
sortBancais: function(bancais, column, direction) {
return [...bancais].sort((a, b) => {
let valA, valB;
switch(column) {
case 'id':
valA = a.id;
valB = b.id;
break;
case 'caizhi':
valA = (a.caizhi?.name || '').toLowerCase();
valB = (b.caizhi?.name || '').toLowerCase();
break;
case 'mupi1':
valA = (a.mupi1?.name || '').toLowerCase();
valB = (b.mupi1?.name || '').toLowerCase();
break;
case 'mupi2':
valA = (a.mupi2?.name || '').toLowerCase();
valB = (b.mupi2?.name || '').toLowerCase();
break;
case 'houdu':
valA = parseFloat(a.houdu) || 0;
valB = parseFloat(b.houdu) || 0;
break;
case 'stock':
valA = a.stock || 0;
valB = b.stock || 0;
break;
default:
return 0;
}
// 统一处理比较逻辑
let comparison = 0;
if (typeof valA === 'string') {
comparison = valA.localeCompare(valB);
} else {
comparison = valA - valB;
}
return direction === 'asc' ? comparison : -comparison;
});
},
/**
* 处理排序点击事件
* @param {Object} e - 事件对象
* @param {string} e.currentTarget.dataset.column - 当前点击列的标识
* @description 根据点击的列切换排序状态(升序/降序),并触发数据过滤
*/
onSortTap: function(e) {
const column = e.currentTarget.dataset.column;
const { sortState } = this.data;
if (sortState.column === column) {
sortState.direction = sortState.direction === 'asc' ? 'desc' : 'asc';
} else {
sortState.column = column;
sortState.direction = 'asc';
}
this.setData({ sortState });
this.filterBancais();
},
onEditTap: function(e) {
const bancaiId = e.currentTarget.dataset.id;
const bancai = this.data.bancais.find(b => b.id === bancaiId);
const dataManager = app.globalData.dataManager;
const kucun = dataManager.data.kucuns.find(k => k.bancai && k.bancai.id === bancaiId);
if (bancai && kucun) {
this.setData({
currentBancai: bancai,
currentKucun: kucun,
stockInput: kucun.shuliang,
noteInput: '',
showEditModal: true
});
} else {
wx.showToast({ title: '找不到板材或库存记录', icon: 'none' });
}
},
saveStock: function() {
const { currentBancai, currentKucun, stockInput, noteInput } = this.data;
const dataManager = app.globalData.dataManager;
if (!currentBancai || !currentKucun) {
wx.showToast({ title: '无效的板材或库存记录', icon: 'none' });
return;
}
const newStock = parseInt(stockInput) || 0;
const note = noteInput.trim();
const oldStock = currentKucun.shuliang;
const changeAmount = newStock - oldStock;
if (changeAmount === 0) {
wx.showToast({ title: '库存数量未变化', icon: 'none' });
return;
}
dataManager.updateEntity('kucun', { id: currentKucun.id, shuliang: newStock })
.then(() => {
const jinhuoData = {
shuliang: changeAmount,
date: new Date().toISOString(),
user: { id: wx.getStorageSync("userId") },
text: note || `手动调整库存: ${oldStock} → ${newStock}`,
theTypeOfOperation: 3,
kucun: { id: currentKucun.id }
};
return dataManager.addEntity('jinhuo', jinhuoData);
})
.then(() => {
this.setData({ showEditModal: false });
this.loadBancaiData();
wx.showToast({ title: '库存更新成功', icon: 'success' });
})
.catch(error => {
console.error('库存更新失败:', error);
wx.showToast({ title: error.message || '库存更新失败', icon: 'none' });
});
},
onDetailTap: function(e) {
const bancaiId = e.currentTarget.dataset.id;
const bancai = this.data.bancais.find(b => b.id === bancaiId);
const dataManager = app.globalData.dataManager;
if (bancai) {
const kucun = dataManager.data.kucuns.find(k => k.bancai && k.bancai.id === bancai.id);
const relatedOrders = this.getRelatedOrders(bancai.id);
const relatedProducts = this.getRelatedProducts(bancai.id);
this.setData({
currentBancai: bancai,
currentKucun: kucun,
relatedOrders,
relatedProducts,
viewMode: 'orders',
showDetailModal: true
});
}
},
getRelatedOrders: function(bancaiId) {
const dataManager = app.globalData.dataManager;
const orderMap = new Map();
dataManager.data.dingdan_bancais.forEach(db => {
if (db.bancai && db.bancai.id === bancaiId && db.dingdan) {
const order = db.dingdan;
const key = order.id;
if (!orderMap.has(key)) {
orderMap.set(key, {
id: order.id,
number: order.number,
xiadan: order.xiadan,
jiaohuo: order.jiaohuo,
products: new Set(),
quantity: 0,
components: new Set()
});
}
const entry = orderMap.get(key);
entry.quantity += db.shuliang;
if (db.chanpin && db.chanpin.bianhao) entry.products.add(db.chanpin.bianhao);
if (db.zujian && db.zujian.name) entry.components.add(db.zujian.name);
}
});
return Array.from(orderMap.values()).map(entry => ({
...entry,
products: Array.from(entry.products).join(', '),
components: Array.from(entry.components).join(', '),
xiadanFormatted: entry.xiadan ? new Date(entry.xiadan).toLocaleDateString() : '无日期',
jiaohuoFormatted: entry.jiaohuo ? new Date(entry.jiaohuo).toLocaleDateString() : '无日期'
}));
},
getRelatedProducts: function(bancaiId) {
const dataManager = app.globalData.dataManager;
const products = [];
dataManager.data.chanpin_zujians.forEach(cz => {
if (cz.bancai && cz.bancai.id === bancaiId && cz.chanpin && cz.zujian) {
let productEntry = products.find(p => p.product.id === cz.chanpin.id);
if (!productEntry) {
productEntry = { product: cz.chanpin, components: [] };
products.push(productEntry);
}
if (!productEntry.components.some(c => c.id === cz.zujian.id)) {
productEntry.components.push(cz.zujian);
}
}
});
dataManager.data.dingdan_bancais.forEach(db => {
if (db.bancai && db.bancai.id === bancaiId && db.chanpin && !products.some(p => p.product.id === db.chanpin.id)) {
products.push({ product: db.chanpin, components: [] });
}
});
products.forEach(item => {
if (item.components && item.components.length > 0) {
const componentNames = [];
for (let i = 0; i < item.components.length; i++) {
if (item.components[i] && item.components[i].name) {
componentNames.push(item.components[i].name);
}
}
item.componentsText = componentNames.join(', ');
} else {
item.componentsText = '';
}
});
return products;
},
onStockInput: function(e) {
this.setData({ stockInput: e.detail.value });
},
onNoteInput: function(e) {
this.setData({ noteInput: e.detail.value });
},
closeEditModal: function() {
this.setData({ showEditModal: false });
},
closeDetailModal: function() {
this.setData({ showDetailModal: false });
},
toggleViewMode: function() {
this.setData({ viewMode: this.data.viewMode === 'orders' ? 'products' : 'orders' });
},
onDeleteTap: function(e) {
const bancaiId = e.currentTarget.dataset.id;
const bancai = this.data.bancais.find(b => b.id === bancaiId);
if (!bancai) {
wx.showToast({ title: '找不到板材记录', icon: 'none' });
return;
}
wx.showModal({
title: '确认删除',
content: `确定要删除这个板材吗?\n材质: ${bancai.caizhi?.name || ''}\n厚度: ${bancai.houdu}mm`,
success: (res) => {
if (res.confirm) {
const dataManager = app.globalData.dataManager;
const relatedOrders = this.getRelatedOrders(bancaiId);
const relatedProducts = this.getRelatedProducts(bancaiId);
if (relatedOrders.length > 0 || relatedProducts.length > 0) {
wx.showModal({
title: '无法删除',
content: `该板材有${relatedOrders.length}个关联订单和${relatedProducts.length}个关联产品,无法删除。`,
showCancel: false
});
return;
}
const kucun = dataManager.data.kucuns.find(k => k.bancai && k.bancai.id === bancaiId);
if (kucun) {
dataManager.deleteEntity('kucun', kucun.id)
.then(() => dataManager.deleteEntity('bancai', bancaiId))
.then(() => {
this.loadBancaiData();
wx.showToast({ title: '删除成功', icon: 'success' });
})
.catch(error => {
console.error('删除失败:', error);
wx.showToast({ title: error.message || '删除失败', icon: 'none' });
});
} else {
dataManager.deleteEntity('bancai', bancaiId)
.then(() => {
this.loadBancaiData();
wx.showToast({ title: '删除成功', icon: 'success' });
})
.catch(error => {
console.error('删除失败:', error);
wx.showToast({ title: error.message || '删除失败', icon: 'none' });
});
}
}
}
});
},
onPullDownRefresh: function() {
if (app.globalData.dataManager) {
app.globalData.dataManager.syncData()
.then(() => {
this.loadBancaiData();
wx.stopPullDownRefresh();
})
.catch(error => {
console.error('同步数据失败:', error);
this.loadBancaiData();
wx.stopPullDownRefresh();
});
} else {
wx.stopPullDownRefresh();
}
}
});
================================================================================
/* 文件路径: webapp/pages/bancai/bancai.json */
{
"navigationBarTitleText": "板材管理",
"usingComponents": {},
"enablePullDownRefresh": true,
"backgroundTextStyle": "dark"
}
================================================================================
/* 文件路径: webapp/pages/bancai/bancai.wxml */
<!-- pages/bancai/bancai.wxml -->
<view class="container">
<view class="header">
<view class="search-box">
<input class="search-input" placeholder="搜索板材..." bindinput="onSearch" value="{{searchText}}" confirm-type="search" bindconfirm="confirmSearch" />
<button class="search-btn" bindtap="confirmSearch">搜索</button>
</view>
</view>
<!-- 板材表格 -->
<view class="table-container">
<view class="table-header">
<view class="th" data-column="caizhi" bindtap="onSortTap">
材质
<text wx:if="{{sortState.column === 'caizhi'}}" class="sort-indicator">{{sortState.direction === 'asc' ? '↑' : '↓'}}</text>
</view>
<view class="th" data-column="mupi1" bindtap="onSortTap">
木皮1
<text wx:if="{{sortState.column === 'mupi1'}}" class="sort-indicator">{{sortState.direction === 'asc' ? '↑' : '↓'}}</text>
</view>
<view class="th" data-column="mupi2" bindtap="onSortTap">
木皮2
<text wx:if="{{sortState.column === 'mupi2'}}" class="sort-indicator">{{sortState.direction === 'asc' ? '↑' : '↓'}}</text>
</view>
<view class="th" data-column="houdu" bindtap="onSortTap">
厚度
<text wx:if="{{sortState.column === 'houdu'}}" class="sort-indicator">{{sortState.direction === 'asc' ? '↑' : '↓'}}</text>
</view>
<view class="th" data-column="stock" bindtap="onSortTap">
库存
<text wx:if="{{sortState.column === 'stock'}}" class="sort-indicator">{{sortState.direction === 'asc' ? '↑' : '↓'}}</text>
</view>
<view class="th">操作</view>
</view>
<scroll-view scroll-y="true" class="table-body">
<block wx:if="{{filteredBancais.length > 0}}">
<view class="tr" wx:for="{{filteredBancais}}" wx:key="id}}">
<view class="td">{{item.caizhi.name || ''}}</view>
<view class="td">{{item.mupi1 ? (item.mupi1.name + (item.mupi1.you ? '(油)' : '')) : ''}}</view>
<view class="td">{{item.mupi2 ? (item.mupi2.name + (item.mupi2.you ? '(油)' : '')) : ''}}</view>
<view class="td">{{item.houdu}}mm</view>
<view class="td">{{item.stock}}</view>
<view class="td actions">
<button class="btn btn-warning" bindtap="onEditTap" data-id="{{item.id}}">管理</button>
</view>
</view>
</block>
<view wx:else class="empty-tip">暂无板材数据</view>
</scroll-view>
</view>
<!-- 编辑库存模态框 -->
<view class="modal" wx:if="{{showEditModal}}">
<view class="modal-mask" bindtap="closeEditModal"></view>
<view class="modal-content">
<view class="modal-header">
<text class="modal-title">编辑板材库存</text>
<text class="modal-close" bindtap="closeEditModal">×</text>
</view>
<view class="modal-body">
<view class="form-item">
<text class="label">材质:</text>
<text class="value">{{currentBancai.caizhi.name || ''}}</text>
</view>
<view class="form-item">
<text class="label">木皮1:</text>
<text class="value">{{currentBancai.mupi1 ? (currentBancai.mupi1.name + (currentBancai.mupi1.you ? '(油)' : '')) : ''}}</text>
</view>
<view class="form-item">
<text class="label">木皮2:</text>
<text class="value">{{currentBancai.mupi2 ? (currentBancai.mupi2.name + (currentBancai.mupi2.you ? '(油)' : '')) : ''}}</text>
</view>
<view class="form-item">
<text class="label">厚度:</text>
<text class="value">{{currentBancai.houdu}}mm</text>
</view>
<view class="form-item">
<text class="label">库存数量:</text>
<input class="input" type="number" value="{{stockInput}}" bindinput="onStockInput" />
</view>
<view class="form-item">
<text class="label">备注:</text>
<textarea class="textarea" value="{{noteInput}}" bindinput="onNoteInput" placeholder="输入库存调整原因"></textarea>
</view>
</view>
<view class="modal-footer">
<button class="btn btn-secondary" bindtap="closeEditModal">取消</button>
<button class="btn btn-primary" bindtap="saveStock">保存</button>
</view>
</view>
</view>
<!-- 详情模态框 -->
<view class="modal" wx:if="{{showDetailModal}}">
<view class="modal-mask" bindtap="closeDetailModal"></view>
<view class="modal-content detail-modal">
<view class="modal-header">
<text class="modal-title">板材详情</text>
<text class="modal-close" bindtap="closeDetailModal">×</text>
</view>
<view class="modal-body">
<view class="detail-section">
<view class="detail-item">
<text class="label">ID:</text>
<text class="value">{{currentBancai.id}}</text>
</view>
<view class="detail-item">
<text class="label">材质:</text>
<text class="value">{{currentBancai.caizhi.name || '无'}}</text>
</view>
<view class="detail-item">
<text class="label">木皮1:</text>
<text class="value">{{currentBancai.mupi1 ? (currentBancai.mupi1.name + (currentBancai.mupi1.you ? '(油)' : '')) : '无'}}</text>
</view>
<view class="detail-item">
<text class="label">木皮2:</text>
<text class="value">{{currentBancai.mupi2 ? (currentBancai.mupi2.name + (currentBancai.mupi2.you ? '(油)' : '')) : '无'}}</text>
</view>
<view class="detail-item">
<text class="label">厚度:</text>
<text class="value">{{currentBancai.houdu}}mm</text>
</view>
<view class="detail-item">
<text class="label">库存:</text>
<text class="value">{{currentKucun ? currentKucun.shuliang : 0}}</text>
</view>
</view>
<view class="view-toggle">
<view class="view-title">
{{viewMode === 'orders' ? '相关订单' : '相关产品'}}
({{viewMode === 'orders' ? relatedOrders.length : relatedProducts.length}})
</view>
<button class="btn btn-toggle" bindtap="toggleViewMode">
查看{{viewMode === 'orders' ? '相关产品' : '相关订单'}}
</button>
</view>
<!-- 订单视图 -->
<view class="view-container" wx:if="{{viewMode === 'orders'}}">
<view class="sub-table" wx:if="{{relatedOrders.length > 0}}">
<view class="sub-table-header">
<view class="sub-th">订单编号</view>
<view class="sub-th">下单日期</view>
<view class="sub-th">产品</view>
<view class="sub-th">数量</view>
<view class="sub-th">交货日期</view>
</view>
<scroll-view scroll-y="true" class="sub-table-body">
<view class="sub-tr" wx:for="{{relatedOrders}}" wx:key="id">
<view class="sub-td">{{item.number || '无编号'}}</view>
<view class="sub-td">{{item.xiadanFormatted}}</view>
<view class="sub-td">{{item.products || '无产品'}}</view>
<view class="sub-td">{{item.quantity}}</view>
<view class="sub-td">{{item.jiaohuoFormatted}}</view>
</view>
</scroll-view>
</view>
<view wx:else class="empty-tip">暂无关联订单</view>
</view>
<!-- 产品视图 -->
<view class="view-container" wx:if="{{viewMode === 'products'}}">
<view class="sub-table" wx:if="{{relatedProducts.length > 0}}">
<view class="sub-table-header">
<view class="sub-th">产品编号</view>
<view class="sub-th">产品名称</view>
<view class="sub-th">组件</view>
</view>
<scroll-view scroll-y="true" class="sub-table-body">
<view class="sub-tr" wx:for="{{relatedProducts}}" wx:key="index">
<view class="sub-td">{{item.product.bianhao || '无编号'}}</view>
<view class="sub-td">{{item.product.name || '无名称'}}</view>
<view class="sub-td">
{{item.componentsText || '无组件信息'}}
</view>
</view>
</scroll-view>
</view>
<view wx:else class="empty-tip">暂无关联产品</view>
</view>
</view>
<view class="modal-footer">
<button class="btn btn-primary" bindtap="closeDetailModal">关闭</button>
</view>
</view>
</view>
</view>
================================================================================
/* 文件路径: webapp/pages/bancai/bancai.wxss */
/* pages/bancai/bancai.wxss */
.container {
padding: 20rpx;
box-sizing: border-box;
display: flex;
flex-direction: column;
height: 100vh;
}
/* 头部搜索区域 */
.header {
flex-shrink: 0;
margin-bottom: 20rpx;
}
.search-box {
display: flex;
gap: 10rpx;
}
.search-input {
flex: 1;
height: 80rpx;
border: 1rpx solid #ddd;
border-radius: 8rpx;
padding: 0 20rpx;
font-size: 18rpx;
}
.search-btn {
width: 150rpx;
height: 80rpx;
line-height: 80rpx;
background-color: #07c160;
color: white;
padding: 0;
font-size: 18rpx;
}
/* 表格容器 - 关键修复 */
.table-container {
flex: 1; /* 占据剩余空间 */
display: flex;
flex-direction: column;
border: 1rpx solid #ddd;
border-radius: 8rpx;
overflow: hidden;
background-color: #fff;
min-height: 300rpx; /* 最小高度保证 */
}
.table-header {
display: flex;
background-color: #f0f8ff;
border-bottom: 2rpx solid #ddd;
flex-shrink: 0;
}
/* 列宽调整 - 更精确的百分比分配 */
.th {
padding: 20rpx 5rpx;
text-align: center;
font-size: 17rpx;
min-width: 0; /* 允许内容收缩 */
}
.th:nth-child(1) { width: 15%; } /* 材质 */
.th:nth-child(2) { width: 15%; } /* 木皮1 */
.th:nth-child(3) { width: 15%; } /* 木皮2 */
.th:nth-child(4) { width: 10%; } /* 厚度 */
.th:nth-child(5) { width: 10%; } /* 库存 */
.th:nth-child(6) { width: 25%; } /* 操作 - 加宽区域 */
.sort-indicator {
margin-left: 5rpx;
font-size: 14rpx;
}
/* 表格主体 - 关键修复 */
.table-body {
flex: 1;
height: 0; /* 重要:触发flex滚动 */
overflow-y: auto;
}
.tr {
display: flex;
border-bottom: 1rpx solid #eee;
}
.td {
padding: 20rpx 5rpx;
text-align: center;
font-size: 17rpx;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
min-width: 0; /* 允许内容收缩 */
}
/* 列宽与表头一致 */
.td:nth-child(1) { width: 15%; }
.td:nth-child(2) { width: 15%; }
.td:nth-child(3) { width: 15%; }
.td:nth-child(4) { width: 10%; }
.td:nth-child(5) { width: 10%; }
.td:nth-child(6) {
width: 25%;
display: flex;
justify-content: center;
align-items: center;
gap: 5rpx; /* 按钮间距 */
flex-wrap: wrap; /* 允许按钮换行 */
}
/* 按钮样式优化 */
.btn {
height: 30rpx;
line-height: 30rpx;
font-size: 14rpx;
padding: 0 15rpx;
border-radius: 8rpx;
min-width: 60rpx; /* 最小宽度 */
flex-shrink: 0; /* 防止按钮被压缩 */
}
.btn-info { background-color: #1989fa; color: white; }
.btn-warning { background-color: #ff9900; color: white; }
.btn-danger { background-color: #f56c6c; color: white; }
.empty-tip {
padding: 40rpx;
text-align: center;
color: #909399;
font-size: 18rpx;
}
/* 模态框样式调整 */
.modal-content {
width: 90%;
max-width: 700rpx;
}
.detail-modal {
max-height: 90vh;
}
.modal-body {
max-height: 60vh;
}@startuml
' 基础类与接口
abstract class EntityBasis {
+ Integer id
+ Date lastUpdated
+ Boolean deleted
+ Date deletedAt
+ getId()
+ setId(Integer)
}
interface EntityBasisId {
+ getId()
+ setId(Integer)
}
abstract class SimpleEntity {
+ Integer id
+ String name
}
' 实体类定义
class Mupi {
+ Boolean you
+ String name
+ List<Bancai> bancaisForMupi1
+ List<Bancai> bancaisForMupi2
}
class User {
+ String name
+ String andy
+ String pass
+ int role
+ int incumbency
}
class Chanpin_zujian {
+ Double one_howmany
+ Double zujianshu
}
class WechatUser {
+ String openid
+ String sessionKey
+ String nickname
+ String avatarUrl
+ String phoneNumber
+ Long userId
+ Date createTime
+ Integer status
}
class Kucun {
+ Integer shuliang
}
class Dingdan_chanpin {
+ Integer shuliang
}
class Information {
+ Integer Status
+ String text
+ Object data
}
class Zujian {
+ String name
+ List<Chanpin_zujian> chanping_zujian
}
class Dingdan_bancai {
+ Integer shuliang
+ Integer currentUserId
}
class Dingdan {
+ String number
+ Date xiadan
+ Date jiaohuo
+ List<Dingdan_chanpin> dingdan_chanpin
}
class Jinhuo {
+ Integer shuliang
+ Date date
+ String text
+ Integer theTypeOfOperation
}
class Caizhi {
+ String name
+ List<Bancai> bancai
}
class Bancai {
+ Double houdu
}
' 继承关系
EntityBasis --|> EntityBasisId
SimpleEntity --|> EntityBasisId
Mupi --|> EntityBasis
User --|> EntityBasis
Chanpin_zujian --|> EntityBasis
WechatUser --|> EntityBasis
Kucun --|> EntityBasis
Dingdan_chanpin --|> EntityBasis
Zujian --|> EntityBasis
Dingdan_bancai --|> EntityBasis
Dingdan --|> EntityBasis
Jinhuo --|> EntityBasis
Caizhi --|> EntityBasis
Bancai --|> EntityBasis
' 关联关系
' 一对一
Bancai -- Kucun : 1:1 (kucun)
' 一对多/多对一
Caizhi "1" -- "*" Bancai : 包含 (bancai)
Mupi "1" -- "*" Bancai : 作为mupi1 (bancaisForMupi1)
Mupi "1" -- "*" Bancai : 作为mupi2 (bancaisForMupi2)
Chanpin "1" -- "*" Chanpin_zujian : 包含 (chanpin_zujian)
Zujian "1" -- "*" Chanpin_zujian : 关联 (chanping_zujian)
Bancai "1" -- "*" Chanpin_zujian : 被使用 (bancai)
Dingdan "1" -- "*" Dingdan_chanpin : 包含 (dingdan_chanpin)
Chanpin "1" -- "*" Dingdan_chanpin : 被订购 (chanpin)
Dingdan "1" -- "*" Dingdan_bancai : 包含 (dingdan)
Chanpin "1" -- "*" Dingdan_bancai : 关联 (chanpin)
Zujian "1" -- "*" Dingdan_bancai : 关联 (zujian)
Bancai "1" -- "*" Dingdan_bancai : 被订购 (bancai)
User "1" -- "*" Jinhuo : 操作 (user)
Dingdan_bancai "1" -- "*" Jinhuo : 关联 (dingdan_bancai)
' 单向关联
WechatUser -- User : 绑定 (userId)
@enduml
管理按钮跳转到kucunguanli页面中,管理页面 最上面石板材基本信息和库存,在库存后面又一个编辑按钮,点开后弹出一个弹窗输入新的库存和理由,保存时创建一个jinhuo记录下来,在dingdan_bancai中查找dingdan为空的数据做出行营的增加或减少。下面是未分配的库存(通过dingdan_bancai中的dingdan为空数据得到),在下面为关联的dingdan_bancai表格,在数量一栏中是一个数字输入框,可以调节数字,在调节数字时未分配的库存要相应的增加或减少。保存时为每一个调节过的dingdan_bancai创建一个jinhuo记录
最新发布