|
|
@@ -0,0 +1,483 @@
|
|
|
+<template>
|
|
|
+ <div>
|
|
|
+ <layout>
|
|
|
+ <layout-header>
|
|
|
+ <div class="top-action-bar">
|
|
|
+ <el-button type="primary" @click="exportMonthlyData" style="margin: 5px">
|
|
|
+ <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16" style="margin-right: 5px">
|
|
|
+ <path d="M8.5 16a.5.5 0 0 1-.5-.5V1H5a1 1 0 0 1 0-2h6a1 1 0 0 1 0 2h-3.5v14.5a.5.5 0 0 1-.5.5z"/>
|
|
|
+ <path d="M7 14.5V6H2a1 1 0 0 1 0-2h12a1 1 0 0 1 0 2H9v8.5a1.5 1.5 0 0 1-3 0z"/>
|
|
|
+ </svg>
|
|
|
+ 导出出货大货生产进度表
|
|
|
+ </el-button>
|
|
|
+ </div>
|
|
|
+ </layout-header>
|
|
|
+
|
|
|
+ <layout>
|
|
|
+ <!-- 左侧日期菜单 -->
|
|
|
+ <layout-sider :resize-directions="['right']" :width="190" style="margin-right: 10px;">
|
|
|
+ <div class="JKWTree-tree treecolor">
|
|
|
+ <h3>出货月份选择</h3>
|
|
|
+ <el-tree :data="treeData" :props="defaultProps" @node-click="handleNodeClick"></el-tree>
|
|
|
+ </div>
|
|
|
+ </layout-sider>
|
|
|
+
|
|
|
+ <!-- 右侧表格区域 -->
|
|
|
+ <layout-content>
|
|
|
+ <el-main>
|
|
|
+ <div class="gva-table-box">
|
|
|
+ <!-- 表格数据 -->
|
|
|
+ <el-table ref="multipleTable" style="width: 100%; height: 65vh" tooltip-effect="dark"
|
|
|
+ :row-style="{ height: '25px' }" :header-cell-style="{ padding: '0px' }"
|
|
|
+ :cell-style="{ padding: '0px' }" :header-row-style="{ height: '20px' }"
|
|
|
+ :data="tableData" border row-key="ID"
|
|
|
+ size="small"
|
|
|
+ highlight-current-row="true"
|
|
|
+ @row-click="tableRowClick" :show-overflow-tooltip="true">
|
|
|
+ <el-table-column sortable align="center" label="款式" prop="款式" width="120" />
|
|
|
+ <el-table-column sortable align="center" label="客人编号" prop="客人编号" width="100" />
|
|
|
+ <el-table-column sortable align="center" label="下单日期" prop="下单日期" width="100" />
|
|
|
+ <el-table-column sortable align="center" label="货期" prop="货期" width="100" />
|
|
|
+ <el-table-column sortable align="center" label="款号" prop="款号" width="150" />
|
|
|
+ <el-table-column sortable align="center" label="生产组别" prop="生产组别" width="100" />
|
|
|
+ <el-table-column sortable align="center" label="订单数量" prop="订单数量" width="100" />
|
|
|
+ <el-table-column sortable align="center" label="实裁数量" prop="实裁数量" width="100" />
|
|
|
+ <el-table-column sortable align="center" label="已完成数量" prop="已完成数量" width="120" />
|
|
|
+ <el-table-column sortable align="center" label="入库数量" prop="入库数量" width="100" />
|
|
|
+ <el-table-column sortable align="center" label="面料入库时间" prop="面料入库时间" width="140" />
|
|
|
+ <el-table-column sortable align="center" label="辅料入库时间" prop="辅料入库时间" width="140" />
|
|
|
+ <el-table-column sortable align="center" label="产前样批核" prop="产前样批核" width="120" />
|
|
|
+ <el-table-column sortable align="center" label="开裁日期" prop="开裁日期" width="100" />
|
|
|
+ <el-table-column sortable align="center" label="上车位日期" prop="上车位日期" width="120" />
|
|
|
+ <el-table-column sortable align="center" label="台产" prop="台产" width="80" />
|
|
|
+ <el-table-column sortable align="center" label="车位完成日期" prop="车位完成日期" width="140" />
|
|
|
+ <el-table-column sortable align="center" label="后道完成日期" prop="后道完成日期" width="140" />
|
|
|
+ <el-table-column sortable align="center" label="备注" prop="备注" width="150" />
|
|
|
+ </el-table>
|
|
|
+
|
|
|
+ <!-- 分页 -->
|
|
|
+ <div class="gva-pagination">
|
|
|
+ <el-pagination layout="total" :current-page="page" :page-size="pageSize"
|
|
|
+ :total="total" @current-change="handleCurrentChange" @size-change="handleSizeChange" />
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </el-main>
|
|
|
+ </layout-content>
|
|
|
+ </layout>
|
|
|
+ </layout>
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+ <script setup>
|
|
|
+ import {ref, reactive, onMounted} from 'vue'
|
|
|
+ import { Layout, LayoutSider, LayoutContent, LayoutHeader } from '@arco-design/web-vue'
|
|
|
+ import {
|
|
|
+ getWorkOrderDates, getWorkOrdersByMonth,
|
|
|
+ } from '@/api/mes/job'
|
|
|
+
|
|
|
+ import { ElMessage } from 'element-plus'
|
|
|
+ import { useUserStore } from '@/pinia/modules/user'
|
|
|
+ import * as ExcelJS from 'exceljs'
|
|
|
+ import { saveAs } from 'file-saver'
|
|
|
+ const userStore = useUserStore()
|
|
|
+ const _username = ref('')
|
|
|
+ _username.value = userStore.userInfo.userName + '/' + userStore.userInfo.nickName
|
|
|
+
|
|
|
+ // 左侧树形数据
|
|
|
+ const treeData = ref([])
|
|
|
+ const defaultProps = {
|
|
|
+ label: 'label'
|
|
|
+ }
|
|
|
+
|
|
|
+ // 右侧表格数据
|
|
|
+ const tableData = reactive([])
|
|
|
+ const page = ref(1)
|
|
|
+ const total = ref(0)
|
|
|
+ const pageSize = ref(10)
|
|
|
+
|
|
|
+ // 选中的日期
|
|
|
+ const selectedDate = ref('')
|
|
|
+
|
|
|
+ // 获取日期列表
|
|
|
+ const getDateList = async () => {
|
|
|
+ try {
|
|
|
+ const response = await getWorkOrderDates({});
|
|
|
+ if (response.code === 0) {
|
|
|
+ // 格式化日期数据为树形结构
|
|
|
+ const formattedData = [];
|
|
|
+ const yearMap = {};
|
|
|
+
|
|
|
+ // 按年份分组
|
|
|
+ response.data.forEach(dateStr => {
|
|
|
+ const year = dateStr.substring(0, 4);
|
|
|
+ const month = dateStr.substring(5);
|
|
|
+
|
|
|
+ if (!yearMap[year]) {
|
|
|
+ yearMap[year] = [];
|
|
|
+ }
|
|
|
+ yearMap[year].push({
|
|
|
+ label: `${month}月`,
|
|
|
+ value: dateStr
|
|
|
+ });
|
|
|
+ });
|
|
|
+
|
|
|
+ // 转换为树形结构,并按年份降序排序
|
|
|
+ Object.entries(yearMap)
|
|
|
+ .sort(([yearA], [yearB]) => parseInt(yearB) - parseInt(yearA)) // 年份降序
|
|
|
+ .forEach(([year, months]) => {
|
|
|
+ // 月份降序排序
|
|
|
+ months.sort((a, b) => {
|
|
|
+ const monthA = parseInt(a.value.substring(5));
|
|
|
+ const monthB = parseInt(b.value.substring(5));
|
|
|
+ return monthB - monthA;
|
|
|
+ });
|
|
|
+
|
|
|
+ formattedData.push({
|
|
|
+ label: year + '年',
|
|
|
+ children: months
|
|
|
+ });
|
|
|
+ });
|
|
|
+
|
|
|
+ treeData.value = formattedData;
|
|
|
+ } else {
|
|
|
+ ElMessage.error('获取日期列表失败');
|
|
|
+ }
|
|
|
+ } catch (error) {
|
|
|
+ console.error('获取日期列表失败:', error);
|
|
|
+ ElMessage.error('获取日期列表失败');
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 处理节点点击
|
|
|
+ const handleNodeClick = async (node) => {
|
|
|
+ // 重置所有节点颜色
|
|
|
+ document.querySelectorAll('.treecolor .el-tree-node').forEach(treeNode => {
|
|
|
+ const label = treeNode.querySelector('.el-tree-node__label');
|
|
|
+ if (label) {
|
|
|
+ label.style.color = '';
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ // 获取当前点击的节点并设置颜色
|
|
|
+ const clickedNode = document.querySelector(`.treecolor .el-tree-node[data-key="${node['$treeNodeId']}"]`);
|
|
|
+ if (clickedNode) {
|
|
|
+ const label = clickedNode.querySelector('.el-tree-node__label');
|
|
|
+ if (label) {
|
|
|
+ label.style.color = 'red';
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 只有叶子节点(包含value属性)才触发数据加载
|
|
|
+ if (node.value) {
|
|
|
+ selectedDate.value = node.value;
|
|
|
+ await getWorkOrderData(node.value);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 获取工单数据
|
|
|
+ const getWorkOrderData = async (rq) => {
|
|
|
+ try {
|
|
|
+ const response = await getWorkOrdersByMonth({ rq: rq });
|
|
|
+ if (response.code === 0) {
|
|
|
+ // 格式化日期为月日格式
|
|
|
+ const formatDate = (dateStr) => {
|
|
|
+ if (!dateStr) return '';
|
|
|
+ const date = new Date(dateStr);
|
|
|
+ return `${date.getMonth() + 1}月${date.getDate()}日`;
|
|
|
+ };
|
|
|
+
|
|
|
+ // 处理数据
|
|
|
+ const formattedData = response.data.map((item, index) => ({
|
|
|
+ ID: index + 1,
|
|
|
+ ...item,
|
|
|
+ '下单日期': formatDate(item['下单日期']),
|
|
|
+ '货期': formatDate(item['货期']),
|
|
|
+ '面料入库时间': formatDate(item['面料入库时间']),
|
|
|
+ '开裁日期': formatDate(item['开裁日期']),
|
|
|
+ '上车位日期': formatDate(item['上车位日期']),
|
|
|
+ '车位完成日期': formatDate(item['车位完成日期']),
|
|
|
+ '后道完成日期': formatDate(item['后道完成日期'])
|
|
|
+ }));
|
|
|
+
|
|
|
+ tableData.splice(0, tableData.length, ...formattedData);
|
|
|
+ total.value = formattedData.length;
|
|
|
+ } else {
|
|
|
+ ElMessage.error('获取工单数据失败');
|
|
|
+ }
|
|
|
+ } catch (error) {
|
|
|
+ console.error('获取工单数据失败:', error);
|
|
|
+ ElMessage.error('获取工单数据失败');
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 表格行点击
|
|
|
+ const tableRowClick = (row) => {
|
|
|
+ console.log('点击行:', row);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 分页处理
|
|
|
+ const handleCurrentChange = (val) => {
|
|
|
+ page.value = val;
|
|
|
+ }
|
|
|
+
|
|
|
+ const handleSizeChange = (val) => {
|
|
|
+ pageSize.value = val;
|
|
|
+ page.value = 1;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 生命周期
|
|
|
+ onMounted(() => {
|
|
|
+ getDateList();
|
|
|
+ })
|
|
|
+
|
|
|
+ // 导出大货生产进度表
|
|
|
+ const exportMonthlyData = async () => {
|
|
|
+ if (!selectedDate.value) {
|
|
|
+ ElMessage.warning('请选择月份');
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ try {
|
|
|
+ // 1. 接口数据获取+处理
|
|
|
+ const rq = selectedDate.value;
|
|
|
+ const year = rq.substring(0, 4);
|
|
|
+ const month = rq.substring(5);
|
|
|
+ // 调用实际的大货生产进度表接口
|
|
|
+ const response = await getWorkOrdersByMonth({ rq: rq });
|
|
|
+ const originalData = response.data;
|
|
|
+ if (!originalData || originalData.length === 0) {
|
|
|
+ ElMessage.warning('暂无数据可导出');
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 核心配置
|
|
|
+ const YEAR = year;
|
|
|
+ const MONTH = month;
|
|
|
+ // 表头字段
|
|
|
+ const HEADER_FIELDS = ['款式', '客人编号', '下单日期', '货期', '款号', '生产组别', '订单数量', '实裁数量', '已完成数量', '入库数量', '面料入库时间', '辅料入库时间', '产前样批核', '开裁日期', '上车位日期', '台产', '车位完成日期', '后道完成日期', '备注'];
|
|
|
+ const totalCol = HEADER_FIELDS.length;
|
|
|
+
|
|
|
+ // 2. 数据处理 - 根据实际接口返回的数据结构进行调整
|
|
|
+ const dataRows = [];
|
|
|
+ // 处理接口返回的数据
|
|
|
+ originalData.forEach(item => {
|
|
|
+ // 格式化日期为月日格式
|
|
|
+ const formatDate = (dateStr) => {
|
|
|
+ if (!dateStr) return '';
|
|
|
+ const date = new Date(dateStr);
|
|
|
+ return `${date.getMonth() + 1}月${date.getDate()}日`;
|
|
|
+ };
|
|
|
+
|
|
|
+ // 构建数据行,按照表头字段顺序排列
|
|
|
+ const row = [
|
|
|
+ item['款式'] || '',
|
|
|
+ item['客人编号'] || '',
|
|
|
+ formatDate(item['下单日期']),
|
|
|
+ formatDate(item['货期']),
|
|
|
+ item['款号'] || '',
|
|
|
+ item['生产组别'] || '', // 接口返回中没有生产组别,默认为空
|
|
|
+ item['订单数量'] || '',
|
|
|
+ item['实裁数量'] || '',
|
|
|
+ item['已完成数量'] || '',
|
|
|
+ item['入库数量'] || '',
|
|
|
+ formatDate(item['面料入库时间']),
|
|
|
+ item['辅料入库时间'] || '', // 接口返回中没有辅料入库时间,默认为空
|
|
|
+ item['产前样批核'] || '', // 接口返回中没有产前样批核,默认为空
|
|
|
+ formatDate(item['开裁日期']),
|
|
|
+ formatDate(item['上车位日期']),
|
|
|
+ item['台产'] || '', // 接口返回中没有台产,默认为空
|
|
|
+ formatDate(item['车位完成日期']),
|
|
|
+ formatDate(item['后道完成日期']),
|
|
|
+ item['备注'] || '' // 接口返回中没有备注,默认为空
|
|
|
+ ];
|
|
|
+ dataRows.push(row);
|
|
|
+ });
|
|
|
+
|
|
|
+ // 3. 构建数据行
|
|
|
+ // 标题行
|
|
|
+ const titleRow = [`${MONTH}月份大货生产进度表`];
|
|
|
+ titleRow.push(...Array(totalCol-1).fill('')); // 标题行补空
|
|
|
+
|
|
|
+ // 表头行
|
|
|
+ const headerRow = [...HEADER_FIELDS];
|
|
|
+
|
|
|
+ // ============== ExcelJS 核心:创建工作簿+设置样式 ==============
|
|
|
+ // 4. 创建工作簿和工作表
|
|
|
+ const workbook = new ExcelJS.Workbook();
|
|
|
+ const worksheet = workbook.addWorksheet('Sheet1'); // 工作表名与原Excel一致
|
|
|
+
|
|
|
+ // 5. 写入数据(按行写入:标题行→表头行→数据行)
|
|
|
+ worksheet.addRow(titleRow);
|
|
|
+ worksheet.addRow(headerRow);
|
|
|
+ dataRows.forEach(row => worksheet.addRow(row));
|
|
|
+
|
|
|
+ // 辅助函数:将列索引转换为Excel列字母(如1→A, 2→B, 26→Z, 27→AA)
|
|
|
+ const getColumnLetter = (colIndex) => {
|
|
|
+ let letter = '';
|
|
|
+ let num = colIndex;
|
|
|
+ while (num > 0) {
|
|
|
+ const remainder = (num - 1) % 26;
|
|
|
+ letter = String.fromCharCode(65 + remainder) + letter;
|
|
|
+ num = Math.floor((num - 1) / 26);
|
|
|
+ }
|
|
|
+ return letter;
|
|
|
+ };
|
|
|
+
|
|
|
+ // 6. 样式配置:合并单元格+边框+底色+居中+列宽
|
|
|
+ // 6.1 合并单元格
|
|
|
+ const mergeRange = (range) => worksheet.mergeCells(range);
|
|
|
+ // 合并1:标题行(A1到最后一列1)
|
|
|
+ mergeRange(`A1:${getColumnLetter(totalCol)}1`);
|
|
|
+
|
|
|
+ // 6.2 定义样式模板
|
|
|
+ const commonStyle = { // 所有单元格公共样式:边框+居中+自动换行
|
|
|
+ border: {
|
|
|
+ top: { style: 'thin', color: { argb: 'FF000000' } },
|
|
|
+ bottom: { style: 'thin', color: { argb: 'FF000000' } },
|
|
|
+ left: { style: 'thin', color: { argb: 'FF000000' } },
|
|
|
+ right: { style: 'thin', color: { argb: 'FF000000' } }
|
|
|
+ },
|
|
|
+ alignment: { horizontal: 'center', vertical: 'middle', wrapText: true },
|
|
|
+ font: { size: 11, color: { argb: 'FF000000' } }
|
|
|
+ };
|
|
|
+ const titleStyle = { // 标题行样式:14号字+加粗
|
|
|
+ ...commonStyle,
|
|
|
+ font: { size: 14, bold: true, color: { argb: 'FF000000' } }
|
|
|
+ };
|
|
|
+ const headerStyle = { // 表头行样式:12号字+加粗
|
|
|
+ ...commonStyle,
|
|
|
+ font: { size: 12, bold: true, color: { argb: 'FF000000' } },
|
|
|
+ fill: { type: 'pattern', pattern: 'solid', fgColor: { argb: 'FFE6E6E6' } }
|
|
|
+ };
|
|
|
+ const remarkStyle = { // 备注列样式:红色字体
|
|
|
+ ...commonStyle,
|
|
|
+ font: { size: 11, color: { argb: 'FFFF0000' } }
|
|
|
+ };
|
|
|
+
|
|
|
+ // 6.3 应用样式到单元格
|
|
|
+ const lastRow = 2 + dataRows.length; // 最后一行:1行标题+1行表头+数据行
|
|
|
+
|
|
|
+ // 标题行(第1行):应用标题样式
|
|
|
+ worksheet.getRow(1).eachCell(cell => cell.style = titleStyle);
|
|
|
+
|
|
|
+ // 表头行(第2行):应用表头样式
|
|
|
+ worksheet.getRow(2).eachCell(cell => cell.style = headerStyle);
|
|
|
+
|
|
|
+ // 数据行(第3行到最后一行):应用公共样式,备注列应用红色字体
|
|
|
+ for (let row = 3; row <= lastRow; row++) {
|
|
|
+ const currentRow = worksheet.getRow(row);
|
|
|
+ currentRow.eachCell((cell, colIndex) => {
|
|
|
+ // 备注列(最后一列)应用红色字体
|
|
|
+ if (colIndex === totalCol) {
|
|
|
+ cell.style = remarkStyle;
|
|
|
+ } else {
|
|
|
+ cell.style = commonStyle;
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ // 6.4 设置列宽(根据实际需求调整)
|
|
|
+ const colWidths = [
|
|
|
+ 80, // 款式
|
|
|
+ 80, // 客人编号
|
|
|
+ 80, // 下单日期
|
|
|
+ 80, // 货期
|
|
|
+ 120, // 款号
|
|
|
+ 80, // 生产组别
|
|
|
+ 80, // 订单数量
|
|
|
+ 80, // 实裁数量
|
|
|
+ 80, // 已完成数量
|
|
|
+ 80, // 入库数量
|
|
|
+ 100, // 面料入库时间
|
|
|
+ 100, // 辅料入库时间
|
|
|
+ 100, // 产前样批核
|
|
|
+ 80, // 开裁日期
|
|
|
+ 80, // 上车位日期
|
|
|
+ 80, // 台产
|
|
|
+ 100, // 车位完成日期
|
|
|
+ 100, // 后道完成日期
|
|
|
+ 150 // 备注
|
|
|
+ ];
|
|
|
+ // ExcelJS列宽单位为「字符」,px转字符按 1px ≈ 0.14 换算
|
|
|
+ worksheet.columns = colWidths.map((width, index) => ({
|
|
|
+ key: index+1,
|
|
|
+ width: width * 0.14
|
|
|
+ }));
|
|
|
+
|
|
|
+ // 6.5 调整行高
|
|
|
+ worksheet.getRow(1).height = 30; // 标题行高
|
|
|
+ worksheet.getRow(2).height = 25; // 表头行高
|
|
|
+
|
|
|
+ // ============== 导出Excel文件 ==============
|
|
|
+ // 7. 生成blob并下载
|
|
|
+ const buffer = await workbook.xlsx.writeBuffer();
|
|
|
+ const blob = new Blob([buffer], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' });
|
|
|
+ saveAs(blob, `${MONTH}月份大货生产进度表.xlsx`);
|
|
|
+
|
|
|
+ ElMessage.success('导出成功!');
|
|
|
+ } catch (error) {
|
|
|
+ console.error('Excel导出失败:', error);
|
|
|
+ ElMessage.error('导出数据失败,请重试');
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ </script>
|
|
|
+ <style scoped>
|
|
|
+ /* 基本样式 */
|
|
|
+ .top-action-bar {
|
|
|
+ padding: 10px 20px;
|
|
|
+ background: #fff;
|
|
|
+ border-bottom: 1px solid #e8e8e8;
|
|
|
+ }
|
|
|
+
|
|
|
+ .action-buttons {
|
|
|
+ display: flex;
|
|
|
+ gap: 10px;
|
|
|
+ flex-wrap: wrap;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* 左侧树状图区域 */
|
|
|
+ .JKWTree-tree {
|
|
|
+ height: 100%;
|
|
|
+ padding: 10px;
|
|
|
+ background: #fff;
|
|
|
+ border-right: 1px solid #e8e8e8;
|
|
|
+ }
|
|
|
+
|
|
|
+ .JKWTree-tree h3 {
|
|
|
+ font-size: 15px;
|
|
|
+ font-weight: 700;
|
|
|
+ margin: 10px 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* 表格区域 */
|
|
|
+ .gva-table-box {
|
|
|
+ padding: 0px !important;
|
|
|
+ }
|
|
|
+
|
|
|
+ .gva-pagination {
|
|
|
+ margin-top: 10px;
|
|
|
+ text-align: right;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* 表格单元格样式 */
|
|
|
+ :deep(.el-table td .cell) {
|
|
|
+ line-height: 20px !important;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* 响应式设计 */
|
|
|
+ @media (max-width: 1200px) {
|
|
|
+ .cert-wrapper {
|
|
|
+ width: 95%;
|
|
|
+ padding: 30px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @media (max-width: 768px) {
|
|
|
+ .cert-wrapper {
|
|
|
+ width: 100%;
|
|
|
+ padding: 20px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ </style>
|
|
|
+
|
|
|
+
|