feat(crm): 新增订单操作记录、异议和收款组件

refactor(crm): 重构订单操作使用actions统一处理
style(crm): 清理无用代码和注释
fix(crm): 修复订单记录排序问题
This commit is contained in:
砂糖
2025-12-26 14:45:11 +08:00
parent 2033d39243
commit 96b6e844d9
12 changed files with 1190 additions and 48 deletions

View File

@@ -98,7 +98,7 @@ public class CrmOrderOperationTraceServiceImpl implements ICrmOrderOperationTrac
lqw.eq(StringUtils.isNotBlank(bo.getOperator()), CrmOrderOperationTrace::getOperator, bo.getOperator());
lqw.eq(bo.getOperationTime() != null, CrmOrderOperationTrace::getOperationTime, bo.getOperationTime());
//根据创建时间正序排序
lqw.orderByAsc(CrmOrderOperationTrace::getCreateTime);
lqw.orderByDesc(CrmOrderOperationTrace::getCreateTime);
return lqw;
}

View File

@@ -5,7 +5,7 @@
</template>
<script>
import { listCustomer } from '@/api/wms/customer';
import { listCustomer } from '@/api/crm/customer';
export default {
name: 'CustomerSelect',

View File

@@ -25,7 +25,6 @@
<el-table v-loading="loading" :data="orderList" height="400px" highlight-current-row @row-click="handleRowClick">
<el-table-column label="订单编号" align="center" prop="orderCode" />
<!-- <el-table-column label="客户" align="center" prop="customerId" /> -->
<el-table-column label="总金额" align="center" prop="orderAmount" />
<el-table-column label="销售员" align="center" prop="salesman" />
<el-table-column label="交货日期" align="center" prop="deliveryDate" width="180">
@@ -202,6 +201,7 @@ export default {
if (newVal !== oldVal) {
this.queryParams.customerId = newVal;
this.getList();
this.getSummary();
}
},
immediate: true
@@ -209,6 +209,38 @@ export default {
},
methods: {
/** 查询正式订单主列表 */
getSummary() {
Promise.all(
[
listOrder({
pageNum: 1,
pageSize: 1,
customerId: this.customerId,
preOrderStatus: 0, // 待审核
}),
listOrder({
pageNum: 1,
pageSize: 1,
customerId: this.customerId,
preOrderStatus: 1, // 已审核
}),
listOrder({
pageNum: 1,
pageSize: 1,
customerId: this.customerId,
preOrderStatus: 2, // 已取消
}),
]
).then(([preOrderList, auditOrderList, canOrderList]) => {
console.log(preOrderList, auditOrderList, canOrderList)
this.currentCustomer = {
waitCount: preOrderList.total,
dealCount: auditOrderList.total,
cancelCount: canOrderList.total,
total: preOrderList.total + auditOrderList.total + canOrderList.total,
}
})
},
getList() {
if (!this.customerId) {
this.total = 0;

View File

@@ -64,6 +64,7 @@
<script>
import { listOrderItem, getOrderItem, delOrderItem, addOrderItem, updateOrderItem } from "@/api/crm/orderItem";
import { actions, ORDER_ACTIONS } from "../js/actions";
export default {
name: "OrderItem",
@@ -223,7 +224,7 @@ export default {
if (valid) {
this.buttonLoading = true;
if (this.form.itemId != null) {
updateOrderItem(this.form).then(response => {
actions[ORDER_ACTIONS.updateOrderdetail].handler(this.form).then(response => {
this.$modal.msgSuccess("修改成功");
this.open = false;
this.getList();
@@ -231,7 +232,7 @@ export default {
this.buttonLoading = false;
});
} else {
addOrderItem(this.form).then(response => {
actions[ORDER_ACTIONS.createOrderdetail].handler(this.form).then(response => {
this.$modal.msgSuccess("新增成功");
this.open = false;
this.getList();

View File

@@ -0,0 +1,352 @@
<template>
<div>
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
<el-form-item label="异议编号" prop="objectionCode">
<el-input
v-model="queryParams.objectionCode"
placeholder="请输入异议编号"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="处理人" prop="handleUser">
<el-input
v-model="queryParams.handleUser"
placeholder="请输入处理人"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item>
<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-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="handleAdd"
>新增</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="warning"
plain
icon="el-icon-download"
size="mini"
@click="handleExport"
>导出</el-button>
</el-col>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
<el-table v-loading="loading" :data="salesObjectionList" @selection-change="handleSelectionChange">
<el-table-column label="编号" align="center" prop="objectionCode" />
<!-- <el-table-column label="异议类型" align="center" prop="objectionType" /> -->
<!-- <el-table-column label="异议内容" align="center" prop="objectionContent" /> -->
<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="handleContent" /> -->
<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="closeTime" width="180">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.closeTime, '{y}-{m}-{d}') }}</span>
</template>
</el-table-column> -->
<el-table-column label="备注" align="center" prop="remark" />
<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="handleUpdate(scope.row)"
></el-button>
<el-button
size="mini"
type="text"
icon="el-icon-check"
@click="handleDo(scope.row)"
></el-button>
<!-- <el-button
size="mini"
type="text"
icon="el-icon-check"
@click="handleFinish(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>
<pagination
v-show="total>0"
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
<!-- 添加或修改销售异议管理对话框 -->
<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="objectionCode">
<el-input v-model="form.objectionCode" placeholder="请输入异议编号" />
</el-form-item>
<el-form-item label="异议内容">
<editor v-model="form.objectionContent" :min-height="192"/>
</el-form-item>
<!-- <el-form-item label="处理内容">
<editor v-model="form.handleContent" :min-height="192"/>
</el-form-item>
<el-form-item label="处理人" prop="handleUser">
<el-input v-model="form.handleUser" placeholder="请输入处理人" />
</el-form-item>
<el-form-item label="处理时间" prop="handleTime">
<el-date-picker clearable
v-model="form.handleTime"
type="datetime"
value-format="yyyy-MM-dd HH:mm:ss"
placeholder="请选择处理时间">
</el-date-picker>
</el-form-item>
<el-form-item label="结案时间" prop="closeTime">
<el-date-picker clearable
v-model="form.closeTime"
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>
</template>
<script>
import { listSalesObjection, getSalesObjection, delSalesObjection, addSalesObjection, updateSalesObjection } from "@/api/crm/salesObjection";
export default {
name: "SalesObjection",
props: {
order: {
type: Object,
default: () => {}
}
},
computed: {
customerId() {
return this.order.customerId
},
orderId() {
console.log(this.order, 'order')
return this.order.orderId
}
},
watch: {
orderId: {
handler(newVal, oldVal) {
if (newVal !== oldVal) {
this.queryParams.orderId = newVal
// this.queryParams.customerId = this.customerId
this.getList();
}
},
immediate: true
},
},
data() {
return {
// 按钮loading
buttonLoading: false,
// 遮罩层
loading: true,
// 选中数组
ids: [],
// 非单个禁用
single: true,
// 非多个禁用
multiple: true,
// 显示搜索条件
showSearch: true,
// 总条数
total: 0,
// 销售异议管理表格数据
salesObjectionList: [],
// 弹出层标题
title: "",
// 是否显示弹出层
open: false,
// 查询参数
queryParams: {
pageNum: 1,
pageSize: 10,
objectionCode: undefined,
orderId: this.orderId,
customerId: this.customerId,
objectionType: undefined,
objectionContent: undefined,
objectionStatus: undefined,
handleContent: undefined,
handleUser: undefined,
handleTime: undefined,
closeTime: undefined,
},
// 表单参数
form: {},
// 表单校验
rules: {
}
};
},
methods: {
/** 查询销售异议管理列表 */
getList() {
this.loading = true;
listSalesObjection(this.queryParams).then(response => {
this.salesObjectionList = response.rows;
this.total = response.total;
this.loading = false;
});
},
// 取消按钮
cancel() {
this.open = false;
this.reset();
},
// 表单重置
reset() {
this.form = {
objectionId: undefined,
objectionCode: undefined,
orderId: this.orderId,
customerId: this.customerId,
objectionType: 0,
objectionContent: undefined,
objectionStatus: undefined,
handleContent: undefined,
handleUser: undefined,
handleTime: undefined,
closeTime: undefined,
remark: undefined,
createBy: undefined,
createTime: undefined,
updateBy: undefined,
updateTime: undefined,
delFlag: undefined
};
this.resetForm("form");
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1;
this.getList();
},
/** 重置按钮操作 */
resetQuery() {
this.resetForm("queryForm");
this.handleQuery();
},
// 多选框选中数据
handleSelectionChange(selection) {
this.ids = selection.map(item => item.objectionId)
this.single = selection.length!==1
this.multiple = !selection.length
},
handleDo(row) {
console.log(row, '处理')
},
/** 新增按钮操作 */
handleAdd() {
this.reset();
this.open = true;
this.title = "添加销售异议管理";
},
/** 修改按钮操作 */
handleUpdate(row) {
this.loading = true;
this.reset();
const objectionId = row.objectionId || this.ids
getSalesObjection(objectionId).then(response => {
this.loading = false;
this.form = response.data;
this.open = true;
this.title = "修改销售异议管理";
});
},
/** 提交按钮 */
submitForm() {
this.$refs["form"].validate(valid => {
if (valid) {
this.buttonLoading = true;
if (this.form.objectionId != null) {
updateSalesObjection(this.form).then(response => {
this.$modal.msgSuccess("修改成功");
this.open = false;
this.getList();
}).finally(() => {
this.buttonLoading = false;
});
} else {
addSalesObjection(this.form).then(response => {
this.$modal.msgSuccess("新增成功");
this.open = false;
this.getList();
}).finally(() => {
this.buttonLoading = false;
});
}
}
});
},
/** 删除按钮操作 */
handleDelete(row) {
const objectionIds = row.objectionId || this.ids;
this.$modal.confirm('是否确认删除销售异议管理编号为"' + objectionIds + '"的数据项?').then(() => {
this.loading = true;
return delSalesObjection(objectionIds);
}).then(() => {
this.loading = false;
this.getList();
this.$modal.msgSuccess("删除成功");
}).catch(() => {
}).finally(() => {
this.loading = false;
});
},
/** 导出按钮操作 */
handleExport() {
this.download('crm/salesObjection/export', {
...this.queryParams
}, `salesObjection_${new Date().getTime()}.xlsx`)
}
}
};
</script>

View File

@@ -0,0 +1,193 @@
<template>
<div class="order-operation-record">
<!-- 标题可选可根据需求删除或修改 -->
<div class="record-title">订单操作记录</div>
<!-- Element-UI 时间轴组件倒序展示最新操作在顶部 -->
<el-timeline reverse>
<!-- 循环渲染操作记录 -->
<el-timeline-item
v-for="(item, index) in operationList"
:key="index"
:timestamp="formatTime(item.createTime)"
placement="left"
>
<!-- 操作内容展示 -->
<div class="operation-item">
<div class="operation-type">
操作类型{{ getActionName(item.operationType) }}
</div>
<div class="operation-type">
操作人{{ item.createByName || '无' }}
</div>
<div class="operation-type">
操作时间{{ item.createTime || '无' }}
</div>
<!-- <div class="operation-content">
操作内容{{ formatOperationContent(item.operationContent) }}
</div> -->
<!-- <div class="operation-status">
操作后状态{{ item.newStatus || '无' }}
</div> -->
</div>
</el-timeline-item>
<!-- 无数据占位 -->
<div v-if="operationList.length === 0" class="empty-record">
暂无操作记录
</div>
</el-timeline>
</div>
</template>
<script>
import { listOrderOperationTrace } from '@/api/crm/orderOperationTrace';
import { ORDER_ACTIONS } from '@/views/crm/js/actions';
export default {
name: 'OrderRecord',
props: {
orderId: {
type: String,
default: ''
}
},
data() {
return {
// 操作记录列表
operationList: []
};
},
watch: {
// 监听orderId变化重新请求数据
orderId: {
immediate: true, // 初始化时立即执行
handler(newVal) {
if (newVal) {
this.getOperationRecord();
} else {
// 订单ID为空时清空列表
this.operationList = [];
}
}
}
},
methods: {
/**
* 获取订单操作记录列表
*/
async getOperationRecord() {
try {
// 构造查询参数pageSize设置为9999获取所有记录
const params = {
orderId: this.orderId,
pageNum: 1,
pageSize: 9999
};
// 请求操作记录数据(根据实际接口返回格式调整,此处假设接口返回{data: {records: []}}
const res = await listOrderOperationTrace(params);
// 赋值操作列表(根据接口实际返回结构调整,若直接返回数组则直接赋值 res.data
this.operationList = res.rows || [];
} catch (error) {
console.error('获取订单操作记录失败:', error);
this.operationList = [];
}
},
/**
* 格式化时间戳/时间字符串
* @param {String|Number} time - 原始时间
* @returns {String} 格式化后的时间
*/
formatTime(time) {
if (!time) return '未知时间';
// 简单格式化若需要更复杂格式可引入dayjs等库
const date = new Date(time);
return `${date.getFullYear()}-${(date.getMonth() + 1).toString().padStart(2, '0')}-${date.getDate().toString().padStart(2, '0')} ${date.getHours().toString().padStart(2, '0')}:${date.getMinutes().toString().padStart(2, '0')}:${date.getSeconds().toString().padStart(2, '0')}`;
},
/**
* 根据操作类型映射操作名称
* @param {String} type - 操作类型对应ORDER_ACTIONS的key
* @returns {String} 友好的操作名称
*/
getActionName(type) {
// 先定义操作类型与中文名称的映射关系
const actionNameMap = {
[ORDER_ACTIONS.createPreOrder]: '创建预订单',
[ORDER_ACTIONS.updatePreOrder]: '修改预订单',
[ORDER_ACTIONS.cancelPreOrder]: '取消预订单',
[ORDER_ACTIONS.approvePreOrder]: '审批预订单',
[ORDER_ACTIONS.createOrder]: '创建正式订单',
[ORDER_ACTIONS.updateOrder]: '修改正式订单',
[ORDER_ACTIONS.createOrderdetail]: '创建订单明细',
[ORDER_ACTIONS.updateOrderdetail]: '修改订单明细'
};
// 若不存在对应映射,返回原始类型
return actionNameMap[type] || type || '未知操作';
},
/**
* 格式化操作内容JSON字符串转易读格式
* @param {String} content - 原始操作内容JSON字符串
* @returns {String} 格式化后的内容
*/
formatOperationContent(content) {
if (!content) return '无';
try {
// 解析JSON字符串
const jsonData = JSON.parse(content);
// 转为带缩进的JSON字符串便于阅读
return JSON.stringify(jsonData, null, 2);
} catch (error) {
// 解析失败时返回原始内容
return content;
}
}
}
};
</script>
<style scoped>
.order-operation-record {
width: 100%;
padding: 16px;
box-sizing: border-box;
}
.record-title {
font-size: 16px;
font-weight: 600;
margin-bottom: 16px;
color: #303133;
}
.operation-item {
padding: 12px;
background-color: #f8f9fa;
border-radius: 4px;
border-left: 3px solid #409eff;
}
.operation-type {
color: #303133;
font-weight: 500;
margin-bottom: 8px;
}
.operation-content {
color: #606266;
margin-bottom: 8px;
word-break: break-all;
white-space: pre-wrap; /* 保留JSON格式化后的换行和缩进 */
}
.operation-status {
color: #606266;
}
.empty-record {
text-align: center;
padding: 20px;
color: #909399;
font-size: 14px;
}
</style>

View File

@@ -0,0 +1,402 @@
<template>
<div>
<!-- <el-form v-if="searchable" :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
<el-form-item label="客户名称" prop="customerId">
<CustomerSelect v-model="queryParams.customerId" />
</el-form-item>
<el-form-item label="到期日" prop="dueDate">
<el-date-picker clearable
v-model="queryParams.dueDate"
type="date"
value-format="yyyy-MM-dd"
placeholder="请选择到期日">
</el-date-picker>
</el-form-item>
<el-form-item>
<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-form-item>
</el-form> -->
<el-descriptions :column="3" title="财务状态" border>
<el-descriptions-item label="订单总金额">{{ order.orderAmount }}</el-descriptions-item>
<el-descriptions-item label="已收款金额">{{ receivedAmount }}</el-descriptions-item>
<el-descriptions-item label="未收款金额">{{ unreceivedAmount }}</el-descriptions-item>
</el-descriptions>
<el-descriptions title="收款明细"></el-descriptions>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
type="primary"
plain
icon="el-icon-plus"
size="mini"
@click="handleAdd"
>新增</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="success"
plain
icon="el-icon-edit"
size="mini"
:disabled="single"
@click="handleUpdate"
>修改</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="danger"
plain
icon="el-icon-delete"
size="mini"
:disabled="multiple"
@click="handleDelete"
>删除</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="warning"
plain
icon="el-icon-download"
size="mini"
@click="handleExport"
>导出</el-button>
</el-col>
<right-toolbar v-if="searchable" :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
<KLPTable v-loading="loading" :data="receivableList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="应收ID" align="center" prop="receivableId" v-if="false"/>
<!-- <el-table-column label="客户" align="center" prop="customerName" /> -->
<el-table-column label="到期日" align="center" prop="dueDate" width="180">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.dueDate, '{y}-{m}-{d}') }}</span>
<el-tag v-if="new Date(scope.row.dueDate) < new Date()" type="danger">过期</el-tag>
<el-tag v-else-if="new Date(scope.row.dueDate) > new Date()" type="success">还剩{{ parseInt((new Date(scope.row.dueDate) - new Date()) / (1000 * 60 * 60 * 24)) }}</el-tag>
</template>
</el-table-column>
<el-table-column label="应收金额" align="center" prop="amount" />
<!-- <el-table-column label="已收金额" align="center" prop="paidAmount" /> -->
<!-- <el-table-column label="未收金额" align="center" prop="balanceAmount" /> -->
<!-- <el-table-column label="状态" align="center" prop="status" /> -->
<el-table-column label="备注" align="center" prop="remark" />
<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="handleUpdate(scope.row)"
>修改</el-button>
<el-button
size="mini"
type="text"
icon="el-icon-delete"
@click="handleDelete(scope.row)"
>删除</el-button>
<!-- <el-button
size="mini"
type="text"
icon="el-icon-money"
@click="handleReceive(scope.row)"
></el-button> -->
</template>
</el-table-column>
</KLPTable>
<pagination
v-show="total>0"
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
<!-- 添加或修改应收款管理宽松版对话框 -->
<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="dueDate">
<el-date-picker clearable
v-model="form.dueDate"
type="datetime"
value-format="yyyy-MM-dd HH:mm:ss"
placeholder="请选择到期日">
</el-date-picker>
</el-form-item>
<el-form-item label="收款金额" prop="amount">
<el-input-number :controls=false v-model="form.amount" :step="1.00" :precision="2" placeholder="请输入应收金额" :min="0" :max="unreceivedAmount" style="width: 100%;"/>
</el-form-item>
<!-- <el-form-item label="已收金额" prop="paidAmount">
<el-input v-model="form.paidAmount" disabled placeholder="请输入已收金额" />
</el-form-item> -->
<!-- <el-form-item label="未收金额" prop="balanceAmount">
<el-input v-model="form.balanceAmount" placeholder="请输入未收金额" />
</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>
<el-dialog title="收款" :visible.sync="receiveOpen" width="500px" append-to-body>
<el-form ref="receiveForm" :model="receiveForm" :rules="rules" label-width="80px">
<el-form-item label="收款金额" prop="amount">
<el-input-number :controls=false v-model="receiveForm.amount" :step="1.00" :precision="2" placeholder="请输入收款金额" :min="0" :max="receiveForm.balanceAmount" style="width: 100%;"/>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button :loading="buttonLoading" type="primary" @click="submitReceiveForm"> </el-button>
<el-button @click="cancelReceive"> </el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import { listReceivable, getReceivable, delReceivable, addReceivable, updateReceivable, updatePaidAmount } from "@/api/finance/receivable";
// import CustomerSelect from '@/components/KLPService/CustomerSelect/index.vue';
export default {
name: "Receivable",
// components: {
// CustomerSelect
// },
props: {
searchable: {
type: Boolean,
default: true
},
order: {
type: Object,
default: undefined
}
},
computed: {
orderId() {
return this.order ? this.order.orderId : undefined;
},
customerId() {
return this.order ? this.order.customerId : undefined;
},
receivedAmount() {
return this.receivableList.reduce((total, item) => total + parseFloat(item.amount), 0);
},
unreceivedAmount() {
// return this.order ? this.order.totalAmount - this.order.receivedAmount : 0;
return this.order ? this.order.orderAmount - this.receivedAmount : 0;
},
},
watch: {
orderId: {
handler(newVal) {
if (newVal) {
this.queryParams.orderId = newVal;
this.getList();
}
},
immediate: true,
}
},
data() {
return {
// 按钮loading
buttonLoading: false,
// 遮罩层
loading: true,
// 选中数组
ids: [],
// 非单个禁用
single: true,
// 非多个禁用
multiple: true,
// 显示搜索条件
showSearch: true,
// 总条数
total: 0,
// 应收款管理(宽松版)表格数据
receivableList: [],
// 弹出层标题
title: "",
// 是否显示弹出层
open: false,
// 查询参数
queryParams: {
pageNum: 1,
pageSize: 20,
customerId: undefined,
orderId: undefined,
orderCode: undefined,
dueDate: undefined,
amount: undefined,
paidAmount: undefined,
balanceAmount: undefined,
status: undefined,
},
// 表单参数
form: {},
// 表单校验
rules: {
},
// 收款表单参数
receiveForm: {},
// 是否显示收款弹出层
receiveOpen: false
};
},
created() {
this.getList();
},
methods: {
/** 查询应收款管理(宽松版)列表 */
getList() {
this.loading = true;
listReceivable(this.queryParams).then(response => {
this.receivableList = response.rows;
this.total = response.total;
this.loading = false;
});
},
// 取消按钮
cancel() {
this.open = false;
this.reset();
},
// 表单重置
reset() {
this.form = {
receivableId: undefined,
customerId: this.customerId,
orderId: this.orderId,
dueDate: undefined,
amount: undefined,
paidAmount: 0,
balanceAmount: undefined,
status: undefined,
delFlag: undefined,
remark: undefined,
createTime: undefined,
createBy: undefined,
updateTime: undefined,
updateBy: undefined
};
this.resetForm("form");
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1;
this.getList();
},
/** 重置按钮操作 */
resetQuery() {
this.resetForm("queryForm");
this.handleQuery();
},
// 多选框选中数据
handleSelectionChange(selection) {
this.ids = selection.map(item => item.receivableId)
this.single = selection.length!==1
this.multiple = !selection.length
},
/** 新增按钮操作 */
handleAdd() {
this.reset();
this.open = true;
this.title = "添加应收款管理(宽松版)";
},
/** 修改按钮操作 */
handleUpdate(row) {
this.loading = true;
this.reset();
const receivableId = row.receivableId || this.ids
getReceivable(receivableId).then(response => {
this.loading = false;
this.form = response.data;
this.open = true;
this.title = "修改应收款管理";
});
},
/** 提交按钮 */
submitForm() {
this.$refs["form"].validate(valid => {
if (valid) {
this.buttonLoading = true;
if (this.form.receivableId != null) {
const {balanceAmount, ...payload} = this.form;
updateReceivable(payload).then(response => {
this.$modal.msgSuccess("修改成功");
this.open = false;
this.getList();
}).finally(() => {
this.buttonLoading = false;
});
} else {
addReceivable(this.form).then(response => {
this.$modal.msgSuccess("新增成功");
this.open = false;
this.getList();
}).finally(() => {
this.buttonLoading = false;
});
}
}
});
},
/** 删除按钮操作 */
handleDelete(row) {
const receivableIds = row.receivableId || this.ids;
this.$modal.confirm('是否确认删除应收款管理编号为"' + receivableIds + '"的数据项?').then(() => {
this.loading = true;
return delReceivable(receivableIds);
}).then(() => {
this.loading = false;
this.getList();
this.$modal.msgSuccess("删除成功");
}).catch(() => {
}).finally(() => {
this.loading = false;
});
},
/** 导出按钮操作 */
handleExport() {
this.download('klp/receivable/export', {
...this.queryParams
}, `receivable_${new Date().getTime()}.xlsx`)
},
// 收款按钮操作
handleReceive(row) {
this.receiveForm = {
receivableId: row.receivableId,
amount: row.balanceAmount,
balanceAmount: row.balanceAmount
};
this.receiveOpen = true;
},
// 取消收款按钮操作
cancelReceive() {
this.receiveOpen = false;
this.receiveForm = {};
},
submitReceiveForm() {
const payload = {
receivableId: this.receiveForm.receivableId,
paidAmount: this.receiveForm.amount,
balanceAmount: this.receiveForm.balanceAmount - this.receiveForm.amount
}
this.buttonLoading = true;
updatePaidAmount(payload).then(response => {
this.$modal.msgSuccess("收款成功");
this.receiveOpen = false;
this.getList();
}).finally(() => {
this.buttonLoading = false;
});
}
}
};
</script>

View File

@@ -1,4 +1,19 @@
import { addOrder, updateOrder } from '@/api/crm/order'
import { addOrderItem, updateOrderItem } from '@/api/crm/orderItem'
import { ORDER_STATUS, PRE_ORDER_STATUS, ORDER_TYPE } from './enum'
import { addOrderOperationTrace } from '@/api/crm/orderOperationTrace'
// 需要被记录的操作
const ORDER_ACTIONS = {
createPreOrder: 'createPreOrder',
updatePreOrder: 'updatePreOrder',
approvePreOrder: 'approvePreOrder',
createOrder: 'createOrder',
updateOrder: 'updateOrder',
createOrderdetail: 'createOrderdetail',
updateOrderdetail: 'updateOrderdetail',
}
const actions = {
// 创建预订单
createPreOrder: {
@@ -6,21 +21,150 @@ const actions = {
name: '创建预订单',
description: '创建一个预订单',
// 预订单的相关信息
async handler(payload, ) {
async handler(payload) {
const { data: order } = await addOrder({
...payload,
})
if (order.orderId) {
addOrderOperationTrace({
orderId: order.orderId,
operationType: ORDER_ACTIONS.createPreOrder,
newStatus: order.orderId,
operationContent: JSON.stringify(payload)
})
}
return order
}
},
// 修改预订单
updatePreOrder: {
type: 'updatePreOrder',
name: '修改预订单',
description: '修改预订单的相关信息',
// 预订单的相关信息
async handler(payload) {
await updateOrder({
...payload,
})
// 预订单明细变更
addOrderOperationTrace({
orderId: payload.orderId,
operationType: ORDER_ACTIONS.updatePreOrder,
newStatus: payload.orderId,
operationContent: JSON.stringify(payload)
})
// 预订单取消
return payload
}
},
// 创建订单明细
createOrderdetail: {
type: 'createOrderdetail',
name: '创建订单明细',
description: '创建订单明细的相关信息',
// 订单明细的相关信息
async handler(payload) {
const { data: orderItem } = await addOrderItem({
...payload,
})
if (orderItem.orderItemId) {
addOrderOperationTrace({
orderId: orderItem.orderId,
operationType: ORDER_ACTIONS.createOrderdetail,
newStatus: payload.orderItemId,
operationContent: JSON.stringify(payload)
})
}
return orderItem
}
},
// 修改订单明细
updateOrderdetail: {
type: 'updateOrderdetail',
name: '修改订单明细',
description: '修改订单明细的相关信息',
// 订单明细的相关信息
async handler(payload) {
await updateOrderItem({
...payload,
})
addOrderOperationTrace({
orderId: payload.orderId,
operationType: ORDER_ACTIONS.updateOrderdetail,
newStatus: payload.orderItemId,
operationContent: JSON.stringify(payload)
})
return payload
}
},
// 预订单审批为正式订单
approvePreOrder: {
type: 'approvePreOrder',
name: '审批预订单',
description: '审批预订单为正式订单',
// 预订单的相关信息
async handler(payload) {
await updateOrder({
...payload,
})
if (payload.orderId) {
addOrderOperationTrace({
orderId: payload.orderId,
operationType: ORDER_ACTIONS.approvePreOrder,
newStatus: payload.orderId,
operationContent: JSON.stringify(payload)
})
}
return payload
}
},
// 直接创建正式订单
createOrder: {
type: 'createOrder',
name: '创建正式订单',
description: '直接创建一个正式订单',
// 正式订单的相关信息
async handler(payload) {
const { data: order } = await addOrder({
...payload,
})
if (order.orderId) {
addOrderOperationTrace({
orderId: order.orderId,
operationType: ORDER_ACTIONS.createOrder,
newStatus: order.orderId,
operationContent: JSON.stringify(payload)
})
}
return order
}
},
// 正式订单修改
updateOrder: {
type: 'updateOrder',
name: '修改正式订单',
description: '修改正式订单的相关信息',
// 正式订单的相关信息
async handler(payload) {
await updateOrder({
...payload,
})
if (payload.orderId) {
addOrderOperationTrace({
orderId: payload.orderId,
operationType: ORDER_ACTIONS.updateOrder,
newStatus: payload.orderId,
operationContent: JSON.stringify(payload)
})
}
return payload
}
}
}
// 正式订单明细修改
export {
ORDER_ACTIONS,
actions,
}

View File

@@ -65,23 +65,25 @@
<el-tab-pane label="财务状态" name="finance">
<div class="order-finance" v-if="activeTab === 'finance'">
<!-- 财务状态内容 -->
<ReceiveTable :order="currentOrder" />
</div>
</el-tab-pane>
<el-tab-pane label="订单异议" name="dispute">
<div class="order-dispute" v-if="activeTab === 'dispute'">
<!-- 订单异议内容 -->
<OrderObjection :order="currentOrder" />
</div>
</el-tab-pane>
<el-tab-pane label="操作记录" name="record">
<div class="order-record" v-if="activeTab === 'record'">
<!-- 操作记录内容 -->
<OrderRecord :orderId="currentOrder.orderId" />
</div>
</el-tab-pane>
<el-tab-pane label="钢卷追溯" name="trace">
<!-- <el-tab-pane label="钢卷追溯" name="trace">
<div class="order-trace" v-if="activeTab === 'trace'">
<!-- 钢卷追溯内容 -->
</div>
</el-tab-pane>
</el-tab-pane> -->
</el-tabs>
</el-col>
</el-row>
@@ -126,16 +128,22 @@
import KLPList from '@/components/KLPUI/KLPList/index.vue'
import { listOrder, addOrder, delOrder, updateOrder } from "@/api/crm/order";
import { listCustomer } from "@/api/crm/customer";
import { ORDER_STATUS, ORDER_TYPE } from '../js/enum'
import { ORDER_STATUS, ORDER_TYPE, ORDER_ACTIONS, actions } from '../js/enum'
import OrderDetail from '../components/OrderDetail.vue';
import OrderEdit from '../components/OrderEdit.vue';
import OrderObjection from '../components/OrderObjection.vue';
import ReceiveTable from '../components/ReceiveTable.vue';
import OrderRecord from '../components/OrderRecord.vue';
export default {
name: 'OrderPage',
components: {
KLPList,
OrderDetail,
OrderEdit
OrderEdit,
OrderObjection,
ReceiveTable,
OrderRecord
},
dicts: ['customer_level', 'customer_industry'],
data() {
@@ -262,7 +270,7 @@ export default {
/** 提交按钮 */
async submitForm() {
if (this.form.orderId) {
updateOrder(this.form).then(_ => {
actions[ORDER_ACTIONS.updateOrder].handler(this.form).then(_ => {
this.$modal.msgSuccess("修改成功");
this.open = false;
this.getList();
@@ -274,7 +282,7 @@ export default {
this.$refs["form"].validate(valid => {
if (valid) {
this.buttonLoading = true;
addOrder(this.form).then(_ => {
actions[ORDER_ACTIONS.createOrder].handler(this.form).then(_ => {
this.$modal.msgSuccess("新增成功");
this.open = false;
this.getList();

View File

@@ -168,6 +168,7 @@ import { listOrder, getOrder, delOrder, addOrder, updateOrder } from "@/api/crm/
import { listCustomer } from "@/api/crm/customer";
import OrderDetailList from '@/views/crm/components/OrderDetail.vue'
import { ORDER_TYPE } from "../js/enum";
import { ORDER_ACTIONS, actions } from "../js/actions";
export default {
name: "Order",
@@ -259,7 +260,7 @@ export default {
cancelButtonText: "取消",
type: "warning"
}).then(() => {
updateOrder({
actions[ORDER_ACTIONS.approvePreOrder].handler({
...row,
orderType: ORDER_TYPE['正式订单'],
}).then(response => {
@@ -335,7 +336,7 @@ export default {
if (valid) {
this.buttonLoading = true;
if (this.form.orderId != null) {
updateOrder(this.form).then(response => {
actions[ORDER_ACTIONS.updatePreOrder].handler(this.form).then(() => {
this.$modal.msgSuccess("修改成功");
this.open = false;
this.getList();
@@ -343,7 +344,7 @@ export default {
this.buttonLoading = false;
});
} else {
addOrder(this.form).then(response => {
actions[ORDER_ACTIONS.createPreOrder].handler(this.form).then(() => {
this.$modal.msgSuccess("新增成功");
this.open = false;
this.getList();

View File

@@ -0,0 +1,10 @@
const liens = [
{
name: '镀锌线',
url: '140.143.206.120:18081'
},
{
name: '酸连轧',
url: ''
}
]

View File

@@ -18,46 +18,45 @@
</template>
<script>
import { getConfigKey } from '@/api/system/config'
import Plan from './panels/plan/index.vue'
// import Plan from './panels/plan/index.vue'
import Track from './panels/track/index.vue'
import Quality from './panels/quality/index.vue'
import Stop from './panels/stop/index.vue'
import PdoAnalysis from './panels/analysis/pdo.vue'
import StopAnalysis from './panels/analysis/stop.vue'
import RollerAnalysis from './panels/analysis/roller.vue'
// import Quality from './panels/quality/index.vue'
// import Stop from './panels/stop/index.vue'
// import PdoAnalysis from './panels/analysis/pdo.vue'
// import StopAnalysis from './panels/analysis/stop.vue'
// import RollerAnalysis from './panels/analysis/roller.vue'
export default {
name: 'Lines',
components: {
Plan,
// Plan,
Track,
Quality,
Stop,
PdoAnalysis,
StopAnalysis,
RollerAnalysis
// Quality,
// Stop,
// PdoAnalysis,
// StopAnalysis,
// RollerAnalysis
},
data() {
return {
activeName: 'Track',
baseURL: '140.143.206.120:18081',
ready: false,
ready: true,
tabs: []
}
},
created() {
// 获取路由地址的最后一项
const route = this.$route.path.split('/').pop()
getConfigKey(`line.${route}.config`).then(res => {
const tabs = res.msg.split(',')
// 是否包含Track, 如果不包含则添加
if (!tabs.includes('Track')) {
tabs.push('Track')
}
this.tabs = tabs
})
}
// created() {
// // 获取路由地址的最后一项
// const route = this.$route.path.split('/').pop()
// getConfigKey(`line.${route}.config`).then(res => {
// const tabs = res.msg.split(',')
// // 是否包含Track, 如果不包含则添加
// if (!tabs.includes('Track')) {
// tabs.push('Track')
// }
// this.tabs = tabs
// })
// }
}
</script>