feat(CoilSelector): 新增入场卷号字段并调整当前卷号显示
feat(customer): 新增客户相关配卷和财务信息查询接口 fix(base.vue): 修复发货单时间条件显示问题 refactor(CustomerEdit): 替换地址选择组件为普通输入框 feat(CoilSelector): 增加入场卷号查询条件并调整对话框宽度 style(OrderEdit): 调整客户名称和销售员选择框宽度 refactor(ChinaAreaSelect): 优化地址解析逻辑并支持空对象处理 feat(FileUpload/FileList): 新增文件预览功能组件 refactor(KLPService/CustomerSelect): 优化客户选择组件并支持自定义字段绑定 fix(AbnormalForm): 修复异常位置校验逻辑并保留当前卷号 feat(ContractTabs): 新增合同附件展示功能 refactor(warehouse/record): 重构操作记录统计展示方式 feat(contract): 集成客户选择组件并优化合同信息填充 refactor(order): 调整订单表单布局并集成合同信息 feat(FilePreview): 新增文件预览组件 feat(customer): 新增财务状态和发货配卷展示 refactor(CustomerOrder): 移除冗余代码并优化布局 feat(PlanDetailForm): 新增合同附件查看功能 feat(dict): 新增字典管理页面
This commit is contained in:
@@ -42,3 +42,19 @@ export function delCustomer(customerId) {
|
|||||||
method: 'delete'
|
method: 'delete'
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 查询该客户相关的配卷情况
|
||||||
|
export function listCoilByCustomerId(customerId) {
|
||||||
|
return request({
|
||||||
|
url: '/crm/orderItem/coils/customer/' + customerId,
|
||||||
|
method: 'get'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查询该项目相关的订单异议和财务信息
|
||||||
|
export function listFinanceByCustomerId(customerId) {
|
||||||
|
return request({
|
||||||
|
url: '/crm/orderItem/customerFinance/' + customerId,
|
||||||
|
method: 'get'
|
||||||
|
})
|
||||||
|
}
|
||||||
@@ -47,12 +47,17 @@ function formatAreaText(value) {
|
|||||||
return { standard, custom };
|
return { standard, custom };
|
||||||
}
|
}
|
||||||
|
|
||||||
// 非组合格式(纯标准地址/纯自定义地址)→ 默认归为standard
|
// 非组合格式(纯任意字符串)→ 归为custom
|
||||||
return { standard: trimVal, custom: '' };
|
return { standard: '', custom: trimVal };
|
||||||
}
|
}
|
||||||
|
|
||||||
// ========== 场景3:输入是对象 → 格式化为组合字符串 ==========
|
// ========== 场景3:输入是对象 → 格式化为组合字符串 ==========
|
||||||
if (typeof value === 'object' && !Array.isArray(value)) {
|
if (typeof value === 'object' && !Array.isArray(value)) {
|
||||||
|
// 处理空对象
|
||||||
|
if (Object.keys(value).length === 0) {
|
||||||
|
return '[]()';
|
||||||
|
}
|
||||||
|
|
||||||
const { standard = '', custom = '' } = value;
|
const { standard = '', custom = '' } = value;
|
||||||
// 转字符串并去空格
|
// 转字符串并去空格
|
||||||
const standardStr = String(standard).trim();
|
const standardStr = String(standard).trim();
|
||||||
@@ -71,11 +76,19 @@ function formatAreaText(value) {
|
|||||||
*/
|
*/
|
||||||
function formatAreaTextEnhanced(value, keyType = 'name') {
|
function formatAreaTextEnhanced(value, keyType = 'name') {
|
||||||
// 先调用基础版解析/格式化
|
// 先调用基础版解析/格式化
|
||||||
const result = formatAreaText(value);
|
let result = formatAreaText(value);
|
||||||
|
|
||||||
// 如果是解析模式(返回对象)且keyType为name,转换code为name
|
// 如果是解析模式(返回对象)且keyType为name,检查是否为代码输入
|
||||||
if (typeof result === 'object' && keyType === 'name') {
|
if (typeof result === 'object' && keyType === 'name') {
|
||||||
result.standard = convertCodeToName(result.standard);
|
// 检查custom是否可能是代码(不包含中文)
|
||||||
|
if (result.custom && !/[\u4e00-\u9fa5]/.test(result.custom)) {
|
||||||
|
// 尝试转换code为name
|
||||||
|
const convertedName = convertCodeToName(result.custom);
|
||||||
|
// 如果转换成功(返回非空字符串),则将其移到standard字段
|
||||||
|
if (convertedName) {
|
||||||
|
result = { standard: convertedName, custom: '' };
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
|||||||
@@ -26,6 +26,7 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
import areaData from './data.js'
|
import areaData from './data.js'
|
||||||
|
import { formatAreaTextEnhanced } from './index.js'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'ChinaAreaSelectWithDetail',
|
name: 'ChinaAreaSelectWithDetail',
|
||||||
@@ -105,32 +106,9 @@ export default {
|
|||||||
* @param {String} val - 外部传入的「[标准地址](自定义地址)」格式值
|
* @param {String} val - 外部传入的「[标准地址](自定义地址)」格式值
|
||||||
*/
|
*/
|
||||||
parseCombineValue(val) {
|
parseCombineValue(val) {
|
||||||
if (!val) {
|
const formattedAddress = formatAreaTextEnhanced(val)
|
||||||
this.areaValue = []
|
this.areaValue = formattedAddress.standard.split('/').filter(Boolean)
|
||||||
this.detailAddress = ''
|
this.detailAddress = formattedAddress.custom.trim()
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// 核心正则:匹配「[xxx](yyy)」格式,分组提取xxx和yyy(无匹配则为空)
|
|
||||||
const reg = /\[([^\]]*)\]\(([^)]*)\)/
|
|
||||||
const matchResult = val.match(reg)
|
|
||||||
|
|
||||||
// 提取标准地址(第一个分组)和自定义地址(第二个分组)
|
|
||||||
const standardAddress = matchResult?.[1] || ''
|
|
||||||
const customAddress = matchResult?.[2] || ''
|
|
||||||
|
|
||||||
// 1. 处理自定义地址:直接赋值
|
|
||||||
this.detailAddress = customAddress.trim()
|
|
||||||
|
|
||||||
// 2. 处理标准地址:转换为区域选择器的code数组
|
|
||||||
if (standardAddress) {
|
|
||||||
const standardArr = standardAddress.split('/').filter(Boolean)
|
|
||||||
this.areaValue = this.keyType === 'name'
|
|
||||||
? this.convertNameToCode(standardArr) // name转code
|
|
||||||
: standardArr.filter(code => !!areaData[code]) // code直接过滤无效值
|
|
||||||
} else {
|
|
||||||
this.areaValue = []
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1,6 +1,12 @@
|
|||||||
export const defaultColumns = [
|
export const defaultColumns = [
|
||||||
{
|
{
|
||||||
label: '卷号',
|
label: '入场卷号',
|
||||||
|
align: 'center',
|
||||||
|
prop: 'enterCoilNo',
|
||||||
|
showOverflowTooltip: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '当前卷号',
|
||||||
align: 'center',
|
align: 'center',
|
||||||
prop: 'currentCoilNo',
|
prop: 'currentCoilNo',
|
||||||
showOverflowTooltip: true
|
showOverflowTooltip: true
|
||||||
|
|||||||
@@ -27,8 +27,12 @@
|
|||||||
<el-option label="原料" value="raw_material" />
|
<el-option label="原料" value="raw_material" />
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item> -->
|
</el-form-item> -->
|
||||||
<el-form-item label="卷号">
|
<el-form-item label="入场卷号">
|
||||||
<el-input v-model="queryParams.currentCoilNo" placeholder="请输入卷号" clearable size="small"
|
<el-input v-model="queryParams.enterCoilNo" placeholder="请输入入场卷号" clearable size="small"
|
||||||
|
@keyup.enter.native="handleQuery" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="当前卷号">
|
||||||
|
<el-input v-model="queryParams.currentCoilNo" placeholder="请输入当前卷号" clearable size="small"
|
||||||
@keyup.enter.native="handleQuery" />
|
@keyup.enter.native="handleQuery" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="物料">
|
<el-form-item label="物料">
|
||||||
@@ -192,7 +196,7 @@ export default {
|
|||||||
},
|
},
|
||||||
dialogWidth: {
|
dialogWidth: {
|
||||||
type: String,
|
type: String,
|
||||||
default: '1000px'
|
default: '1200px'
|
||||||
},
|
},
|
||||||
// 过滤条件(可以预设一些查询条件)
|
// 过滤条件(可以预设一些查询条件)
|
||||||
filters: {
|
filters: {
|
||||||
|
|||||||
@@ -15,6 +15,16 @@
|
|||||||
<i class="el-icon-document"></i>
|
<i class="el-icon-document"></i>
|
||||||
<span class="file-name">{{ file.originalName }}</span>
|
<span class="file-name">{{ file.originalName }}</span>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="file-actions">
|
||||||
|
<el-button
|
||||||
|
type="text"
|
||||||
|
icon="el-icon-view"
|
||||||
|
@click="handlePreview(file)"
|
||||||
|
size="small"
|
||||||
|
class="preview-btn"
|
||||||
|
>
|
||||||
|
预览
|
||||||
|
</el-button>
|
||||||
<el-button
|
<el-button
|
||||||
type="text"
|
type="text"
|
||||||
icon="el-icon-download"
|
icon="el-icon-download"
|
||||||
@@ -27,13 +37,25 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- 文件预览组件 -->
|
||||||
|
<file-preview
|
||||||
|
:visible.sync="previewVisible"
|
||||||
|
:file-url="previewFileUrl"
|
||||||
|
:file-name="previewFileName"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { listByIds } from "@/api/system/oss";
|
import { listByIds } from "@/api/system/oss";
|
||||||
|
import FilePreview from "../FilePreview";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "FileList",
|
name: "FileList",
|
||||||
|
components: {
|
||||||
|
FilePreview
|
||||||
|
},
|
||||||
props: {
|
props: {
|
||||||
ossIds: {
|
ossIds: {
|
||||||
type: String,
|
type: String,
|
||||||
@@ -43,7 +65,11 @@ export default {
|
|||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
fileList: [],
|
fileList: [],
|
||||||
loading: false // 加载状态
|
loading: false, // 加载状态
|
||||||
|
// 预览相关
|
||||||
|
previewVisible: false,
|
||||||
|
previewFileUrl: '',
|
||||||
|
previewFileName: ''
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
@@ -81,6 +107,12 @@ export default {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.$download.oss(file.ossId);
|
this.$download.oss(file.ossId);
|
||||||
|
},
|
||||||
|
// 预览文件
|
||||||
|
handlePreview(file) {
|
||||||
|
this.previewFileUrl = file.url;
|
||||||
|
this.previewFileName = file.originalName;
|
||||||
|
this.previewVisible = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -115,6 +147,12 @@ export default {
|
|||||||
transition: background-color 0.3s;
|
transition: background-color 0.3s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.file-actions {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
.file-item:last-child {
|
.file-item:last-child {
|
||||||
border-bottom: none;
|
border-bottom: none;
|
||||||
}
|
}
|
||||||
|
|||||||
185
klp-ui/src/components/FilePreview/index.vue
Normal file
185
klp-ui/src/components/FilePreview/index.vue
Normal file
@@ -0,0 +1,185 @@
|
|||||||
|
<template>
|
||||||
|
<el-dialog
|
||||||
|
:title="title"
|
||||||
|
:visible.sync="dialogVisible"
|
||||||
|
:width="width"
|
||||||
|
:close-on-click-modal="false"
|
||||||
|
destroy-on-close
|
||||||
|
append-to-body
|
||||||
|
@close="handleClose"
|
||||||
|
>
|
||||||
|
<!-- 图片预览 -->
|
||||||
|
<div v-if="fileType === 'image'" class="preview-image">
|
||||||
|
<div class="image-controls">
|
||||||
|
<el-button type="primary" size="small" @click="zoomIn">放大</el-button>
|
||||||
|
<el-button type="primary" size="small" @click="zoomOut">缩小</el-button>
|
||||||
|
<el-button type="primary" size="small" @click="resetZoom">重置</el-button>
|
||||||
|
</div>
|
||||||
|
<div class="image-container" ref="imageContainer">
|
||||||
|
<img
|
||||||
|
:src="fileUrl"
|
||||||
|
:style="{ transform: `scale(${scale})` }"
|
||||||
|
class="preview-image-content"
|
||||||
|
@wheel="handleWheel"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- PDF预览 -->
|
||||||
|
<div v-else-if="fileType === 'pdf'" class="preview-pdf">
|
||||||
|
<iframe
|
||||||
|
:src="fileUrl"
|
||||||
|
class="preview-pdf-content"
|
||||||
|
frameborder="0"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 不支持的文件类型 -->
|
||||||
|
<div v-else class="preview-not-supported">
|
||||||
|
<el-empty description="暂不支持预览此文件类型"></el-empty>
|
||||||
|
</div>
|
||||||
|
</el-dialog>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: "FilePreview",
|
||||||
|
props: {
|
||||||
|
visible: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
fileUrl: {
|
||||||
|
type: String,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
fileName: {
|
||||||
|
type: String,
|
||||||
|
default: "文件预览"
|
||||||
|
},
|
||||||
|
width: {
|
||||||
|
type: String,
|
||||||
|
default: "80%"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
dialogVisible: false,
|
||||||
|
scale: 1
|
||||||
|
};
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
visible: {
|
||||||
|
handler(val) {
|
||||||
|
this.dialogVisible = val;
|
||||||
|
},
|
||||||
|
immediate: true
|
||||||
|
},
|
||||||
|
dialogVisible(val) {
|
||||||
|
if (!val) {
|
||||||
|
this.$emit('update:visible', false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
title() {
|
||||||
|
return this.fileName || "文件预览";
|
||||||
|
},
|
||||||
|
fileType() {
|
||||||
|
const fileName = this.fileName || '';
|
||||||
|
const ext = fileName.split('.').pop()?.toLowerCase();
|
||||||
|
if (['png', 'jpg', 'jpeg', 'bmp', 'webp'].includes(ext)) {
|
||||||
|
return 'image';
|
||||||
|
} else if (ext === 'pdf') {
|
||||||
|
return 'pdf';
|
||||||
|
} else {
|
||||||
|
return 'other';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
handleClose() {
|
||||||
|
this.$emit('update:visible', false);
|
||||||
|
},
|
||||||
|
// 放大图片
|
||||||
|
zoomIn() {
|
||||||
|
if (this.scale < 3) {
|
||||||
|
this.scale += 0.1;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 缩小图片
|
||||||
|
zoomOut() {
|
||||||
|
if (this.scale > 0.1) {
|
||||||
|
this.scale -= 0.1;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 重置缩放
|
||||||
|
resetZoom() {
|
||||||
|
this.scale = 1;
|
||||||
|
},
|
||||||
|
// 鼠标滚轮缩放
|
||||||
|
handleWheel(event) {
|
||||||
|
event.preventDefault();
|
||||||
|
const delta = event.deltaY > 0 ? -0.1 : 0.1;
|
||||||
|
if ((this.scale > 0.1 || delta > 0) && (this.scale < 3 || delta < 0)) {
|
||||||
|
this.scale += delta;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.preview-image {
|
||||||
|
width: 100%;
|
||||||
|
height: 70vh;
|
||||||
|
background-color: #f5f7fa;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.image-controls {
|
||||||
|
padding: 10px;
|
||||||
|
display: flex;
|
||||||
|
gap: 10px;
|
||||||
|
border-bottom: 1px solid #e4e7ed;
|
||||||
|
background-color: #ffffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.image-container {
|
||||||
|
flex: 1;
|
||||||
|
overflow: auto;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: flex-start;
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.preview-image-content {
|
||||||
|
transition: transform 0.3s ease;
|
||||||
|
cursor: zoom-in;
|
||||||
|
max-width: 100%;
|
||||||
|
max-height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.preview-image-content:hover {
|
||||||
|
cursor: zoom-in;
|
||||||
|
}
|
||||||
|
|
||||||
|
.preview-pdf {
|
||||||
|
width: 100%;
|
||||||
|
height: 70vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
.preview-pdf-content {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.preview-not-supported {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
height: 400px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -32,19 +32,31 @@
|
|||||||
<span class="el-icon-document"> {{ getFileName(file.name) }} </span>
|
<span class="el-icon-document"> {{ getFileName(file.name) }} </span>
|
||||||
</el-link>
|
</el-link>
|
||||||
<div class="ele-upload-list__item-content-action">
|
<div class="ele-upload-list__item-content-action">
|
||||||
|
<el-link :underline="false" @click="handlePreview(file)" type="primary">预览</el-link>
|
||||||
<el-link :underline="false" @click="handleDelete(index)" type="danger">删除</el-link>
|
<el-link :underline="false" @click="handleDelete(index)" type="danger">删除</el-link>
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
</transition-group>
|
</transition-group>
|
||||||
|
|
||||||
|
<!-- 文件预览组件 -->
|
||||||
|
<file-preview
|
||||||
|
:visible.sync="previewVisible"
|
||||||
|
:file-url="previewFileUrl"
|
||||||
|
:file-name="previewFileName"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { getToken } from "@/utils/auth";
|
import { getToken } from "@/utils/auth";
|
||||||
import { listByIds, delOss } from "@/api/system/oss";
|
import { listByIds, delOss } from "@/api/system/oss";
|
||||||
|
import FilePreview from "../FilePreview";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "FileUpload",
|
name: "FileUpload",
|
||||||
|
components: {
|
||||||
|
FilePreview
|
||||||
|
},
|
||||||
props: {
|
props: {
|
||||||
// 值
|
// 值
|
||||||
value: [String, Object, Array],
|
value: [String, Object, Array],
|
||||||
@@ -85,6 +97,10 @@ export default {
|
|||||||
},
|
},
|
||||||
fileList: [],
|
fileList: [],
|
||||||
loading: false,
|
loading: false,
|
||||||
|
// 预览相关
|
||||||
|
previewVisible: false,
|
||||||
|
previewFileUrl: '',
|
||||||
|
previewFileName: ''
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
@@ -232,6 +248,12 @@ export default {
|
|||||||
}
|
}
|
||||||
return strs != "" ? strs.substr(0, strs.length - 1) : "";
|
return strs != "" ? strs.substr(0, strs.length - 1) : "";
|
||||||
},
|
},
|
||||||
|
// 预览文件
|
||||||
|
handlePreview(file) {
|
||||||
|
this.previewFileUrl = file.url;
|
||||||
|
this.previewFileName = file.name;
|
||||||
|
this.previewVisible = true;
|
||||||
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<el-select filterable v-model="_customerId" remote :remote-method="remoteSearchCustomer" :loading="customerLoading" placeholder="请选择客户">
|
<el-select filterable v-model="_customerId" remote :remote-method="remoteSearchCustomer" :style="style" :loading="customerLoading" placeholder="请选择客户">
|
||||||
<el-option v-for="item in customerList" :key="item.customerId" :label="item.name" :value="item.customerId" />
|
<el-option v-for="item in customerList" :key="item[bindField]" :label="item.companyName" :value="item[bindField]" />
|
||||||
</el-select>
|
</el-select>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -13,6 +13,14 @@
|
|||||||
value: {
|
value: {
|
||||||
type: String,
|
type: String,
|
||||||
default: ''
|
default: ''
|
||||||
|
},
|
||||||
|
bindField: {
|
||||||
|
type: String,
|
||||||
|
default: 'customerId'
|
||||||
|
},
|
||||||
|
style: {
|
||||||
|
type: Object,
|
||||||
|
default: () => ({})
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
@@ -22,6 +30,12 @@
|
|||||||
},
|
},
|
||||||
set(value) {
|
set(value) {
|
||||||
this.$emit('input', value);
|
this.$emit('input', value);
|
||||||
|
// 找到对应的客户信息
|
||||||
|
const customer = this.customerList.find(item => item[this.bindField] === value);
|
||||||
|
// 触发 change 事件,传递客户信息
|
||||||
|
if (customer) {
|
||||||
|
this.$emit('change', customer);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -37,7 +51,7 @@
|
|||||||
methods: {
|
methods: {
|
||||||
remoteSearchCustomer(query) {
|
remoteSearchCustomer(query) {
|
||||||
this.customerLoading = true;
|
this.customerLoading = true;
|
||||||
listCustomer({ name: query, pageNum: 1, pageSize: 10 }).then(response => {
|
listCustomer({ companyName: query, pageNum: 1, pageSize: 10 }).then(response => {
|
||||||
this.customerList = response.rows;
|
this.customerList = response.rows;
|
||||||
}).finally(() => {
|
}).finally(() => {
|
||||||
this.customerLoading = false;
|
this.customerLoading = false;
|
||||||
|
|||||||
@@ -7,9 +7,14 @@
|
|||||||
<template slot="title">
|
<template slot="title">
|
||||||
<!-- 在这里选择订单后快速填写相关信息 -->
|
<!-- 在这里选择订单后快速填写相关信息 -->
|
||||||
<span>订单信息</span>
|
<span>订单信息</span>
|
||||||
<el-button @click.stop="openOrderDialog" style="margin-left: 10px;" plain :type="formData.orderId ? 'success' : 'default'">
|
<el-button @click.stop="openOrderDialog" style="margin-left: 10px;" plain
|
||||||
|
:type="formData.orderId ? 'success' : 'default'">
|
||||||
{{ formData.orderId ? formData.orderCode : '选择订单' }}
|
{{ formData.orderId ? formData.orderCode : '选择订单' }}
|
||||||
</el-button>
|
</el-button>
|
||||||
|
<div v-if="formData.orderId" @click.stop="openOrderAttachmentDialog" style="margin-left: 10px; cursor: pointer; color: #409eff;"
|
||||||
|
type="primary">
|
||||||
|
查看附件
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<el-row>
|
<el-row>
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
@@ -207,12 +212,8 @@
|
|||||||
<el-form :model="orderQueryParams" ref="orderQueryForm" size="small" :inline="true" label-width="80px">
|
<el-form :model="orderQueryParams" ref="orderQueryForm" size="small" :inline="true" label-width="80px">
|
||||||
<el-form-item label="合同号">
|
<el-form-item label="合同号">
|
||||||
<el-select v-model="orderQueryParams.contractId" placeholder="请选择合同">
|
<el-select v-model="orderQueryParams.contractId" placeholder="请选择合同">
|
||||||
<el-option
|
<el-option v-for="contract in contractList" :key="contract.contractId" :label="contract.contractNo"
|
||||||
v-for="contract in contractList"
|
:value="contract.contractId" />
|
||||||
:key="contract.contractId"
|
|
||||||
:label="contract.contractNo"
|
|
||||||
:value="contract.contractId"
|
|
||||||
/>
|
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="订单号">
|
<el-form-item label="订单号">
|
||||||
@@ -250,14 +251,26 @@
|
|||||||
|
|
||||||
<!-- 分页 -->
|
<!-- 分页 -->
|
||||||
<div class="pagination-container">
|
<div class="pagination-container">
|
||||||
<el-pagination
|
<el-pagination background layout="prev, pager, next, jumper" :total="orderTotal"
|
||||||
background
|
:page-size="orderQueryParams.pageSize" :current-page.sync="orderQueryParams.pageNum"
|
||||||
layout="prev, pager, next, jumper"
|
@current-change="getOrderList" />
|
||||||
:total="orderTotal"
|
</div>
|
||||||
:page-size="orderQueryParams.pageSize"
|
</div>
|
||||||
:current-page.sync="orderQueryParams.pageNum"
|
</el-dialog>
|
||||||
@current-change="getOrderList"
|
|
||||||
/>
|
<el-dialog title="合同附件" :visible.sync="attachmentOpen" width="50%" append-to-body>
|
||||||
|
<div class="attachment-section" v-loading="loading">
|
||||||
|
<!-- <div class="attachment-item">
|
||||||
|
<h4>商务附件</h4>
|
||||||
|
<FileList :oss-ids="contractAttachment" />
|
||||||
|
</div> -->
|
||||||
|
<div class="attachment-item">
|
||||||
|
<h4>技术附件</h4>
|
||||||
|
<FileList :oss-ids="contract.techAnnex" />
|
||||||
|
</div>
|
||||||
|
<div class="attachment-item">
|
||||||
|
<h4>排产函</h4>
|
||||||
|
<FileList :oss-ids="contract.productionSchedule" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
@@ -265,8 +278,9 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { listOrder } from '@/api/crm/order';
|
import { listOrder, getOrder } from '@/api/crm/order';
|
||||||
import { listContract } from '@/api/crm/contract';
|
import { listContract, getContract } from '@/api/crm/contract';
|
||||||
|
import FileList from '@/components/FileList'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "PlanDetailForm",
|
name: "PlanDetailForm",
|
||||||
@@ -284,6 +298,9 @@ export default {
|
|||||||
default: false
|
default: false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
components: {
|
||||||
|
FileList
|
||||||
|
},
|
||||||
computed: {
|
computed: {
|
||||||
formData: {
|
formData: {
|
||||||
get() {
|
get() {
|
||||||
@@ -330,7 +347,10 @@ export default {
|
|||||||
contractId: undefined,
|
contractId: undefined,
|
||||||
contractCode: undefined,
|
contractCode: undefined,
|
||||||
customerName: undefined
|
customerName: undefined
|
||||||
}
|
},
|
||||||
|
attachmentOpen: false,
|
||||||
|
contract: {},
|
||||||
|
loading: false,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
@@ -349,6 +369,29 @@ export default {
|
|||||||
// 加载订单列表
|
// 加载订单列表
|
||||||
this.getOrderList();
|
this.getOrderList();
|
||||||
},
|
},
|
||||||
|
async openOrderAttachmentDialog() {
|
||||||
|
this.loading = true;
|
||||||
|
this.attachmentOpen = true;
|
||||||
|
// 根据订单id获取订单详情,拿到合同id
|
||||||
|
try {
|
||||||
|
if (!this.formData.orderId) {
|
||||||
|
this.$message.error('订单不存在')
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const order = await getOrder(this.formData.orderId);
|
||||||
|
if (!order.data.contractId) {
|
||||||
|
this.$message.error('未找到合同')
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// 根据合同id拿到合同详情
|
||||||
|
const contract = await getContract(order.data.contractId);
|
||||||
|
this.contract = contract.data;
|
||||||
|
} catch {
|
||||||
|
this.$message.error('获取合同附件失败')
|
||||||
|
} finally {
|
||||||
|
this.loading = false;
|
||||||
|
}
|
||||||
|
},
|
||||||
/** 获取合同列表 */
|
/** 获取合同列表 */
|
||||||
getContractList() {
|
getContractList() {
|
||||||
listContract().then(response => {
|
listContract().then(response => {
|
||||||
@@ -388,6 +431,7 @@ export default {
|
|||||||
this.formData.contractCode = row.contractCode;
|
this.formData.contractCode = row.contractCode;
|
||||||
this.formData.customerName = row.companyName;
|
this.formData.customerName = row.companyName;
|
||||||
this.formData.salesman = row.salesman;
|
this.formData.salesman = row.salesman;
|
||||||
|
this.formData.orderId = row.orderId;
|
||||||
this.dialogVisible = false;
|
this.dialogVisible = false;
|
||||||
},
|
},
|
||||||
/** 处理订单行点击 */
|
/** 处理订单行点击 */
|
||||||
@@ -411,4 +455,24 @@ export default {
|
|||||||
margin-top: 20px;
|
margin-top: 20px;
|
||||||
text-align: right;
|
text-align: right;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.attachment-section {
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.attachment-item {
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.attachment-item h4 {
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #303133;
|
||||||
|
}
|
||||||
|
|
||||||
|
.attachment-item .file-list-container {
|
||||||
|
border: 1px solid #ebeef5;
|
||||||
|
border-radius: 4px;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
@@ -95,17 +95,16 @@
|
|||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="24" v-hasPermi="['crm:customer:address']">
|
<el-col :span="24" v-hasPermi="['crm:customer:address']">
|
||||||
<el-form-item label="客户地址" prop="address">
|
<el-form-item label="客户地址" prop="address">
|
||||||
<!-- <el-input
|
<el-input
|
||||||
type="textarea"
|
|
||||||
v-model="customer.address"
|
v-model="customer.address"
|
||||||
placeholder="请输入客户地址"
|
placeholder="请输入客户地址"
|
||||||
@input="handleInputChange"
|
@input="handleInputChange"
|
||||||
/> -->
|
/>
|
||||||
<ChinaAreaSelect
|
<!-- <ChinaAreaSelect
|
||||||
v-model="customer.address"
|
v-model="customer.address"
|
||||||
placeholder="请选择客户地址"
|
placeholder="请选择客户地址"
|
||||||
@change="handleInputChange"
|
@change="handleInputChange"
|
||||||
/>
|
/> -->
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="24" v-hasPermi="['crm:customer:bank']">
|
<el-col :span="24" v-hasPermi="['crm:customer:bank']">
|
||||||
|
|||||||
@@ -1,12 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<el-descriptions :column="2" border title="订单统计">
|
|
||||||
<el-descriptions-item label="订单总数">{{ currentCustomer.totalCount || 0 }}</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="已成交订单数">{{ currentCustomer.dealCount || 0 }}</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="待成交订单数">{{ currentCustomer.waitCount || 0 }}</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="取消订单数">{{ currentCustomer.cancelCount || 0 }}</el-descriptions-item>
|
|
||||||
</el-descriptions>
|
|
||||||
|
|
||||||
<el-descriptions border title="订单详情">
|
<el-descriptions border title="订单详情">
|
||||||
</el-descriptions>
|
</el-descriptions>
|
||||||
|
|
||||||
@@ -21,6 +14,10 @@
|
|||||||
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
|
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
|
||||||
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
|
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
<el-form-item label="订单总数" prop="totalCount" style="margin-left: 10px; float: right;">
|
||||||
|
<div>{{ total || 0 }}</div>
|
||||||
|
<!-- <el-input v-model="queryParams.totalCount" placeholder="请输入订单总数" clearable @keyup.enter.native="handleQuery" /> -->
|
||||||
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
|
|
||||||
<el-table v-loading="loading" :data="orderList" height="400px" highlight-current-row @row-click="handleRowClick">
|
<el-table v-loading="loading" :data="orderList" height="400px" highlight-current-row @row-click="handleRowClick">
|
||||||
@@ -38,90 +35,15 @@
|
|||||||
<span v-else-if="scope.row.orderType === ORDER_TYPE['正式订单']">正式订单</span>
|
<span v-else-if="scope.row.orderType === ORDER_TYPE['正式订单']">正式订单</span>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<!-- <el-table-column v-if="orderType === ORDER_TYPE['预订单']" label="审核状态" align="center" prop="preOrderStatus">
|
|
||||||
<template slot-scope="scope">
|
|
||||||
<span v-if="scope.row.preOrderStatus === 0">待审核</span>
|
|
||||||
<span v-else-if="scope.row.preOrderStatus === 1">已审核</span>
|
|
||||||
<span v-else-if="scope.row.preOrderStatus === 2">已取消</span>
|
|
||||||
<span v-else>未知状态</span>
|
|
||||||
</template>
|
|
||||||
</el-table-column> -->
|
|
||||||
<!-- <el-table-column label="审核人" align="center" prop="auditUser" />
|
|
||||||
<el-table-column label="审核时间" align="center" prop="auditTime" width="180">
|
|
||||||
<template slot-scope="scope">
|
|
||||||
<span>{{ parseTime(scope.row.auditTime, '{y}-{m}-{d}') }}</span>
|
|
||||||
</template>
|
|
||||||
</el-table-column> -->
|
|
||||||
<!-- <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
|
|
||||||
<template slot-scope="scope">
|
|
||||||
<el-button
|
|
||||||
size="mini"
|
|
||||||
type="text"
|
|
||||||
icon="el-icon-check"
|
|
||||||
@click="handleApprove(scope.row)"
|
|
||||||
>审批</el-button>
|
|
||||||
<el-button
|
|
||||||
size="mini"
|
|
||||||
type="text"
|
|
||||||
icon="el-icon-edit"
|
|
||||||
@click="handleUpdate(scope.row)"
|
|
||||||
>修改</el-button>
|
|
||||||
<el-button
|
|
||||||
size="mini"
|
|
||||||
type="text"
|
|
||||||
icon="el-icon-delete"
|
|
||||||
@click="handleDelete(scope.row)"
|
|
||||||
>删除</el-button>
|
|
||||||
</template>
|
|
||||||
</el-table-column> -->
|
|
||||||
</el-table>
|
</el-table>
|
||||||
|
|
||||||
<pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize"
|
<pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize"
|
||||||
@pagination="getList" />
|
@pagination="getList" />
|
||||||
|
|
||||||
<!-- 正式订单明细列表组件 -->
|
|
||||||
<!-- <OrderDetailList ref="orderDetailList" :orderId="orderId" /> -->
|
|
||||||
|
|
||||||
<!-- 添加或修改正式订单主对话框 -->
|
|
||||||
<!-- <el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
|
|
||||||
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
|
|
||||||
<el-form-item label="订单编号" prop="orderCode">
|
|
||||||
<el-input v-model="form.orderCode" placeholder="请输入订单编号" />
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="客户" prop="customerId">
|
|
||||||
<el-select v-model="form.customerId" placeholder="请选择客户">
|
|
||||||
<el-option v-for="item in customerList" :key="item.customerId" :label="item.customerCode" :value="item.customerId" />
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="订单总金额" prop="orderAmount">
|
|
||||||
<el-input v-model="form.orderAmount" placeholder="请输入订单总金额" />
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="销售员" prop="salesman">
|
|
||||||
<el-input v-model="form.salesman" placeholder="请输入销售员" />
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="交货日期" prop="deliveryDate">
|
|
||||||
<el-date-picker clearable
|
|
||||||
v-model="form.deliveryDate"
|
|
||||||
type="datetime"
|
|
||||||
value-format="yyyy-MM-dd HH:mm:ss"
|
|
||||||
placeholder="请选择交货日期">
|
|
||||||
</el-date-picker>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="备注" prop="remark">
|
|
||||||
<el-input v-model="form.remark" placeholder="请输入备注" />
|
|
||||||
</el-form-item>
|
|
||||||
</el-form>
|
|
||||||
<div slot="footer" class="dialog-footer">
|
|
||||||
<el-button :loading="buttonLoading" type="primary" @click="submitForm">确 定</el-button>
|
|
||||||
<el-button @click="cancel">取 消</el-button>
|
|
||||||
</div>
|
|
||||||
</el-dialog> -->
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { listOrder, getOrder, delOrder, addOrder, updateOrder } from "@/api/crm/order";
|
import { listOrder, getOrder, delOrder, addOrder, updateOrder } from "@/api/crm/order";
|
||||||
// import { listCustomer } from "@/api/crm/customer";
|
|
||||||
import OrderDetailList from '@/views/crm/components/OrderDetail.vue'
|
import OrderDetailList from '@/views/crm/components/OrderDetail.vue'
|
||||||
import { ORDER_TYPE } from "../js/enum";
|
import { ORDER_TYPE } from "../js/enum";
|
||||||
|
|
||||||
|
|||||||
@@ -12,8 +12,8 @@
|
|||||||
<el-row>
|
<el-row>
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item label="客户名称" prop="customerId">
|
<el-form-item label="客户名称" prop="customerId">
|
||||||
<el-select v-model="form.customerId" placeholder="请选择客户名称">
|
<el-select style="width: 100%;" v-model="form.customerId" placeholder="请选择客户名称">
|
||||||
<el-option v-for="item in customerList" :key="item.customerId" :label="item.customerCode"
|
<el-option v-for="item in customerList" :key="item.customerId" :label="item.companyName"
|
||||||
:value="item.customerId"></el-option>
|
:value="item.customerId"></el-option>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
@@ -27,7 +27,7 @@
|
|||||||
|
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item label="销售员" prop="salesman">
|
<el-form-item label="销售员" prop="salesman">
|
||||||
<el-select v-model="form.salesman" placeholder="请选择销售员">
|
<el-select style="width: 100%;" v-model="form.salesman" placeholder="请选择销售员">
|
||||||
<el-option v-for="item in dict.type.wip_pack_saleman" :key="item.value" :label="item.label"
|
<el-option v-for="item in dict.type.wip_pack_saleman" :key="item.value" :label="item.label"
|
||||||
:value="item.value" />
|
:value="item.value" />
|
||||||
</el-select>
|
</el-select>
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
<div v-if="contractId" class="tabs-content">
|
<div v-if="contractId" class="tabs-content">
|
||||||
<el-tabs v-model="activeTab" type="card" tab-position="top" v-loading="tabLoading">
|
<el-tabs v-model="activeTab" type="card" tab-position="top" v-loading="tabLoading">
|
||||||
<el-tab-pane label="下发订单" name="second">
|
<el-tab-pane label="下发订单" name="second">
|
||||||
<OrderPage v-if="activeTab === 'second'" :contractId="contractId" />
|
<OrderPage v-if="activeTab === 'second'" :contractId="contractId" :customerId="customerId" />
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
<el-tab-pane label="财务状态" name="third">
|
<el-tab-pane label="财务状态" name="third">
|
||||||
<KLPTable v-loading="loading" :data="financeList">
|
<KLPTable v-loading="loading" :data="financeList">
|
||||||
@@ -38,6 +38,22 @@
|
|||||||
<el-tab-pane label="发货配卷" name="fifth">
|
<el-tab-pane label="发货配卷" name="fifth">
|
||||||
<CoilTable :data="coilList" />
|
<CoilTable :data="coilList" />
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
|
<el-tab-pane label="合同附件" name="sixth">
|
||||||
|
<div class="attachment-section">
|
||||||
|
<div class="attachment-item">
|
||||||
|
<h4>商务附件</h4>
|
||||||
|
<FileList :oss-ids="contractAttachment" />
|
||||||
|
</div>
|
||||||
|
<div class="attachment-item">
|
||||||
|
<h4>技术附件</h4>
|
||||||
|
<FileList :oss-ids="technicalAgreement" />
|
||||||
|
</div>
|
||||||
|
<div class="attachment-item">
|
||||||
|
<h4>排产函</h4>
|
||||||
|
<FileList :oss-ids="otherAttachment" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</el-tab-pane>
|
||||||
</el-tabs>
|
</el-tabs>
|
||||||
</div>
|
</div>
|
||||||
<div v-else class="no-selection" style="display: flex; align-items: center; justify-content: center; height: 100%;">
|
<div v-else class="no-selection" style="display: flex; align-items: center; justify-content: center; height: 100%;">
|
||||||
@@ -49,18 +65,24 @@
|
|||||||
<script>
|
<script>
|
||||||
import OrderPage from "@/views/crm/order/index.vue";
|
import OrderPage from "@/views/crm/order/index.vue";
|
||||||
import CoilTable from "../../components/CoilTable.vue";
|
import CoilTable from "../../components/CoilTable.vue";
|
||||||
|
import FileList from "@/components/FileList";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "ContractTabs",
|
name: "ContractTabs",
|
||||||
components: {
|
components: {
|
||||||
OrderPage,
|
OrderPage,
|
||||||
CoilTable
|
CoilTable,
|
||||||
|
FileList
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
contractId: {
|
contractId: {
|
||||||
type: [Number, String],
|
type: [Number, String],
|
||||||
default: null
|
default: null
|
||||||
},
|
},
|
||||||
|
customerId: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
financeList: {
|
financeList: {
|
||||||
type: Array,
|
type: Array,
|
||||||
default: () => []
|
default: () => []
|
||||||
@@ -80,6 +102,19 @@ export default {
|
|||||||
tabLoading: {
|
tabLoading: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false
|
default: false
|
||||||
|
},
|
||||||
|
// 附件字段
|
||||||
|
contractAttachment: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
technicalAgreement: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
otherAttachment: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
@@ -116,4 +151,24 @@ export default {
|
|||||||
height: 100%;
|
height: 100%;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.attachment-section {
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.attachment-item {
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.attachment-item h4 {
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #303133;
|
||||||
|
}
|
||||||
|
|
||||||
|
.attachment-item .file-list-container {
|
||||||
|
border: 1px solid #ebeef5;
|
||||||
|
border-radius: 4px;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
@@ -24,8 +24,12 @@
|
|||||||
|
|
||||||
<!-- 右侧下方:Tab标签页 -->
|
<!-- 右侧下方:Tab标签页 -->
|
||||||
<div class="tab-panel" ref="tabPanel" style="flex: 1; overflow-y: auto;">
|
<div class="tab-panel" ref="tabPanel" style="flex: 1; overflow-y: auto;">
|
||||||
<ContractTabs :contractId="form.contractId" :financeList="financeList" :objectionList="objectionList"
|
<ContractTabs :contractId="form.contractId"
|
||||||
:coilList="coilList" :tabLoading="tabLoading" />
|
:customerId="form.customerId" :financeList="financeList" :objectionList="objectionList"
|
||||||
|
:coilList="coilList" :tabLoading="tabLoading"
|
||||||
|
:contract-attachment="form.businessAnnex"
|
||||||
|
:technical-agreement="form.techAnnex"
|
||||||
|
:other-attachment="form.productionSchedule" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div v-else style="flex: 1; display: flex; flex-direction: column;">
|
<div v-else style="flex: 1; display: flex; flex-direction: column;">
|
||||||
@@ -102,7 +106,8 @@
|
|||||||
<!-- 需方信息 -->
|
<!-- 需方信息 -->
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item label="需方" prop="customer">
|
<el-form-item label="需方" prop="customer">
|
||||||
<el-input v-model="form.customer" placeholder="请输入需方" />
|
<CustomerSelect v-model="form.customer" bindField="companyName" @change="handleCustomerChange" :style="{ width: '100%' }" />
|
||||||
|
<!-- <el-input v-model="form.customer" placeholder="请输入需方" /> -->
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="需方地址" prop="customerAddress">
|
<el-form-item label="需方地址" prop="customerAddress">
|
||||||
<el-input v-model="form.customerAddress" placeholder="请输入需方地址" />
|
<el-input v-model="form.customerAddress" placeholder="请输入需方地址" />
|
||||||
@@ -151,6 +156,8 @@ import ContractList from "./components/ContractList.vue";
|
|||||||
import ContractPreview from "./components/ContractPreview.vue";
|
import ContractPreview from "./components/ContractPreview.vue";
|
||||||
import ContractTabs from "./components/ContractTabs.vue";
|
import ContractTabs from "./components/ContractTabs.vue";
|
||||||
import ProductContent from "./components/ProductContent.vue";
|
import ProductContent from "./components/ProductContent.vue";
|
||||||
|
import CustomerSelect from "@/components/KLPService/CustomerSelect/index.vue";
|
||||||
|
import { formatAreaTextEnhanced } from '@/components/ChinaAreaSelect/index.js'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "Contract",
|
name: "Contract",
|
||||||
@@ -158,7 +165,8 @@ export default {
|
|||||||
ContractList,
|
ContractList,
|
||||||
ContractPreview,
|
ContractPreview,
|
||||||
ContractTabs,
|
ContractTabs,
|
||||||
ProductContent
|
ProductContent,
|
||||||
|
CustomerSelect
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
@@ -258,6 +266,29 @@ export default {
|
|||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
|
/** 处理客户选择 */
|
||||||
|
handleCustomerChange(customer) {
|
||||||
|
console.log(customer);
|
||||||
|
this.form.customerAddress = customer.address;
|
||||||
|
this.form.customerPhone = customer.contactWay;
|
||||||
|
this.form.customerTaxNo = customer.taxNumber;
|
||||||
|
this.form.customerId = customer.customerId;
|
||||||
|
// 处理银行信息
|
||||||
|
if (customer.bankInfo) {
|
||||||
|
try {
|
||||||
|
const bankList = JSON.parse(customer.bankInfo);
|
||||||
|
if (bankList && bankList.length > 0) {
|
||||||
|
const firstBank = bankList[0];
|
||||||
|
this.form.customerBank = firstBank.bankName;
|
||||||
|
this.form.customerAccount = firstBank.bankAccount;
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('解析银行信息失败:', error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 开户行和银行账号在客户信息中是一个json数组字符串,如果存在则默认选中第一个,将输入框改为下拉选可以快速切换
|
||||||
|
console.log(customer);
|
||||||
|
},
|
||||||
|
|
||||||
/** 处理合同状态更新 */
|
/** 处理合同状态更新 */
|
||||||
handleStatusChange(status) {
|
handleStatusChange(status) {
|
||||||
|
|||||||
@@ -65,6 +65,39 @@
|
|||||||
<CustomerOrder :customer="currentCustomer" :dict="dict" />
|
<CustomerOrder :customer="currentCustomer" :dict="dict" />
|
||||||
</div>
|
</div>
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
|
<el-tab-pane label="财务状态" name="third">
|
||||||
|
<KLPTable v-loading="loading" :data="financeList">
|
||||||
|
<el-table-column label="收款日期" align="center" prop="dueDate" width="180">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<span>{{ parseTime(scope.row.dueDate, '{y}-{m}-{d}') }}</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="收款金额" align="center" prop="amount" />
|
||||||
|
<el-table-column label="备注" align="center" prop="remark" />
|
||||||
|
</KLPTable>
|
||||||
|
</el-tab-pane>
|
||||||
|
<el-tab-pane label="订单异议" name="fourth">
|
||||||
|
<el-table v-loading="loading" :data="objectionList">
|
||||||
|
<el-table-column label="编号" align="center" prop="objectionCode" />
|
||||||
|
<el-table-column label="状态" align="center" prop="objectionStatus">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<el-tag v-if="scope.row.objectionStatus === 0" type="danger">待处理</el-tag>
|
||||||
|
<el-tag v-else-if="scope.row.objectionStatus === 1" type="success">已处理</el-tag>
|
||||||
|
<el-tag v-else-if="scope.row.objectionStatus === 2" type="info">已关闭</el-tag>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="处理人" align="center" prop="handleUser" />
|
||||||
|
<el-table-column label="处理时间" align="center" prop="handleTime" width="180">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<span>{{ parseTime(scope.row.handleTime, '{y}-{m}-{d}') }}</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="备注" align="center" prop="remark" />
|
||||||
|
</el-table>
|
||||||
|
</el-tab-pane>
|
||||||
|
<el-tab-pane label="发货配卷" name="fifth">
|
||||||
|
<CoilTable :data="coilList" />
|
||||||
|
</el-tab-pane>
|
||||||
</el-tabs>
|
</el-tabs>
|
||||||
<el-empty v-else style="margin-top: 20px;" description="选择客户查看详情"></el-empty>
|
<el-empty v-else style="margin-top: 20px;" description="选择客户查看详情"></el-empty>
|
||||||
</el-col>
|
</el-col>
|
||||||
@@ -101,7 +134,8 @@
|
|||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="客户地址" prop="address">
|
<el-form-item label="客户地址" prop="address">
|
||||||
<ChinaAreaSelect v-model="form.address" placeholder="请选择客户地址" />
|
<el-input v-model="form.address" placeholder="请输入客户地址" />
|
||||||
|
<!-- <ChinaAreaSelect v-model="form.address" placeholder="请选择客户地址" /> -->
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="备注" prop="remark">
|
<el-form-item label="备注" prop="remark">
|
||||||
<el-input v-model="form.remark" placeholder="请输入备注" />
|
<el-input v-model="form.remark" placeholder="请输入备注" />
|
||||||
@@ -126,8 +160,9 @@ import CustomerDetail from '../components/CustomerInfo.vue'
|
|||||||
import CustomerEdit from '../components/CustomerEdit.vue'
|
import CustomerEdit from '../components/CustomerEdit.vue'
|
||||||
import CustomerOrder from '../components/CustomerOrder.vue'
|
import CustomerOrder from '../components/CustomerOrder.vue'
|
||||||
import ChinaAreaSelect from '@/components/ChinaAreaSelect/index.vue'
|
import ChinaAreaSelect from '@/components/ChinaAreaSelect/index.vue'
|
||||||
|
import CoilTable from '../components/CoilTable.vue'
|
||||||
|
|
||||||
import { listCustomer, addCustomer, updateCustomer, delCustomer } from '@/api/crm/customer'
|
import { listCustomer, addCustomer, updateCustomer, delCustomer, listCoilByCustomerId, listFinanceByCustomerId } from '@/api/crm/customer'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'CustomerPage',
|
name: 'CustomerPage',
|
||||||
@@ -137,12 +172,16 @@ export default {
|
|||||||
CustomerDetail,
|
CustomerDetail,
|
||||||
CustomerEdit,
|
CustomerEdit,
|
||||||
CustomerOrder,
|
CustomerOrder,
|
||||||
ChinaAreaSelect
|
ChinaAreaSelect,
|
||||||
|
CoilTable
|
||||||
},
|
},
|
||||||
dicts: ['customer_industry', 'customer_level'],
|
dicts: ['customer_industry', 'customer_level'],
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
customerList: [],
|
customerList: [],
|
||||||
|
financeList: [],
|
||||||
|
objectionList: [],
|
||||||
|
coilList: [],
|
||||||
showQuery: false,
|
showQuery: false,
|
||||||
queryParams: {
|
queryParams: {
|
||||||
industry: '',
|
industry: '',
|
||||||
@@ -187,6 +226,24 @@ export default {
|
|||||||
this.showQuery = !this.showQuery
|
this.showQuery = !this.showQuery
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// 获取客户财务状态
|
||||||
|
getFinanceList() {
|
||||||
|
if (!this.currentCustomerId) return;
|
||||||
|
listFinanceByCustomerId(this.currentCustomerId).then(response => {
|
||||||
|
this.financeList = response.data.financeList || [];
|
||||||
|
this.objectionList = response.data.oobjectionList || [];
|
||||||
|
}).catch(() => {
|
||||||
|
this.$message.error('获取客户财务状态失败');
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
/** 查询合同配卷列表 */
|
||||||
|
getCoilList() {
|
||||||
|
listContractPackaging(this.form.contractId).then(response => {
|
||||||
|
this.coilList = response.data || [];
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
debounce(fn, delay) {
|
debounce(fn, delay) {
|
||||||
return (...args) => {
|
return (...args) => {
|
||||||
if (this.debounceTimer) clearTimeout(this.debounceTimer);
|
if (this.debounceTimer) clearTimeout(this.debounceTimer);
|
||||||
|
|||||||
497
klp-ui/src/views/crm/dict/index.vue
Normal file
497
klp-ui/src/views/crm/dict/index.vue
Normal file
@@ -0,0 +1,497 @@
|
|||||||
|
<template>
|
||||||
|
<div class="app-container">
|
||||||
|
<el-row :gutter="20">
|
||||||
|
<!-- 左侧:字典类型管理 -->
|
||||||
|
<el-col :span="6" style="height: calc(100vh - 124px); overflow-y: auto;">
|
||||||
|
<div>
|
||||||
|
<div class="dict-type-list">
|
||||||
|
<div
|
||||||
|
v-for="item in typeList"
|
||||||
|
:key="item.dictId"
|
||||||
|
:class="['dict-type-item', { 'active': selectedDictType === item.dictType }]"
|
||||||
|
@click="selectDictType(item.dictType, item.dictId)"
|
||||||
|
>
|
||||||
|
<div class="dict-type-name">{{ item.dictName }}</div>
|
||||||
|
<div class="dict-type-info">
|
||||||
|
<span class="dict-type-code">{{ item.dictType }}</span>
|
||||||
|
<span class="dict-type-id">#{{ item.dictId }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</el-col>
|
||||||
|
|
||||||
|
<!-- 右侧:字典数据管理 -->
|
||||||
|
<el-col :span="18" style="height: 100%; overflow-y: auto;">
|
||||||
|
<div class="dict-data-container">
|
||||||
|
<h3>字典数据管理</h3>
|
||||||
|
<el-form :model="dataQueryParams" ref="dataQueryForm" size="small" :inline="true" v-show="dataShowSearch" label-width="68px">
|
||||||
|
<el-form-item label="字典标签" prop="dictLabel">
|
||||||
|
<el-input
|
||||||
|
v-model="dataQueryParams.dictLabel"
|
||||||
|
placeholder="请输入字典标签"
|
||||||
|
clearable
|
||||||
|
@keyup.enter.native="dataHandleQuery"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="状态" prop="status">
|
||||||
|
<el-select v-model="dataQueryParams.status" placeholder="数据状态" clearable>
|
||||||
|
<el-option
|
||||||
|
v-for="dict in dict.type.sys_normal_disable"
|
||||||
|
:key="dict.value"
|
||||||
|
:label="dict.label"
|
||||||
|
:value="dict.value"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item>
|
||||||
|
<el-button type="primary" icon="el-icon-search" size="mini" @click="dataHandleQuery">搜索</el-button>
|
||||||
|
<el-button icon="el-icon-refresh" size="mini" @click="dataResetQuery">重置</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
|
||||||
|
<el-row :gutter="10" class="mb8">
|
||||||
|
<el-col :span="1.5">
|
||||||
|
<el-button
|
||||||
|
type="primary"
|
||||||
|
plain
|
||||||
|
icon="el-icon-plus"
|
||||||
|
size="mini"
|
||||||
|
@click="dataHandleAdd"
|
||||||
|
v-hasPermi="['system:dict:add']"
|
||||||
|
>新增</el-button>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="1.5">
|
||||||
|
<el-button
|
||||||
|
type="success"
|
||||||
|
plain
|
||||||
|
icon="el-icon-edit"
|
||||||
|
size="mini"
|
||||||
|
:disabled="dataSingle"
|
||||||
|
@click="dataHandleUpdate"
|
||||||
|
v-hasPermi="['system:dict:edit']"
|
||||||
|
>修改</el-button>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="1.5">
|
||||||
|
<el-button
|
||||||
|
type="danger"
|
||||||
|
plain
|
||||||
|
icon="el-icon-delete"
|
||||||
|
size="mini"
|
||||||
|
:disabled="dataMultiple"
|
||||||
|
@click="dataHandleDelete"
|
||||||
|
v-hasPermi="['system:dict:remove']"
|
||||||
|
>删除</el-button>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="1.5">
|
||||||
|
<el-button
|
||||||
|
type="warning"
|
||||||
|
plain
|
||||||
|
icon="el-icon-download"
|
||||||
|
size="mini"
|
||||||
|
@click="dataHandleExport"
|
||||||
|
v-hasPermi="['system:dict:export']"
|
||||||
|
>导出</el-button>
|
||||||
|
</el-col>
|
||||||
|
<right-toolbar :showSearch.sync="dataShowSearch" @queryTable="dataGetList"></right-toolbar>
|
||||||
|
</el-row>
|
||||||
|
|
||||||
|
<el-empty v-if="!dataQueryParams.dictType" description="请选择一个字典类型" />
|
||||||
|
<template v-else>
|
||||||
|
<el-table v-loading="dataLoading" max-height="calc(100vh - 300px)" :data="dataList" @selection-change="dataHandleSelectionChange">
|
||||||
|
<el-table-column type="selection" width="55" align="center" />
|
||||||
|
<el-table-column label="字典编码" align="center" prop="dictCode" />
|
||||||
|
<el-table-column label="字典标签" align="center" prop="dictLabel">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<span v-if="scope.row.listClass == '' || scope.row.listClass == 'default'">{{scope.row.dictLabel}}</span>
|
||||||
|
<el-tag v-else :type="scope.row.listClass == 'primary' ? '' : scope.row.listClass">{{scope.row.dictLabel}}</el-tag>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="字典键值" align="center" prop="dictValue" />
|
||||||
|
<el-table-column label="字典排序" align="center" prop="dictSort" />
|
||||||
|
<el-table-column label="状态" align="center" prop="status">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<dict-tag :options="dict.type.sys_normal_disable" :value="scope.row.status"/>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="备注" align="center" prop="remark" :show-overflow-tooltip="true" />
|
||||||
|
<el-table-column label="创建时间" align="center" prop="createTime" width="180">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<span>{{ parseTime(scope.row.createTime) }}</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<el-button
|
||||||
|
size="mini"
|
||||||
|
type="text"
|
||||||
|
icon="el-icon-edit"
|
||||||
|
@click="dataHandleUpdate(scope.row)"
|
||||||
|
v-hasPermi="['system:dict:edit']"
|
||||||
|
>修改</el-button>
|
||||||
|
<el-button
|
||||||
|
size="mini"
|
||||||
|
type="text"
|
||||||
|
icon="el-icon-delete"
|
||||||
|
@click="dataHandleDelete(scope.row)"
|
||||||
|
v-hasPermi="['system:dict:remove']"
|
||||||
|
>删除</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
|
||||||
|
<pagination
|
||||||
|
v-show="dataTotal>0"
|
||||||
|
:total="dataTotal"
|
||||||
|
:page.sync="dataQueryParams.pageNum"
|
||||||
|
:limit.sync="dataQueryParams.pageSize"
|
||||||
|
@pagination="dataGetList"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- 添加或修改字典数据对话框 -->
|
||||||
|
<el-dialog :title="dataTitle" :visible.sync="dataOpen" width="500px" append-to-body>
|
||||||
|
<el-form ref="dataForm" :model="dataForm" :rules="dataRules" label-width="80px">
|
||||||
|
<el-form-item label="字典类型">
|
||||||
|
<el-input v-model="dataForm.dictType" :disabled="true" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="数据标签" prop="dictLabel">
|
||||||
|
<el-input v-model="dataForm.dictLabel" placeholder="请输入数据标签" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="数据键值" prop="dictValue">
|
||||||
|
<el-input v-model="dataForm.dictValue" placeholder="请输入数据键值" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="样式属性" prop="cssClass">
|
||||||
|
<el-input v-model="dataForm.cssClass" placeholder="请输入样式属性" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="显示排序" prop="dictSort">
|
||||||
|
<el-input-number :controls=false controls-position="right" v-model="dataForm.dictSort" :min="0" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="回显样式" prop="listClass">
|
||||||
|
<el-select v-model="dataForm.listClass">
|
||||||
|
<el-option
|
||||||
|
v-for="item in listClassOptions"
|
||||||
|
:key="item.value"
|
||||||
|
:label="item.label + '(' + item.value + ')'"
|
||||||
|
:value="item.value"
|
||||||
|
></el-option>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="状态" prop="status">
|
||||||
|
<el-radio-group v-model="dataForm.status">
|
||||||
|
<el-radio
|
||||||
|
v-for="dict in dict.type.sys_normal_disable"
|
||||||
|
:key="dict.value"
|
||||||
|
:label="dict.value"
|
||||||
|
>{{dict.label}}</el-radio>
|
||||||
|
</el-radio-group>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="备注" prop="remark">
|
||||||
|
<el-input v-model="dataForm.remark" type="textarea" placeholder="请输入内容"></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
<div slot="footer" class="dialog-footer">
|
||||||
|
<el-button type="primary" @click="dataSubmitForm">确 定</el-button>
|
||||||
|
<el-button @click="dataCancel">取 消</el-button>
|
||||||
|
</div>
|
||||||
|
</el-dialog>
|
||||||
|
</div>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { listType, getType, delType, addType, updateType, refreshCache, optionselect as getDictOptionselect } from "@/api/system/dict/type";
|
||||||
|
import { listData, getData, delData, addData, updateData } from "@/api/system/dict/data";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "Dict",
|
||||||
|
dicts: ['sys_normal_disable'],
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
// 字典类型管理相关
|
||||||
|
typeLoading: false,
|
||||||
|
typeIds: [],
|
||||||
|
typeSingle: true,
|
||||||
|
typeMultiple: true,
|
||||||
|
typeShowSearch: true,
|
||||||
|
typeTotal: 0,
|
||||||
|
selectedDictType: '',
|
||||||
|
typeList: [
|
||||||
|
{ dictId: '1996470503006347266', dictName: "钢卷异常位置", dictType: "coil_abnormal_position" },
|
||||||
|
{ dictId: '1996471384858763265', dictName: "钢卷异常缺陷代码", dictType: "coil_abnormal_code" },
|
||||||
|
{ dictId: '1996471559400529922', dictName: "钢卷异常程度", dictType: "coil_abnormal_degree" },
|
||||||
|
{ dictId: '2000385565177729025', dictName: "钢卷厂家", dictType: "coil_manufacturer" },
|
||||||
|
{ dictId: '2000385689094246401', dictName: "钢卷材质", dictType: "coil_material" },
|
||||||
|
{ dictId: '2000385875539447809', dictName: "钢卷名称", dictType: "coil_itemname" },
|
||||||
|
|
||||||
|
{ dictId: '2000445660494381058', dictName: "客户行业", dictType: "customer_industry" },
|
||||||
|
{ dictId: '2000446466396340226', dictName: "客户等级", dictType: "customer_level" },
|
||||||
|
{ dictId: '2010954150756622337', dictName: "钢卷质量状态", dictType: "coil_quality_status" },
|
||||||
|
{ dictId: '2034910283200458753', dictName: "机组产线", dictType: "sys_lines" },
|
||||||
|
|
||||||
|
],
|
||||||
|
typeTitle: "",
|
||||||
|
typeOpen: false,
|
||||||
|
typeDateRange: [],
|
||||||
|
typeQueryParams: {
|
||||||
|
pageNum: 1,
|
||||||
|
pageSize: 20,
|
||||||
|
dictName: undefined,
|
||||||
|
dictType: undefined,
|
||||||
|
status: undefined
|
||||||
|
},
|
||||||
|
typeForm: {},
|
||||||
|
typeRules: {
|
||||||
|
dictName: [
|
||||||
|
{ required: true, message: "字典名称不能为空", trigger: "blur" }
|
||||||
|
],
|
||||||
|
dictType: [
|
||||||
|
{ required: true, message: "字典类型不能为空", trigger: "blur" }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
|
||||||
|
// 字典数据管理相关
|
||||||
|
dataLoading: true,
|
||||||
|
dataIds: [],
|
||||||
|
dataSingle: true,
|
||||||
|
dataMultiple: true,
|
||||||
|
dataShowSearch: true,
|
||||||
|
dataTotal: 0,
|
||||||
|
dataList: [],
|
||||||
|
dataTitle: "",
|
||||||
|
dataOpen: false,
|
||||||
|
listClassOptions: [
|
||||||
|
{
|
||||||
|
value: "default",
|
||||||
|
label: "默认"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: "primary",
|
||||||
|
label: "主要"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: "success",
|
||||||
|
label: "成功"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: "info",
|
||||||
|
label: "信息"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: "warning",
|
||||||
|
label: "警告"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: "danger",
|
||||||
|
label: "危险"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
typeOptions: [],
|
||||||
|
dataQueryParams: {
|
||||||
|
pageNum: 1,
|
||||||
|
pageSize: 20,
|
||||||
|
dictName: undefined,
|
||||||
|
dictType: undefined,
|
||||||
|
status: undefined
|
||||||
|
},
|
||||||
|
dataForm: {},
|
||||||
|
dataRules: {
|
||||||
|
dictLabel: [
|
||||||
|
{ required: true, message: "数据标签不能为空", trigger: "blur" }
|
||||||
|
],
|
||||||
|
dictValue: [
|
||||||
|
{ required: true, message: "数据键值不能为空", trigger: "blur" }
|
||||||
|
],
|
||||||
|
dictSort: [
|
||||||
|
{ required: true, message: "数据顺序不能为空", trigger: "blur" }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
};
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
// 初始化时设置类型选项
|
||||||
|
this.typeOptions = this.typeList.map(item => ({
|
||||||
|
dictId: item.dictId,
|
||||||
|
dictName: item.dictName,
|
||||||
|
dictType: item.dictType
|
||||||
|
}));
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
// 字典数据管理方法
|
||||||
|
/** 查询字典数据列表 */
|
||||||
|
dataGetList() {
|
||||||
|
this.dataLoading = true;
|
||||||
|
listData(this.dataQueryParams).then(response => {
|
||||||
|
this.dataList = response.rows;
|
||||||
|
this.dataTotal = response.total;
|
||||||
|
this.dataLoading = false;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
// 取消按钮
|
||||||
|
dataCancel() {
|
||||||
|
this.dataOpen = false;
|
||||||
|
this.dataReset();
|
||||||
|
},
|
||||||
|
// 表单重置
|
||||||
|
dataReset() {
|
||||||
|
this.dataForm = {
|
||||||
|
dictCode: undefined,
|
||||||
|
dictLabel: undefined,
|
||||||
|
dictValue: undefined,
|
||||||
|
cssClass: undefined,
|
||||||
|
listClass: 'default',
|
||||||
|
dictSort: 0,
|
||||||
|
status: "0",
|
||||||
|
remark: undefined
|
||||||
|
};
|
||||||
|
this.resetForm("dataForm");
|
||||||
|
},
|
||||||
|
/** 搜索按钮操作 */
|
||||||
|
dataHandleQuery() {
|
||||||
|
this.dataQueryParams.pageNum = 1;
|
||||||
|
this.dataGetList();
|
||||||
|
},
|
||||||
|
/** 重置按钮操作 */
|
||||||
|
dataResetQuery() {
|
||||||
|
this.resetForm("dataQueryForm");
|
||||||
|
this.dataHandleQuery();
|
||||||
|
},
|
||||||
|
/** 新增按钮操作 */
|
||||||
|
dataHandleAdd() {
|
||||||
|
this.dataReset();
|
||||||
|
this.dataOpen = true;
|
||||||
|
this.dataTitle = "添加字典数据";
|
||||||
|
this.dataForm.dictType = this.dataQueryParams.dictType;
|
||||||
|
},
|
||||||
|
// 多选框选中数据
|
||||||
|
dataHandleSelectionChange(selection) {
|
||||||
|
this.dataIds = selection.map(item => item.dictCode)
|
||||||
|
this.dataSingle = selection.length!=1
|
||||||
|
this.dataMultiple = !selection.length
|
||||||
|
},
|
||||||
|
/** 修改按钮操作 */
|
||||||
|
dataHandleUpdate(row) {
|
||||||
|
this.dataReset();
|
||||||
|
const dictCode = row.dictCode || this.dataIds
|
||||||
|
getData(dictCode).then(response => {
|
||||||
|
this.dataForm = response.data;
|
||||||
|
this.dataOpen = true;
|
||||||
|
this.dataTitle = "修改字典数据";
|
||||||
|
});
|
||||||
|
},
|
||||||
|
/** 提交按钮 */
|
||||||
|
dataSubmitForm: function() {
|
||||||
|
this.$refs["dataForm"].validate(valid => {
|
||||||
|
if (valid) {
|
||||||
|
if (this.dataForm.dictCode != undefined) {
|
||||||
|
updateData(this.dataForm).then(response => {
|
||||||
|
this.$store.dispatch('dict/removeDict', this.dataQueryParams.dictType);
|
||||||
|
this.$modal.msgSuccess("修改成功");
|
||||||
|
this.dataOpen = false;
|
||||||
|
this.dataGetList();
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
addData(this.dataForm).then(response => {
|
||||||
|
this.$store.dispatch('dict/removeDict', this.dataQueryParams.dictType);
|
||||||
|
this.$modal.msgSuccess("新增成功");
|
||||||
|
this.dataOpen = false;
|
||||||
|
this.dataGetList();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
/** 删除按钮操作 */
|
||||||
|
dataHandleDelete(row) {
|
||||||
|
const dictCodes = row.dictCode || this.dataIds;
|
||||||
|
this.$modal.confirm('是否确认删除字典编码为"' + dictCodes + '"的数据项?').then(function() {
|
||||||
|
return delData(dictCodes);
|
||||||
|
}).then(() => {
|
||||||
|
this.dataGetList();
|
||||||
|
this.$modal.msgSuccess("删除成功");
|
||||||
|
this.$store.dispatch('dict/removeDict', this.dataQueryParams.dictType);
|
||||||
|
}).catch(() => {});
|
||||||
|
},
|
||||||
|
/** 导出按钮操作 */
|
||||||
|
dataHandleExport() {
|
||||||
|
this.download('system/dict/data/export', {
|
||||||
|
...this.dataQueryParams
|
||||||
|
}, `data_${new Date().getTime()}.xlsx`)
|
||||||
|
},
|
||||||
|
|
||||||
|
/** 选择字典类型 */
|
||||||
|
selectDictType(dictType, dictId) {
|
||||||
|
this.selectedDictType = dictType;
|
||||||
|
this.dataQueryParams.dictType = dictType;
|
||||||
|
this.dataGetList();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.dict-type-container,
|
||||||
|
.dict-data-container {
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
h3 {
|
||||||
|
margin-bottom: 20px;
|
||||||
|
font-size: 18px;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #303133;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dict-type-list {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dict-type-item {
|
||||||
|
padding: 15px;
|
||||||
|
border: 1px solid #e4e7ed;
|
||||||
|
border-radius: 4px;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dict-type-item:hover {
|
||||||
|
border-color: #409eff;
|
||||||
|
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.dict-type-item.active {
|
||||||
|
border-color: #409eff;
|
||||||
|
background-color: #ecf5ff;
|
||||||
|
box-shadow: 0 2px 12px 0 rgba(64, 158, 255, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.dict-type-item.active .dict-type-name {
|
||||||
|
color: #409eff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dict-type-name {
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: bold;
|
||||||
|
margin-bottom: 5px;
|
||||||
|
color: #303133;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dict-type-info {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
font-size: 14px;
|
||||||
|
color: #606266;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dict-type-code {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dict-type-id {
|
||||||
|
color: #909399;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -102,28 +102,28 @@
|
|||||||
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
|
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
|
||||||
<el-form-item label="订单编号" prop="orderCode">
|
<el-form-item label="订单编号" prop="orderCode">
|
||||||
<el-input v-model="form.orderCode" placeholder="请输入订单编号" />
|
<el-input v-model="form.orderCode" placeholder="请输入订单编号" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="合同号" prop="contractId">
|
||||||
|
<el-select style="width: 100%;" v-model="form.contractId" placeholder="请选择合同号" filterable clearable @change="handleContractChange">
|
||||||
|
<el-option v-for="item in contractList" :key="item.contractId" :label="item.contractNo"
|
||||||
|
:value="item.contractId" />
|
||||||
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="客户" prop="customerId">
|
<el-form-item label="客户" prop="customerId">
|
||||||
<!-- <el-input v-model="form.customerId" placeholder="请输入客户" /> -->
|
<!-- <el-input v-model="form.customerId" placeholder="请输入客户" /> -->
|
||||||
<el-select v-model="form.customerId" placeholder="请选择客户">
|
<el-select style="width: 100%;" v-model="form.customerId" placeholder="请选择客户">
|
||||||
<el-option v-for="item in customerList" :key="item.customerId" :label="item.customerCode"
|
<el-option v-for="item in customerList" :key="item.customerId" :label="item.companyName"
|
||||||
:value="item.customerId" />
|
:value="item.customerId" />
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="订单总金额" prop="orderAmount">
|
|
||||||
<el-input v-model="form.orderAmount" placeholder="请输入订单总金额" />
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="销售员" prop="salesman">
|
<el-form-item label="销售员" prop="salesman">
|
||||||
<el-select v-model="form.salesman" placeholder="请选择销售员">
|
<el-select style="width: 100%;" v-model="form.salesman" placeholder="请选择销售员">
|
||||||
<el-option v-for="item in dict.type.wip_pack_saleman" :key="item.value" :label="item.label"
|
<el-option v-for="item in dict.type.wip_pack_saleman" :key="item.value" :label="item.label"
|
||||||
:value="item.value" />
|
:value="item.value" />
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="合同号" prop="contractId">
|
<el-form-item label="订单总金额" prop="orderAmount">
|
||||||
<el-select v-model="form.contractId" placeholder="请选择合同号" filterable clearable @change="handleContractChange">
|
<el-input v-model="form.orderAmount" placeholder="请输入订单总金额" />
|
||||||
<el-option v-for="item in contractList" :key="item.contractId" :label="item.contractNo"
|
|
||||||
:value="item.contractId" />
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="交货日期" prop="deliveryDate">
|
<el-form-item label="交货日期" prop="deliveryDate">
|
||||||
<el-date-picker clearable v-model="form.deliveryDate" type="datetime" value-format="yyyy-MM-dd HH:mm:ss"
|
<el-date-picker clearable v-model="form.deliveryDate" type="datetime" value-format="yyyy-MM-dd HH:mm:ss"
|
||||||
@@ -177,6 +177,10 @@ export default {
|
|||||||
contractId: {
|
contractId: {
|
||||||
type: String,
|
type: String,
|
||||||
default: ''
|
default: ''
|
||||||
|
},
|
||||||
|
customerId: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
@@ -186,7 +190,7 @@ export default {
|
|||||||
showQuery: false,
|
showQuery: false,
|
||||||
queryParams: {
|
queryParams: {
|
||||||
orderCode: '',
|
orderCode: '',
|
||||||
customerId: '',
|
customerId: this.customerId,
|
||||||
salesman: '',
|
salesman: '',
|
||||||
orderStatus: '',
|
orderStatus: '',
|
||||||
contractId: this.contractId,
|
contractId: this.contractId,
|
||||||
@@ -243,7 +247,10 @@ export default {
|
|||||||
handleContractChange(contractId) {
|
handleContractChange(contractId) {
|
||||||
const contract = this.contractList.find(item => item.contractId === contractId)
|
const contract = this.contractList.find(item => item.contractId === contractId)
|
||||||
if (contract) {
|
if (contract) {
|
||||||
|
console.log(contract)
|
||||||
this.form.contractCode = contract.contractNo
|
this.form.contractCode = contract.contractNo
|
||||||
|
this.form.deliveryDate = contract.deliveryDate
|
||||||
|
this.form.customerId = contract.customerId
|
||||||
}
|
}
|
||||||
|
|
||||||
},
|
},
|
||||||
@@ -284,7 +291,7 @@ export default {
|
|||||||
orderId: undefined,
|
orderId: undefined,
|
||||||
orderCode: undefined,
|
orderCode: undefined,
|
||||||
orderType: ORDER_TYPE['正式订单'],
|
orderType: ORDER_TYPE['正式订单'],
|
||||||
customerId: undefined,
|
customerId: this.customerId,
|
||||||
orderAmount: undefined,
|
orderAmount: undefined,
|
||||||
salesman: undefined,
|
salesman: undefined,
|
||||||
deliveryDate: undefined,
|
deliveryDate: undefined,
|
||||||
|
|||||||
@@ -73,12 +73,12 @@ export default {
|
|||||||
{ required: true, message: '请选择位置', trigger: 'change' }
|
{ required: true, message: '请选择位置', trigger: 'change' }
|
||||||
],
|
],
|
||||||
startPosition: [
|
startPosition: [
|
||||||
{ required: true, message: '请输入开始位置', trigger: 'blur' },
|
{ required: true, message: '请输入开始位置', trigger: ['blur', 'change'] },
|
||||||
// { type: 'number', message: '请输入数字', trigger: 'blur' }
|
{ validator: this.validateStartPosition, trigger: ['blur', 'change'] }
|
||||||
],
|
],
|
||||||
endPosition: [
|
endPosition: [
|
||||||
{ required: true, message: '请输入结束位置', trigger: 'blur' },
|
{ required: true, message: '请输入结束位置', trigger: ['blur', 'change'] },
|
||||||
// { type: 'number', message: '请输入数字', trigger: 'blur' }
|
{ validator: this.validateEndPosition, trigger: ['blur', 'change'] }
|
||||||
],
|
],
|
||||||
defectCode: [
|
defectCode: [
|
||||||
{ required: true, message: '请选择缺陷代码', trigger: 'change' }
|
{ required: true, message: '请选择缺陷代码', trigger: 'change' }
|
||||||
@@ -102,14 +102,19 @@ export default {
|
|||||||
methods: {
|
methods: {
|
||||||
/** 表单验证 */
|
/** 表单验证 */
|
||||||
validate(callback) {
|
validate(callback) {
|
||||||
|
if (this.formData.startPosition > this.formData.endPosition) {
|
||||||
|
this.$message.error('开始位置必须小于结束位置');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
return this.$refs.form.validate(callback);
|
return this.$refs.form.validate(callback);
|
||||||
},
|
},
|
||||||
/** 重置表单 */
|
/** 重置表单 */
|
||||||
resetFields() {
|
resetFields() {
|
||||||
this.$refs.form.resetFields();
|
this.$refs.form.resetFields();
|
||||||
|
const currentCoilId = this.formData.coilId;
|
||||||
this.formData = {
|
this.formData = {
|
||||||
abnormalId: undefined,
|
abnormalId: undefined,
|
||||||
coilId: undefined,
|
coilId: currentCoilId,
|
||||||
position: undefined,
|
position: undefined,
|
||||||
startPosition: undefined,
|
startPosition: undefined,
|
||||||
endPosition: undefined,
|
endPosition: undefined,
|
||||||
@@ -124,6 +129,22 @@ export default {
|
|||||||
if (this.formData.startPosition && this.formData.endPosition) {
|
if (this.formData.startPosition && this.formData.endPosition) {
|
||||||
this.formData.length = this.formData.endPosition - this.formData.startPosition;
|
this.formData.length = this.formData.endPosition - this.formData.startPosition;
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
/** 校验开始位置 */
|
||||||
|
validateStartPosition(rule, value, callback) {
|
||||||
|
if (value <= 0) {
|
||||||
|
callback(new Error('开始位置必须为正数'));
|
||||||
|
} else {
|
||||||
|
callback();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
/** 校验结束位置 */
|
||||||
|
validateEndPosition(rule, value, callback) {
|
||||||
|
if (value <= 0) {
|
||||||
|
callback(new Error('结束位置必须为正数'));
|
||||||
|
} else {
|
||||||
|
callback();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -48,8 +48,8 @@
|
|||||||
<MaterialSelect :hideType="hideType" :itemId.sync="queryParams.itemIds" :itemType.sync="queryParams.itemType"
|
<MaterialSelect :hideType="hideType" :itemId.sync="queryParams.itemIds" :itemType.sync="queryParams.itemType"
|
||||||
:multiple="true" />
|
:multiple="true" />
|
||||||
|
|
||||||
<el-form-item label="发货单时间">
|
<el-form-item v-if="showWaybill" label="发货单时间">
|
||||||
<el-date-picker v-if="showWaybill" v-model="queryParams.shipmentTime" type="daterange" value-format="yyyy-MM-dd HH:mm:ss"
|
<el-date-picker v-model="queryParams.shipmentTime" type="daterange" value-format="yyyy-MM-dd HH:mm:ss"
|
||||||
range-separator="至" start-placeholder="开始日期" end-placeholder="结束日期" />
|
range-separator="至" start-placeholder="开始日期" end-placeholder="结束日期" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
|
|||||||
@@ -28,6 +28,8 @@
|
|||||||
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
|
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
|
|
||||||
|
|
||||||
<!-- 统计指标卡 -->
|
<!-- 统计指标卡 -->
|
||||||
<el-row :gutter="10" class="mb10">
|
<el-row :gutter="10" class="mb10">
|
||||||
<el-col :span="8">
|
<el-col :span="8">
|
||||||
@@ -71,15 +73,28 @@
|
|||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
|
|
||||||
<!-- 图表区域 -->
|
<!-- 操作人汇总表格 -->
|
||||||
<el-row :gutter="10" class="mb10">
|
<el-card shadow="hover" :body-style="{ padding: '10px' }" class="mb10">
|
||||||
<el-col :span="12">
|
|
||||||
<el-card shadow="hover" :body-style="{ padding: '10px' }">
|
|
||||||
<div slot="header" class="clearfix" style="padding-bottom: 5px;">
|
<div slot="header" class="clearfix" style="padding-bottom: 5px;">
|
||||||
<span>操作记录趋势</span>
|
<span>操作记录趋势</span>
|
||||||
</div>
|
</div>
|
||||||
<div id="trendChart" style="height: 250px;"></div>
|
<div id="trendChart" style="height: 250px;"></div>
|
||||||
</el-card>
|
</el-card>
|
||||||
|
|
||||||
|
<!-- 图表区域 -->
|
||||||
|
<el-row :gutter="10" class="mb10">
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-card shadow="hover" :body-style="{ padding: '10px' }">
|
||||||
|
<el-table :data="userSummaryData" style="width: 100%" height="280px">
|
||||||
|
<el-table-column prop="createBy" label="操作人" width="180"></el-table-column>
|
||||||
|
<el-table-column prop="coilCount" label="操作卷数" width="120"></el-table-column>
|
||||||
|
<el-table-column prop="totalWeight" label="总重量(kg)">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
{{ scope.row.totalWeight.toFixed(2) }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
</el-card>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="6">
|
<el-col :span="6">
|
||||||
<el-card shadow="hover" :body-style="{ padding: '10px' }">
|
<el-card shadow="hover" :body-style="{ padding: '10px' }">
|
||||||
@@ -212,6 +227,8 @@ export default {
|
|||||||
totalWeight: 0,
|
totalWeight: 0,
|
||||||
warehouseCount: 0
|
warehouseCount: 0
|
||||||
},
|
},
|
||||||
|
// 操作人汇总数据
|
||||||
|
userSummaryData: [],
|
||||||
// 图表实例
|
// 图表实例
|
||||||
trendChart: null,
|
trendChart: null,
|
||||||
pieChart: null,
|
pieChart: null,
|
||||||
@@ -258,7 +275,7 @@ export default {
|
|||||||
this.queryParams.createEndTime = this.queryParams.createTimeRange[1];
|
this.queryParams.createEndTime = this.queryParams.createTimeRange[1];
|
||||||
}
|
}
|
||||||
// 移除分页参数,获取全部数据
|
// 移除分页参数,获取全部数据
|
||||||
const params = { ...this.queryParams, pageNum:1, pageSize: 10000 };
|
const params = { ...this.queryParams, pageNum: 1, pageSize: 10000 };
|
||||||
|
|
||||||
listCoilWarehouseOperationLog(params).then(response => {
|
listCoilWarehouseOperationLog(params).then(response => {
|
||||||
this.allData = response.rows;
|
this.allData = response.rows;
|
||||||
@@ -296,6 +313,26 @@ export default {
|
|||||||
});
|
});
|
||||||
this.stats.warehouseCount = warehouseIds.size;
|
this.stats.warehouseCount = warehouseIds.size;
|
||||||
|
|
||||||
|
// 按操作人汇总数据
|
||||||
|
const userMap = {};
|
||||||
|
this.allData.forEach(item => {
|
||||||
|
const user = item.createBy || '未知';
|
||||||
|
if (!userMap[user]) {
|
||||||
|
userMap[user] = {
|
||||||
|
createBy: user,
|
||||||
|
coilCount: 0,
|
||||||
|
totalWeight: 0
|
||||||
|
};
|
||||||
|
}
|
||||||
|
userMap[user].coilCount++;
|
||||||
|
if (item.coil && item.coil.netWeight) {
|
||||||
|
userMap[user].totalWeight += parseFloat(item.coil.netWeight);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 转换为数组并按操作卷数降序排序
|
||||||
|
this.userSummaryData = Object.values(userMap).sort((a, b) => b.coilCount - a.coilCount);
|
||||||
|
|
||||||
// 更新图表数据
|
// 更新图表数据
|
||||||
this.updateCharts();
|
this.updateCharts();
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user