This commit is contained in:
磷叶 2024-12-26 18:03:22 +08:00
parent a61704bc5c
commit 88b3a77770
17 changed files with 876 additions and 154 deletions

1
.gitignore vendored
View File

@ -21,3 +21,4 @@ selenium-debug.log
package-lock.json
yarn.lock
dist.zip

10
jsconfig.json Normal file
View File

@ -0,0 +1,10 @@
{
"compilerOptions": {
"baseUrl": "./",
"paths": {
"@/*": ["src/*"]
}
},
"include": ["src/**/*"],
"exclude": ["node_modules"]
}

View File

@ -29,7 +29,7 @@ export default {
},
placeholder: {
type: String,
default: '选择部门'
default: '选择车间'
},
disabled: {
type: Boolean,

View File

@ -25,7 +25,6 @@
readonly
:placeholder="placeholder">
<template #suffix>
<el-tag type="primary" size="mini" v-if="!isEmpty(tagName)">负责工序{{tagName}}</el-tag>
<i class="el-icon-arrow-right"/>
</template>
</el-input>

View File

@ -16,6 +16,8 @@
:file-list="fileList"
:on-preview="handlePictureCardPreview"
:class="{hide: this.fileList.length >= this.limit}"
class="image-upload"
:style="cssVars"
>
<i class="el-icon-plus"></i>
</el-upload>
@ -67,6 +69,14 @@ export default {
isShowTip: {
type: Boolean,
default: true
},
width: {
type: String,
default: "148px"
},
height: {
type: String,
default: "148px"
}
},
data() {
@ -115,6 +125,12 @@ export default {
showTip() {
return this.isShowTip && (this.fileType || this.fileSize);
},
cssVars() {
return {
'--width': this.width,
'--height': this.height
}
}
},
methods: {
// loading
@ -208,17 +224,58 @@ export default {
};
</script>
<style scoped lang="scss">
// .el-upload--picture-card
::v-deep.hide .el-upload--picture-card {
display: none;
}
//
::v-deep .el-list-enter-active,
::v-deep .el-list-leave-active {
transition: all 0s;
/* 上传区域基础样式 */
::v-deep .el-upload {
display: flex;
justify-content: center;
align-items: center;
}
::v-deep .el-list-enter, .el-list-leave-active {
/* 上传按钮样式 */
::v-deep .el-upload--picture-card {
width: var(--width);
height: var(--height);
}
/* 隐藏上传按钮 */
::v-deep.hide .el-upload--picture-card {
display: none;
}
/* 已上传图片项样式 */
::v-deep .el-upload-list__item {
width: var(--width);
height: var(--height);
}
/* 图片操作按钮容器 */
::v-deep .el-upload-list__item-actions {
display: flex;
justify-content: space-between;
align-items: center;
text-align: center;
padding: 0 10%;
.el-upload-list__item-preview {
flex: 1;
text-align: center;
}
.el-upload-list__item-delete {
flex: 1;
margin-left: 0;
text-align: center;
}
}
/* 移除列表动画效果 */
::v-deep .el-list-enter-active,
::v-deep .el-list-leave-active {
transition: all 0s;
}
::v-deep .el-list-enter,
.el-list-leave-active {
opacity: 0;
transform: translateY(0);
}

View File

@ -1,11 +1,25 @@
<template>
<el-table-column class="table-form-col" align="center" :width="width" :show-overflow-tooltip="showOverflowTooltip">
<el-table-column class="table-form-col" :align="align" :width="width" :show-overflow-tooltip="showOverflowTooltip">
<template #header>
<span :class="required ? 'required-label' : ''">{{label}}</span>
<el-tooltip v-if="!isEmpty(tips)" :content="tips" placement="top">
<i class="el-icon-question" style="cursor: pointer;"/>
</el-tooltip>
</template>
<template scope="d">
<form-col table label-width="0" :prop="colProp(d.$index)" :rules="rules">
<slot :row="d.row"/>
<el-popover
v-if="showOverflowTooltip"
placement="top"
width="250"
trigger="hover">
<slot name="content-tip" :row="d.row" :index="d.$index"/>
<template #reference>
<slot :row="d.row" :index="d.$index"/>
</template>
</el-popover>
<slot v-else :row="d.row" :index="d.$index"/>
</form-col>
</template>
</el-table-column>
@ -20,6 +34,10 @@ export default {
name: "TableFormCol",
components: { HoverShow, FormCol },
props: {
align: {
type: String,
default: "center"
},
label: {
type: String,
default: null,
@ -47,6 +65,10 @@ export default {
showOverflowTooltip: {
type: Boolean,
default: false,
},
tips: {
type: String,
default: null,
}
},
computed: {
@ -58,6 +80,9 @@ export default {
return `${this.propPrefix}[${index}].${this.prop}`;
}
}
},
methods: {
isEmpty,
}
}
</script>

View File

@ -5,6 +5,10 @@ export const OrderStatus = {
// 允许编辑
canEdit() {
return [this.PROPOSED, this.RELEASED];
},
// 允许发布
canRelease() {
return [this.PROPOSED];
},
// 允许完工

View File

@ -1,9 +1,5 @@
<template>
<div>
<!-- <el-row class="edit-table-operate">-->
<!-- <el-button size="small" icon="el-icon-plus" type="text" @click="handleAdd" >新增工序</el-button>-->
<!-- </el-row>-->
<el-table
:data="value"
size="mini"
@ -11,31 +7,18 @@
class="mini-table"
>
<el-table-column align="center" label="序号" width="50" type="index"/>
<table-form-col label="生产车间" :prop-prefix="propPrefix" prop="deptId" required :rules="rules.deptId">
<table-form-col label="生产车间" :prop-prefix="propPrefix" prop="deptId" required :rules="rules.deptId" width="250">
<dept-input slot-scope="d" v-model="d.row.deptId"/>
</table-form-col>
<table-form-col label="数量" :prop-prefix="propPrefix" prop="num" required :rules="rules.num">
<table-form-col label="数量" :prop-prefix="propPrefix" prop="num" required :rules="rules.num" width="250">
<el-input-number slot-scope="d" v-model="d.row.num" :min="0" controls-position="right" style="width: 100%"/>
</table-form-col>
<table-form-col label="最终工序" :prop-prefix="propPrefix" prop="isEnd" width="100">
<el-checkbox slot-scope="d" v-model="d.row.isEnd" />
<table-form-col label="最终工序" :prop-prefix="propPrefix" prop="isEnd" width="100" tips="最终工序,表示该工序是产品的最终工序,每个产品有且仅有一个最终工序">
<el-checkbox slot-scope="d" :value="d.row.isEnd" @change="handleIsEndChange(d.index)"/>
</table-form-col>
<table-form-col label="处理方式" :prop-prefix="propPrefix" prop="handleWay">
<el-input slot-scope="d" v-model="d.row.handleWay" placeholder="请输入处理方式"/>
<table-form-col label="备注" :prop-prefix="propPrefix" prop="remark">
<el-input slot-scope="d" v-model="d.row.remark" placeholder="请输入备注" :maxlength="200" show-word-limit />
</table-form-col>
<table-form-col label="效果" :prop-prefix="propPrefix" prop="effect">
<el-input slot-scope="d" v-model="d.row.effect" placeholder="请输入效果"/>
</table-form-col>
<table-form-col label="颜色" :prop-prefix="propPrefix" prop="color">
<el-input slot-scope="d" v-model="d.row.color" placeholder="请输入颜色"/>
</table-form-col>
<table-form-col label="盖子颜色" :prop-prefix="propPrefix" prop="coverColor">
<el-input slot-scope="d" v-model="d.row.coverColor" placeholder="请输入盖子颜色"/>
</table-form-col>
<!-- <table-form-col label="排序" :prop-prefix="propPrefix" prop="sort" width="80">-->
<!-- <template slot-scope="d">{{d.row.sort}}</template>-->
<!-- </table-form-col>-->
<el-table-column label="操作" align="center" width="160">
<template #header>
<el-button size="small" icon="el-icon-plus" type="text" @click="handleAdd" >新增工序</el-button>
@ -95,6 +78,10 @@ export default {
propPrefix: {
type: String,
default: null,
},
prod: {
type: Object,
default: () => ({})
}
},
data () {
@ -109,6 +96,12 @@ export default {
}
},
methods: {
//
handleIsEndChange(index) {
this.value.forEach((item, idx) => {
item.isEnd = idx === index;
})
},
//
handleAdd() {
this.showDeptDialog = true;
@ -123,12 +116,8 @@ export default {
id: null,
orderProdId: null,
deptId: dept.deptId,
num: null,
num: this.prod.num,
isEnd: false,
handleWay: null,
effect: null,
color: null,
coverColor: null,
remark: null,
sort: this.getNewSort(),
});

View File

@ -1,9 +1,5 @@
<template>
<div>
<!-- <el-row class="edit-table-operate">-->
<!-- <el-button size="small" plain icon="el-icon-plus" type="success" @click="handleAdd" >新增产品</el-button>-->
<!-- </el-row>-->
<el-table
:data="form.prodList"
size="mini"
@ -14,22 +10,23 @@
<el-table-column type="expand" width="50" align="left">
<template slot-scope="d">
<div class="expand-container">
<prod-process-list v-model="d.row.processList" :prop-prefix="`prodList[${d.$index}].processList`" :rules="rules.processList"/>
<prod-process-list v-model="d.row.processList" :prop-prefix="`prodList[${d.$index}].processList`" :rules="rules.processList" :prod="d.row"/>
</div>
</template>
</el-table-column>
<el-table-column type="index" width="50" align="center" label="序号"/>
<table-form-col label="主图" prop-prefix="prodList" prop="picture" width="200">
<table-form-col label="主图" prop-prefix="prodList" prop="picture" width="80" >
<template slot-scope="d">
<hover-show>
<template #show>
<image-preview :src="d.row.picture" :width="50" :height="50"/>
</template>
<image-upload v-model="d.row.picture" :limit="1" :is-show-tip="false"/>
<image-upload v-model="d.row.picture" :limit="1" :is-show-tip="false" width="50px" height="50px"/>
</hover-show>
</template>
</table-form-col>
<table-form-col label="名称" prop-prefix="prodList" prop="name" required :rules="rules.name">
<table-form-col label="名称" prop-prefix="prodList" prop="name" required :rules="rules.name" show-overflow-tooltip>
<template v-slot:content-tip="d">{{d.row.name}}</template>
<el-input slot-scope="d" v-model="d.row.name" placeholder="请输入名称"/>
</table-form-col>
<table-form-col label="数量" prop-prefix="prodList" prop="num" required :rules="rules.num">
@ -41,21 +38,35 @@
</el-select>
</table-form-col>
<table-form-col label="物料编码" prop-prefix="prodList" prop="materialNo">
<template v-slot:content-tip="d">{{d.row.materialNo}}</template>
<el-input slot-scope="d" v-model="d.row.materialNo" placeholder="请输入物料编码"/>
</table-form-col>
<table-form-col label="规格" prop-prefix="prodList" prop="spec">
<table-form-col label="规格" prop-prefix="prodList" prop="spec" show-overflow-tooltip>
<template v-slot:content-tip="d">{{d.row.spec}}</template>
<el-input slot-scope="d" v-model="d.row.spec" placeholder="请输入规格"/>
</table-form-col>
<table-form-col label="成品" prop-prefix="prodList" prop="isEnd" width="80">
<el-checkbox slot-scope="d" v-model="d.row.isEnd" />
<table-form-col label="成品" prop-prefix="prodList" prop="isEnd" width="80" tips="成品,表示该产品是成品,订单有且仅有一个成品">
<el-checkbox slot-scope="d" :value="d.row.isEnd" @change="handleIsEndChange(d.index)"/>
</table-form-col>
<!-- <table-form-col label="排序" prop-prefix="prodList" prop="sort" width="80">-->
<!-- <template slot-scope="d">{{d.row.sort}}</template>-->
<!-- </table-form-col>-->
<table-form-col label="备注" prop-prefix="prodList" prop="remark">
<template slot-scope="d">
<el-input v-model="d.row.remark" placeholder="请输入备注" maxlength="200" show-word-limit type="textarea"/>
</template>
<table-form-col label="处理方式" prop-prefix="prodList" prop="handleWay" show-overflow-tooltip>
<template v-slot:content-tip="d">{{d.row.handleWay}}</template>
<el-input slot-scope="d" v-model="d.row.handleWay" placeholder="请输入处理方式"/>
</table-form-col>
<table-form-col label="效果" prop-prefix="prodList" prop="effect" show-overflow-tooltip>
<template v-slot:content-tip="d">{{d.row.effect}}</template>
<el-input slot-scope="d" v-model="d.row.effect" placeholder="请输入效果"/>
</table-form-col>
<table-form-col label="颜色" prop-prefix="prodList" prop="color" show-overflow-tooltip>
<template v-slot:content-tip="d">{{d.row.color}}</template>
<el-input slot-scope="d" v-model="d.row.color" placeholder="请输入颜色"/>
</table-form-col>
<table-form-col label="盖子颜色" prop-prefix="prodList" prop="coverColor" show-overflow-tooltip>
<template v-slot:content-tip="d">{{d.row.coverColor}}</template>
<el-input slot-scope="d" v-model="d.row.coverColor" placeholder="请输入盖子颜色"/>
</table-form-col>
<table-form-col label="备注" prop-prefix="prodList" prop="remark" show-overflow-tooltip>
<template v-slot:content-tip="d">{{d.row.remark}}</template>
<el-input slot-scope="d" v-model="d.row.remark" placeholder="请输入备注" maxlength="200" show-word-limit type="textarea"/>
</table-form-col>
<el-table-column label="操作" align="center" width="160">
@ -117,22 +128,33 @@ export default {
}
},
methods: {
//
handleIsEndChange(index) {
this.form.prodList.forEach((item, idx) => {
item.isEnd = idx === index;
})
},
//
handleAdd() {
this.form.prodList.push(this.getNewRow())
this.reorder();
},
//
getNewRow() {
return {
name:null,
materialNo:null,
picture:null,
spec:null,
num: null,
num: this.form.num,
remark:null,
isEnd: false,
workType: "1",
sort: this.getNewSort(),
handleWay: null,
effect: null,
color: null,
coverColor: null,
processList: [],
}
},

View File

@ -1,8 +1,8 @@
<template>
<div v-loading="loading">
<edit-header :title="title">
<el-button type="primary" plain @click="submitForm(false)" icon="el-icon-check" size="small">保存</el-button>
<el-button type="primary" @click="submitForm(true)" icon="el-icon-s-check" size="small">保存并发布</el-button>
<el-button type="primary" plain @click="submitForm(false)" icon="el-icon-check" size="small">保存</el-button>
<el-button type="primary" @click="submitForm(true)" icon="el-icon-s-check" size="small" v-if="OrderStatus.canRelease().includes(form.status)">保存并发布</el-button>
</edit-header>
<div class="app-container">
@ -12,17 +12,26 @@
<form-col :span="span" label="主图" prop="picture">
<image-upload v-model="form.picture" :limit="1"/>
</form-col>
<form-col :span="span" label="订单编号" prop="orderNo">
<el-input v-model="form.orderNo" placeholder="请输入订单编号"/>
</form-col>
<form-col :span="span" label="订单日期" prop="orderDate">
<el-date-picker v-model="form.orderDate" type="date" value-format="yyyy-MM-dd" placeholder="选择日期" :clearable="false" style="width: 100%;"/>
</form-col>
<form-col :span="span" label="交货日期" prop="deliveryDate">
<el-date-picker v-model="form.deliveryDate" type="date" value-format="yyyy-MM-dd" placeholder="选择日期" :clearable="false" style="width: 100%;"/>
</form-col>
<form-col :span="span" label="数量" prop="num">
<el-input-number v-model="form.num" :min="0" controls-position="right" style="width: 100%;"/>
</form-col>
<form-col :span="span" label="客户" prop="customer">
<el-input v-model="form.customer" placeholder="请输入客户"/>
</form-col>
<form-col :span="span * 3" label="备注" prop="remark">
<el-input v-model="form.remark" type="textarea" placeholder="请输入备注" :maxlength="1000" show-word-limit :autosize="{minRows: 3, maxRows: 10}"/>
<form-col :span="span" label="数量" prop="num">
<el-input-number v-model="form.num" :min="0" controls-position="right" style="width: 100%;"/>
</form-col>
<form-col :span="span" label="用料" prop="material">
<el-input v-model="form.material" placeholder="请输入用料"/>
</form-col>
<form-col :span="span * 3" label="特殊要求" prop="remark">
<el-input v-model="form.remark" type="textarea" placeholder="请输入特殊要求" :maxlength="1000" show-word-limit :autosize="{minRows: 3, maxRows: 10}"/>
</form-col>
</el-row>
@ -42,12 +51,15 @@ import EditHeader from '@/components/EditHeader/index.vue'
import { addOrder, getOrder, updateOrder } from '@/api/bst/order'
import FormCol from '@/components/FormCol/index.vue'
import OrderProdList from '@/views/bst/order/edit/components/orderProdList.vue'
import { parseTime } from '@/utils/ruoyi'
import { OrderStatus } from '@/utils/enums'
export default {
name: "OrderEdit",
components: { OrderProdList, FormCol, EditHeader },
data() {
return {
OrderStatus,
title: null,
form: {},
loading: false,
@ -57,6 +69,12 @@ export default {
num: [
{ required: true, message: "数量不能为空", trigger: "blur" }
],
orderDate: [
{ required: true, message: "订单日期不能为空", trigger: "blur" }
],
orderNo: [
{ required: true, message: "订单编号不能为空", trigger: "blur" }
],
prodList: {
name: [
{ required: true, message: "产品名称不能为空", trigger: "blur" }
@ -111,9 +129,8 @@ export default {
createBy: null,
createTime: null,
deleted: null,
prodList: [
this.$refs.orderProdList.getNewRow()
]
orderDate: parseTime(new Date(), '{y}-{m}-{d}'),
prodList: []
};
this.resetForm("form");
},
@ -138,6 +155,8 @@ export default {
this.loading = false;
})
}
} else {
this.$modal.msgError("表单校验未通过,请检查");
}
});
},

View File

@ -27,6 +27,22 @@
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="用料" prop="material">
<el-input
v-model="queryParams.material"
placeholder="请输入用料"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="特殊要求" prop="remark">
<el-input
v-model="queryParams.remark"
placeholder="请输入特殊要求"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="创建人" prop="createBy">
<el-input
v-model="queryParams.createBy"
@ -35,6 +51,30 @@
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="订单日期" prop="orderDateRange">
<el-date-picker
v-model="queryParams.orderDateRange"
type="daterange"
range-separator="至"
start-placeholder="开始日期"
end-placeholder="结束日期"
value-format="yyyy-MM-dd"
@change="handleQuery"
clearable
/>
</el-form-item>
<el-form-item label="交货日期" prop="deliveryDateRange">
<el-date-picker
v-model="queryParams.deliveryDateRange"
type="daterange"
range-separator="至"
start-placeholder="开始日期"
end-placeholder="结束日期"
value-format="yyyy-MM-dd"
@change="handleQuery"
clearable
/>
</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>
@ -176,8 +216,10 @@ export default {
{key: 'status', visible: true, label: '订单状态', minWidth: null, sortable: true, overflow: false, align: 'center', width: null},
{key: 'picture', visible: true, label: '主图', minWidth: null, sortable: false, overflow: false, align: 'center', width: null},
{key: 'customer', visible: true, label: '客户', minWidth: null, sortable: true, overflow: false, align: 'center', width: null},
{key: 'orderDate', visible: true, label: '订单日期', minWidth: null, sortable: true, overflow: false, align: 'center', width: null},
{key: 'deliveryDate', visible: true, label: '交货日期', minWidth: null, sortable: true, overflow: false, align: 'center', width: null},
{key: 'remark', visible: true, label: '备注', minWidth: null, sortable: true, overflow: true, align: 'center', width: null},
{key: 'material', visible: true, label: '用料', minWidth: null, sortable: true, overflow: true, align: 'center', width: null},
{key: 'remark', visible: true, label: '特殊要求', minWidth: null, sortable: true, overflow: true, align: 'center', width: null},
{key: 'num', visible: true, label: '数量', minWidth: null, sortable: true, overflow: false, align: 'center', width: null},
{key: 'reportNum', visible: true, label: '已上报', minWidth: null, sortable: false, overflow: false, align: 'center', width: null},
{key: 'storeNum', visible: true, label: '已清点', minWidth: null, sortable: false, overflow: false, align: 'center', width: null},
@ -217,7 +259,9 @@ export default {
customer: null,
remark: null,
createBy: null,
deleted: null
deleted: null,
orderDateRange: [],
deliveryDateRange: []
},
};
},

View File

@ -9,10 +9,12 @@
<dict-tag :options="dict.type.order_status" :value="detail.status" size="mini"/>
</el-descriptions-item>
<el-descriptions-item label="客户">{{ detail.customer | dv}}</el-descriptions-item>
<el-descriptions-item label="订单日期">{{ detail.orderDate | dv}}</el-descriptions-item>
<el-descriptions-item label="交货日期">{{ detail.deliveryDate | dv}}</el-descriptions-item>
<el-descriptions-item label="用料">{{ detail.material | dv}}</el-descriptions-item>
<el-descriptions-item label="特殊要求" :span="2">{{ detail.remark | dv}}</el-descriptions-item>
<el-descriptions-item label="创建人">{{ detail.createBy | dv}}</el-descriptions-item>
<el-descriptions-item label="创建时间">{{ detail.createTime | dv}}</el-descriptions-item>
<el-descriptions-item label="备注" :span="2">{{ detail.remark | dv}}</el-descriptions-item>
<el-descriptions-item label="数量">{{ detail.num | dv}}</el-descriptions-item>
<el-descriptions-item label="已上报">{{ detail.reportNum | dv}}</el-descriptions-item>
<el-descriptions-item label="已清点">{{ detail.storeNum | dv}}</el-descriptions-item>

View File

@ -50,6 +50,39 @@
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="处理方式" prop="handleWay">
<el-input
v-model="queryParams.handleWay"
placeholder="请输入处理方式"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="效果" prop="effect">
<el-input
v-model="queryParams.effect"
placeholder="请输入效果"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="颜色" prop="color">
<el-input
v-model="queryParams.color"
placeholder="请输入颜色"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="盖子颜色" prop="coverColor">
<el-input
v-model="queryParams.coverColor"
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>
@ -92,18 +125,6 @@
</el-row>
<el-table v-loading="loading" :data="orderProdList" @selection-change="handleSelectionChange" :default-sort="defaultSort" @sort-change="onSortChange">
<el-table-column type="expand" width="50" align="left" fixed="left">
<template slot-scope="d">
<div class="expand-container">
<prod-process
:custom-data="d.row.processList"
is-custom-data
:container-class="null"
:hide-columns="['id', 'orderNo', 'orderProdName']"
/>
</div>
</template>
</el-table-column>
<el-table-column type="selection" width="50" align="center" />
<template v-for="column of showColumns">
<el-table-column
@ -134,7 +155,12 @@
<boolean-tag :value="d.row.isEnd"/>
</template>
<template v-else-if="column.key === 'progress'">
<el-progress :percentage="d.row.progress" :color="ProgressColors" :format="ProgressFormat"/>
<el-popover :width="500" trigger="hover" placement="left">
<process-card-list :data="d.row.processList" />
<template #reference>
<el-progress :percentage="d.row.progress" :color="ProgressColors" :format="ProgressFormat" style="cursor: pointer;" />
</template>
</el-popover>
</template>
<template v-else>
{{d.row[column.key]}}
@ -142,24 +168,6 @@
</template>
</el-table-column>
</template>
<!-- <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)"-->
<!-- v-has-permi="['bst:orderProd:edit']"-->
<!-- >修改</el-button>-->
<!-- <el-button-->
<!-- size="mini"-->
<!-- type="text"-->
<!-- icon="el-icon-delete"-->
<!-- @click="handleDelete(scope.row)"-->
<!-- v-has-permi="['bst:orderProd:remove']"-->
<!-- >删除</el-button>-->
<!-- </template>-->
<!-- </el-table-column>-->
</el-table>
<pagination
@ -169,6 +177,8 @@
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
</div>
</template>
@ -180,6 +190,7 @@ import BooleanTag from '@/components/BooleanTag/index.vue'
import { ProgressColors, ProgressFormat } from '@/utils/constants'
import ProdProcess from '@/views/bst/prodProcess/index.vue'
import OrderLink from '@/components/Business/Order/OrderLink.vue'
import ProcessCardList from '@/views/bst/prodProcess/components/ProcessCardList.vue'
//
const defaultSort = {
@ -191,7 +202,7 @@ export default {
name: "OrderProd",
mixins: [$showColumns],
dicts: ['order_prod_work_type'],
components: { OrderLink, ProdProcess, BooleanTag, FormCol},
components: { OrderLink, ProdProcess, BooleanTag, FormCol, ProcessCardList},
props: {
query: {
type: Object,
@ -213,7 +224,7 @@ export default {
span: 24,
//
columns: [
{key: 'id', visible: true, label: 'ID', minWidth: null, sortable: true, overflow: false, align: 'center', width: "80"},
{key: 'id', visible: false, label: 'ID', minWidth: null, sortable: true, overflow: false, align: 'center', width: "80"},
{key: 'orderNo', visible: true, label: '订单', minWidth: null, sortable: true, overflow: false, align: 'center', width: null},
{key: 'picture', visible: true, label: '主图', minWidth: null, sortable: false, overflow: false, align: 'center', width: null},
{key: 'name', visible: true, label: '名称', minWidth: null, sortable: true, overflow: false, align: 'center', width: null},
@ -222,6 +233,10 @@ export default {
{key: 'spec', visible: true, label: '规格', minWidth: null, sortable: true, overflow: false, align: 'center', width: null},
{key: 'remark', visible: true, label: '备注', minWidth: null, sortable: true, overflow: true, align: 'center', width: null},
{key: 'isEnd', visible: true, label: '是否成品', minWidth: null, sortable: true, overflow: false, align: 'center', width: null},
{key: 'handleWay', visible: true, label: '处理方式', minWidth: null, sortable: true, overflow: false, align: 'center', width: null},
{key: 'effect', visible: true, label: '效果', minWidth: null, sortable: true, overflow: false, align: 'center', width: null},
{key: 'color', visible: true, label: '颜色', minWidth: null, sortable: true, overflow: false, align: 'center', width: null},
{key: 'coverColor', visible: true, label: '盖子颜色', minWidth: null, sortable: true, overflow: false, align: 'center', width: null},
{key: 'num', visible: true, label: '数量', minWidth: null, sortable: true, overflow: false, align: 'center', width: null},
{key: 'reportNum', visible: true, label: '已上报', minWidth: null, sortable: false, overflow: false, align: 'center', width: null},
{key: 'storeNum', visible: true, label: '已清点', minWidth: null, sortable: false, overflow: false, align: 'center', width: null},

View File

@ -0,0 +1,237 @@
<template>
<div class="process-card-list">
<el-card
v-for="(item, index) in data"
:key="index"
class="process-card"
:class="{ 'is-final': item.isEnd }"
>
<div class="process-card__header">
<div class="process-name">
<i class="el-icon-office-building"></i>
{{ item.deptName | dv}}
</div>
<div class="process-tags">
<el-tag v-if="item.isEnd" size="mini" type="success">最终工序</el-tag>
</div>
</div>
<div class="process-card__body">
<div class="progress-wrapper">
<el-progress
:percentage="item.progress"
:color="ProgressColors"
:format="ProgressFormat"
:stroke-width="8"
>
</el-progress>
</div>
</div>
<div class="process-card__info">
<div class="info-item">
<span class="label">计划数量:</span>
<span class="value">{{ item.num }}</span>
</div>
<div class="info-item">
<span class="label">已上报:</span>
<span class="value">{{ item.reportNum }}</span>
</div>
<div class="info-item">
<span class="label">已清点:</span>
<span class="value">{{ item.storeNum }}</span>
</div>
</div>
<div v-if="item.remark" class="process-card__remark">
<div class="remark-title">
<i class="el-icon-info"></i>{{ item.remark }}
</div>
</div>
</el-card>
</div>
</template>
<script>
import { ProgressColors, ProgressFormat } from '@/utils/constants'
export default {
name: 'ProcessCardList',
props: {
data: {
type: Array,
required: true
}
},
data() {
return {
ProgressColors,
}
},
methods: {
ProgressFormat,
}
}
</script>
<style scoped lang="scss">
.process-card-list {
max-height: 600px;
padding: 4px;
overflow-y: auto;
.process-card {
margin-bottom: 6px;
border-radius: 6px;
:deep(.el-card__body) {
padding: 10px 12px;
}
&.is-final {
border: 1px solid #67c23a;
}
&__header {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 8px;
.process-name {
font-size: 14px;
font-weight: bold;
color: #303133;
display: flex;
align-items: center;
gap: 6px;
.remark-icon {
font-size: 14px;
color: #909399;
cursor: help;
&:hover {
color: #409eff;
}
}
}
.process-tags {
flex-shrink: 0;
}
}
&__body {
display: flex;
align-items: center;
gap: 12px;
margin-bottom: 8px;
.workshop {
min-width: 90px;
color: #606266;
font-size: 12px;
display: flex;
align-items: center;
gap: 4px;
i {
margin-right: 4px;
}
.dept-process {
color: #909399;
font-size: 11px;
}
}
.progress-wrapper {
flex: 1;
:deep(.el-progress-bar__outer) {
background-color: #f5f7fa;
height: 6px !important;
}
}
}
&__info {
display: flex;
justify-content: space-between;
flex-wrap: wrap;
gap: 6px;
margin-bottom: 6px;
padding: 6px;
background: #f8f9fb;
border-radius: 4px;
.info-item {
font-size: 12px;
.label {
color: #909399;
margin-right: 4px;
}
.value {
color: #303133;
font-weight: 500;
}
}
}
&__remark {
margin-top: 6px;
padding: 6px 8px;
background: #fafafa;
border-radius: 4px;
.remark-title {
display: flex;
align-items: center;
gap: 3px;
color: #606266;
font-size: 12px;
margin-bottom: 4px;
i {
color: #909399;
font-size: 12px;
}
}
.remark-content {
color: #606266;
font-size: 13px;
line-height: 1.5;
white-space: pre-wrap;
word-break: break-all;
}
}
}
}
//
@media screen and (max-width: 768px) {
.process-card-list {
.process-card {
&__body {
flex-direction: column;
align-items: flex-start;
gap: 6px;
.workshop {
min-width: auto;
}
.progress-wrapper {
width: 100%;
}
}
&__info {
flex-direction: column;
gap: 4px;
}
}
}
}
</style>

View File

@ -0,0 +1,306 @@
<template>
<el-drawer
:visible.sync="visible"
width="500px"
@open="onOpen"
:with-header="false"
>
<div class="process-detail" v-loading="loading">
<!-- 顶部信息区 -->
<div class="section header-section">
<div class="order-info">
<div class="order-title">
<order-link :id="detail.orderId" :name="detail.orderNo" />
<dict-tag
:value="detail.orderStatus"
:options="dict.type.order_status"
/>
</div>
<div class="product-name">{{ detail.orderProdName }}</div>
</div>
<div class="images-area">
<div class="image-wrapper">
<image-preview
:src="detail.orderPicture"
:width="70"
:height="70"
class="image-item"
/>
<div class="image-label">订单图片</div>
</div>
<div class="image-wrapper">
<image-preview
:src="detail.orderProdPicture"
:width="70"
:height="70"
class="image-item"
/>
<div class="image-label">产品图片</div>
</div>
</div>
</div>
<!-- 工序进度区 -->
<div class="section process-section">
<div class="progress-title">
<span class="dept-name">{{ detail.deptName }}</span>
<el-tag type="success" v-if="detail.isEnd">最终工序</el-tag>
</div>
<el-progress
:percentage="detail.progress"
:color="ProgressColors"
:format="ProgressFormat"
class="progress-bar"
/>
<div class="progress-numbers">
<div class="number-item">
<div class="number">{{ detail.num | dv }}</div>
<div class="label">总数量</div>
</div>
<div class="number-item">
<div class="number">{{ detail.reportNum | dv }}</div>
<div class="label">已上报</div>
</div>
<div class="number-item">
<div class="number">{{ detail.storeNum | dv }}</div>
<div class="label">已清点</div>
</div>
</div>
</div>
<!-- 工艺参数区 -->
<div class="section params-section">
<div class="param-item" v-if="detail.handleWay">
<div class="param-label">处理方式</div>
<div class="param-value">{{detail.handleWay}}</div>
</div>
<div class="param-item" v-if="detail.effect">
<div class="param-label">效果</div>
<div class="param-value">{{detail.effect}}</div>
</div>
<div class="param-item" v-if="detail.color">
<div class="param-label">颜色</div>
<div class="param-value">{{detail.color}}</div>
</div>
<div class="param-item" v-if="detail.coverColor">
<div class="param-label">盖子颜色</div>
<div class="param-value">{{detail.coverColor}}</div>
</div>
<div class="param-item" v-if="detail.remark">
<div class="param-label">备注</div>
<div class="param-value">{{detail.remark}}</div>
</div>
</div>
<!-- 操作按钮区 -->
<div class="action-area">
<el-button type="primary">上报库存</el-button>
</div>
</div>
</el-drawer>
</template>
<script>
import { ProgressColors, ProgressFormat } from '@/utils/constants'
import OrderLink from '@/components/Business/Order/OrderLink'
import BooleanTag from '@/components/BooleanTag'
import { getProdProcess } from '@/api/bst/prodProcess'
export default {
name: 'ProdProcessDetail',
components: {
OrderLink,
BooleanTag
},
dicts: ['order_status'],
props: {
id: {
type: String,
default: null,
},
show: {
type: Boolean,
default: false,
}
},
data() {
return {
ProgressColors,
detail: {},
loading: false,
}
},
computed: {
visible: {
get() {
return this.show;
},
set(value) {
this.$emit('update:show', value);
}
}
},
methods: {
ProgressFormat,
onOpen() {
this.getDetail();
},
getDetail() {
this.loading = true;
getProdProcess(this.id).then(res => {
this.detail = res.data;
}).finally(() => {
this.loading = false;
});
}
}
}
</script>
<style lang="scss" scoped>
.process-detail {
padding: 16px;
background: #fff;
.section {
background: #fff;
border-radius: 8px;
padding: 16px;
margin-bottom: 16px;
box-shadow: 0 1px 4px rgba(0,0,0,0.05);
}
.header-section {
.order-info {
margin-bottom: 16px;
.order-title {
display: flex;
align-items: center;
gap: 8px;
margin-bottom: 8px;
}
.product-name {
font-size: 16px;
font-weight: bold;
color: #303133;
}
}
.images-area {
display: flex;
gap: 20px;
justify-content: center;
.image-wrapper {
text-align: center;
.image-item {
border-radius: 4px;
border: 1px solid #ebeef5;
}
.image-label {
margin-top: 8px;
font-size: 12px;
color: #909399;
}
}
}
}
.process-section {
background: #f5f7fa;
.progress-title {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 16px;
.dept-name {
font-size: 16px;
font-weight: bold;
color: #303133;
}
}
.progress-bar {
margin-bottom: 16px;
}
.progress-numbers {
display: flex;
justify-content: space-around;
text-align: center;
.number-item {
.number {
font-size: 20px;
font-weight: bold;
color: #409eff;
}
.label {
font-size: 12px;
color: #909399;
margin-top: 4px;
}
}
}
}
.params-section {
.param-item {
padding: 12px 16px;
display: flex;
align-items: flex-start;
border-bottom: 1px solid #f0f0f0;
&:last-child {
border-bottom: none;
}
.param-label {
width: 80px;
color: #909399;
font-size: 14px;
flex-shrink: 0;
}
.param-value {
flex: 1;
color: #303133;
font-size: 14px;
word-break: break-all;
}
}
}
.action-area {
padding: 16px 0;
border-top: 1px solid #ebeef5;
display: flex;
justify-content: center;
gap: 16px;
}
}
//
@media screen and (max-width: 768px) {
.process-detail {
padding: 12px;
.section {
padding: 12px;
}
.header-section {
.images-area {
gap: 12px;
}
}
}
}
</style>

View File

@ -24,24 +24,9 @@
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="生产车间" prop="deptId">
<el-form-item label="车间工序" prop="deptId">
<dept-tree-select v-model="queryParams.deptId" class="small-tree-select" @change="handleQuery"/>
</el-form-item>
<el-form-item label="负责工序" prop="deptProcess">
<el-input
v-model="queryParams.deptProcess"
placeholder="请输入负责工序"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="是否最终" prop="isEnd">
<el-radio-group v-model="queryParams.isEnd" @change="handleQuery">
<el-radio :label="null">全部</el-radio>
<el-radio :label="true"></el-radio>
<el-radio :label="false"></el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="处理方式" prop="handleWay">
<el-input
v-model="queryParams.handleWay"
@ -158,6 +143,9 @@
<template v-else-if="column.key === 'progress'">
<el-progress :percentage="d.row.progress" :color="ProgressColors" :format="ProgressFormat"/>
</template>
<template v-else-if="['orderPicture', 'orderProdPicture'].includes(column.key)">
<image-preview :src="d.row[column.key]" :width="50" :height="50"/>
</template>
<template v-else>
{{d.row[column.key]}}
</template>
@ -174,6 +162,13 @@
v-has-permi="['bst:store:add']"
v-show="OrderStatus.canAddStore().includes(scope.row.orderStatus)"
>上报入库</el-button>
<el-button
size="mini"
type="text"
icon="el-icon-view"
@click="handleView(scope.row)"
v-has-permi="['bst:prodProcess:query']"
>详情</el-button>
</template>
</el-table-column>
</el-table>
@ -187,6 +182,8 @@
/>
<store-edit-dialog :show.sync="showStoreEdit" :process-id="row.id" @success="getList"/>
<prod-process-detail :id="row.id" :show.sync="showDetail" />
</div>
</template>
@ -206,6 +203,7 @@ import DeptTreeSelect from '@/components/Business/Dept/DeptTreeSelect.vue'
import { ProgressColors, ProgressFormat } from '@/utils/constants'
import OrderLink from '@/components/Business/Order/OrderLink.vue'
import { OrderStatus } from '@/utils/enums'
import ProdProcessDetail from '@/views/bst/prodProcess/components/ProdProcessDetail.vue'
//
const defaultSort = {
@ -217,7 +215,7 @@ export default {
name: "ProdProcess",
dicts: ['order_status'],
mixins: [$showColumns],
components: { OrderLink, DeptTreeSelect, StoreEditDialog, BooleanTag, FormCol},
components: { OrderLink, DeptTreeSelect, StoreEditDialog, BooleanTag, FormCol, ProdProcessDetail},
props: {
//
customData: {
@ -238,23 +236,25 @@ export default {
return {
OrderStatus,
ProgressColors,
showDetail: false,
row: {},
showStoreEdit: false,
span: 24,
//
columns: [
{key: 'id', visible: true, label: 'ID', minWidth: null, sortable: true, overflow: false, align: 'center', width: "80"},
{key: 'id', visible: false, label: 'ID', minWidth: null, sortable: true, overflow: false, align: 'center', width: "80"},
{key: 'orderNo', visible: true, label: '订单', minWidth: null, sortable: true, overflow: false, align: 'center', width: null},
{key: 'orderStatus', visible: true, label: '订单状态', minWidth: null, sortable: true, overflow: false, align: 'center', width: null},
{key: 'orderPicture', visible: true, label: '订单主图', minWidth: null, sortable: false, overflow: false, align: 'center', width: null},
{key: 'orderStatus', visible: true, label: '状态', minWidth: null, sortable: true, overflow: false, align: 'center', width: null},
{key: 'orderProdName', visible: true, label: '产品', minWidth: null, sortable: true, overflow: false, align: 'center', width: null},
{key: 'deptName', visible: true, label: '车间', minWidth: null, sortable: true, overflow: false, align: 'center', width: null},
{key: 'deptProcess', visible: true, label: '工序', minWidth: null, sortable: true, overflow: false, align: 'center', width: null},
{key: 'handleWay', visible: true, label: '处理方式', minWidth: null, sortable: true, overflow: false, align: 'center', width: null},
{key: 'effect', visible: true, label: '效果', minWidth: null, sortable: true, overflow: false, align: 'center', width: null},
{key: 'color', visible: true, label: '颜色', minWidth: null, sortable: true, overflow: false, align: 'center', width: null},
{key: 'coverColor', visible: true, label: '盖子颜色', minWidth: null, sortable: true, overflow: false, align: 'center', width: null},
{key: 'remark', visible: true, label: '备注', minWidth: null, sortable: true, overflow: false, align: 'center', width: null},
{key: 'isEnd', visible: true, label: '是否最终', minWidth: null, sortable: true, overflow: false, align: 'center', width: null},
{key: 'orderProdPicture', visible: true, label: '产品主图', minWidth: null, sortable: false, overflow: false, align: 'center', width: null},
{key: 'deptName', visible: true, label: '工序', minWidth: null, sortable: true, overflow: false, align: 'center', width: null},
{key: 'handleWay', visible: true, label: '处理方式', minWidth: null, sortable: false, overflow: false, align: 'center', width: null},
{key: 'effect', visible: true, label: '效果', minWidth: null, sortable: false, overflow: false, align: 'center', width: null},
{key: 'color', visible: true, label: '颜色', minWidth: null, sortable: false, overflow: false, align: 'center', width: null},
{key: 'coverColor', visible: true, label: '盖子颜色', minWidth: null, sortable: false, overflow: false, align: 'center', width: null},
{key: 'remark', visible: true, label: '备注', minWidth: null, sortable: false, overflow: false, align: 'center', width: null},
{key: 'isEnd', visible: true, label: '最终', minWidth: null, sortable: true, overflow: false, align: 'center', width: null},
{key: 'num', visible: true, label: '数量', minWidth: null, sortable: true, overflow: false, align: 'center', width: null},
{key: 'reportNum', visible: true, label: '已上报', minWidth: null, sortable: false, overflow: false, align: 'center', width: null},
{key: 'storeNum', visible: true, label: '已清点', minWidth: null, sortable: false, overflow: false, align: 'center', width: null},
@ -336,6 +336,10 @@ export default {
}
},
methods: {
handleView(row) {
this.row = row;
this.showDetail = true;
},
ProgressFormat,
//
handleStore(row) {

View File

@ -1,16 +1,16 @@
<template>
<div class="app-container">
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch">
<el-form-item label="部门名称" prop="deptName">
<el-form-item label="车间名称" prop="deptName">
<el-input
v-model="queryParams.deptName"
placeholder="请输入部门名称"
placeholder="请输入车间名称"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="状态" prop="status">
<el-select v-model="queryParams.status" placeholder="部门状态" clearable @change="handleQuery">
<el-select v-model="queryParams.status" placeholder="请选择状态" clearable @change="handleQuery">
<el-option
v-for="dict in dict.type.sys_normal_disable"
:key="dict.value"
@ -19,14 +19,6 @@
/>
</el-select>
</el-form-item>
<el-form-item label="负责工序" prop="process">
<el-input
v-model="queryParams.process"
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>
@ -64,7 +56,7 @@
:default-expand-all="isExpandAll"
:tree-props="{children: 'children', hasChildren: 'hasChildren'}"
>
<el-table-column prop="deptName" label="部门名称"/>
<el-table-column prop="deptName" label="车间名称"/>
<el-table-column prop="orderNum" label="排序" width="100" align="center"/>
<el-table-column prop="status" label="状态" width="100" align="center">
<template slot-scope="scope">
@ -80,7 +72,6 @@
</template>
</template>
</el-table-column>
<el-table-column prop="process" label="负责工序" align="center"/>
<el-table-column label="创建时间" align="center" prop="createTime" width="180">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.createTime) }}</span>
@ -121,10 +112,10 @@
<form-col :span="span" label="上级部门" prop="parentId" v-if="form.parentId !== 0">
<treeselect v-model="form.parentId" :options="deptOptions" :normalizer="normalizer" placeholder="选择上级部门" />
</form-col>
<form-col :span="span" label="部门名称" prop="deptName">
<el-input v-model="form.deptName" placeholder="请输入部门名称" />
<form-col :span="span" label="名称" prop="deptName">
<el-input v-model="form.deptName" placeholder="请输入车间名称" />
</form-col>
<form-col :span="span" label="部门状态">
<form-col :span="span" label="状态">
<el-radio-group v-model="form.status">
<el-radio
v-for="dict in dict.type.sys_normal_disable"
@ -136,9 +127,6 @@
<form-col :span="span" label="显示排序" prop="orderNum">
<el-input-number v-model="form.orderNum" controls-position="right" :min="0" style="width: 100%" placeholder="请输入显示排序" />
</form-col>
<form-col :span="span" label="负责工序" prop="process">
<el-input v-model="form.process" placeholder="请输入负责工序" />
</form-col>
<form-col :span="span" label="负责人" prop="leaderId">
<user-input v-model="form.leaderIds" multiple/>
</form-col>
@ -280,7 +268,7 @@ export default {
this.form.parentId = row.deptId;
}
this.open = true;
this.title = "添加部门";
this.title = "添加车间";
listDept().then(response => {
this.deptOptions = this.handleTree(response.data, "deptId");
});
@ -299,7 +287,7 @@ export default {
getDept(row.deptId).then(response => {
this.form = response.data;
this.open = true;
this.title = "修改部门";
this.title = "修改车间";
listDeptExcludeChild(row.deptId).then(response => {
this.deptOptions = this.handleTree(response.data, "deptId");
if (this.deptOptions.length == 0) {