完善BOM单据

This commit is contained in:
龙运模 2024-12-01 21:43:59 +08:00
parent fce26e7766
commit c77131aa5e
11 changed files with 407 additions and 24 deletions

View File

@ -280,6 +280,62 @@ export default {
return await http.post(this.url, data);
},
},
field:{
url: `${config.API_URL}/bom.field.list`,
name: "清单字段选择列表",
post: async function (data) {
return await http.post(this.url, data);
},
},
statusList:{
url: `${config.API_URL}/bom.status.const.list`,
name: "清单状态常量列表",
post: async function (data) {
return await http.post(this.url, data);
},
},
disabledStatus:{
url: `${config.API_URL}/bom.disabled.state.const.list`,
name: "清单禁用状态列表",
post: async function (data) {
return await http.post(this.url, data);
},
},
add:{
url: `${config.API_URL}/bom.add`,
name: "bom单条新增或者编辑",
post: async function (data) {
return await http.post(this.url, data);
},
},
delete:{
url: `${config.API_URL}/bom.delete`,
name: "bom删除",
post: async function (data) {
return await http.post(this.url, data);
},
},
enable:{
url: `${config.API_URL}/bom.enable`,
name: "bom启用/禁用",
post: async function (data) {
return await http.post(this.url, data);
},
},
import:{
url: `${config.API_URL}/bom.import`,
name: "BOM导入",
post: async function (params) {
return await http.post(this.url,params,{'Content-Type': 'multipart/form-data'});
}
},
template:{
url: `${config.API_URL}/bom.list.import.template`,
name: "bom导入模版",
post: async function (params) {
return await http.get(this.url,params,{responseType: 'arraybuffer'});
}
},
export:{
url: `${config.API_URL}/bom.export`,
name: "BOM导出",
@ -287,5 +343,6 @@ export default {
return await http.post(this.url,params);
}
},
}
};

View File

@ -108,7 +108,7 @@ export default {
},
methods:{
getWsResult(res){
if(res.data && (res.data.type == 4 || res.data.type == 5 || res.data.type == 10 || res.data.type == 17 || res.data.type == 18 || res.data.type == 28 || res.data.type == 31)){
if(res.data && (res.data.type == 4 || res.data.type == 5 || res.data.type == 10 || res.data.type == 17 || res.data.type == 18 || res.data.type == 28 || res.data.type == 31 || res.data.type == 42)){
this.importInfo = res.data;
this.progressShow = true;
if(res.data.status == 0){

View File

@ -54,7 +54,7 @@
</el-container>
</el-drawer>
</div>
<el-dropdown class="user userDropdown panel-item" trigger="click" @command="handleUser">
<el-dropdown ref="userDropdown" class="user userDropdown panel-item" trigger="click" @command="handleUser">
<div class="user-avatar">
<el-avatar :size="22" shape="circle" :src="this.$store.state.global.login_avatar"><span class="userName">{{ userNameF }}</span></el-avatar>
<label>{{ userName }}</label>
@ -157,6 +157,7 @@
}
},
linkUser(){
this.$refs.userDropdown.handleClose();
this.$router.push({ path: '/user/center' });
},
clearCache(){

View File

@ -4,7 +4,7 @@
<div class="leftBox">
<div class="item" v-for="(item,index) in inletList" :key="index" @click="linkDetail(item)">
<div class="img">
<el-icon size="30" color="#fff" class="icon" v-if="item.meta && item.meta.icon"><component :is="item.meta.icon || 'el-icon-menu'" /></el-icon>
<el-icon size="36" color="#fff" class="icon" v-if="item.meta && item.meta.icon"><component :is="item.meta.icon || 'el-icon-menu'" /></el-icon>
</div>
<text class="text">{{item.meta && item.meta.title}}</text>
</div>
@ -27,7 +27,7 @@
<template #item="{ element }">
<div class="box">
<div class="img">
<el-icon size="30" color="#fff" class="icon" v-if="element.meta && element.meta.icon"><component :is="element.meta.icon || 'el-icon-menu'" /></el-icon>
<el-icon size="36" color="#fff" class="icon" v-if="element.meta && element.meta.icon"><component :is="element.meta.icon || 'el-icon-menu'" /></el-icon>
</div>
<div class="text">{{element.meta && element.meta.title}}</div>
</div>
@ -41,7 +41,7 @@
<template #item="{ element }">
<div class="box">
<div class="img imgDis">
<el-icon size="30" color="#fff" class="icon" v-if="element.meta && element.meta.icon"><component :is="element.meta.icon || 'el-icon-menu'" /></el-icon>
<el-icon size="36" color="#fff" class="icon" v-if="element.meta && element.meta.icon"><component :is="element.meta.icon || 'el-icon-menu'" /></el-icon>
</div>
<div class="text">{{element.meta && element.meta.title}}</div>
</div>

View File

@ -2,7 +2,7 @@
<div class="pageBody">
<div class="rowView">
<div class="rowList">
<div class="colItem" v-for="(item,index) in list" :key="index">
<div class="colItem" v-for="(item,index) in list" :key="index" @click="linkDetail(item)">
<div class="cardView">
<el-icon size="56" v-if="item.icon"><component :is="item.icon"/></el-icon>
<div class="name">
@ -13,7 +13,7 @@
<div class="describe">
<el-icon size="56" v-if="item.icon"><component :is="item.icon"/></el-icon>
<div class="name">
占位占位占位
{{item.text}}
<el-icon class="icon" size="30"><sc-icon-ArrowRightServe/></el-icon>
</div>
</div>
@ -36,6 +36,7 @@
<script>
import footerPage from "@/views/serveView/components/footerPage";
import {eventBus} from "@/utils/eventBus";
export default {
name: "mainView",
components:{
@ -44,13 +45,22 @@ export default {
data(){
return{
list:[
{name:"技术支持与服务",icon:"sc-icon-TechnicalSupport",url:''},
{name:"常见问题",icon:"sc-icon-Problem",url:''},
{name:"咨询与联系方式",icon:"sc-icon-SeekAdviceFrom",url:''},
{name:"其他",icon:"sc-icon-OtherServe",url:''},
{name:"技术支持与服务",icon:"sc-icon-TechnicalSupport",url:'serveView',page:"term", text:"维保支持与服务包括故障修复、定期检查、软件更新及技术支持"},
{name:"常见问题",icon:"sc-icon-Problem",url:'personalCenter',page:"queryHistory",text:"常见问题包括响应延迟、故障频发、配件缺货及技术支持不足,影响服务效率"},
{name:"咨询与联系方式",icon:"sc-icon-SeekAdviceFrom",url:'personalCenter',page:"problem",text:'提供电话、邮件支持,设立在线客服,确保快速响应客户需求与咨询'},
{name:"其他",icon:"sc-icon-OtherServe",url:'personalCenter',page:"editAccount",text:'涵盖预防性维护、性能优化、培训服务及远程监控,全面提升系统可靠性'},
],
recommendList:[],
historyList:[]
historyList:[],
//
recommendRouter:[
{method:"customerWorkOrderMyList",name:"personalCenter",page:"feedback",text:"我的工单列表"},
{method:"userInformation",name:"personalCenter",page:"editAccount",text:"用户中心"},
{method:"maintenancePeriodQuery",name:"serveView",page:"term",text:"维保期限"},
{method:"myQuery",name:"personalCenter",page:"queryHistory",text:"我的查询记录"},
{method:"customerWorkOrderSubmit",name:"personalCenter",page:"problem",text:"提交问题工单"},
]
}
},
activated() {
@ -67,6 +77,18 @@ export default {
},
methods:{
linkDetail(item){
eventBus.$emit('headerRouterBack',{name:item.url});
if(item.url === 'serveView'){
this.$nextTick(()=>{
eventBus.$emit('queryBack',{name:item.page});
})
}else{
this.$nextTick(()=>{
eventBus.$emit('userBack',{name:item.page});
})
}
},
getCreateBubble(item){
const containerWidth = this.$refs.bubble.offsetWidth;
const containerHeight = this.$refs.bubble.offsetHeight;
@ -84,6 +106,23 @@ export default {
bubble.style.maxHeight = '38px';
bubble.style.background = this.getRandomColor();
bubble.innerText =`${item.description}`;
bubble.addEventListener('click', () => {
this.recommendRouter.forEach(em=>{
if(em.method === item.method){
eventBus.$emit('headerRouterBack',{name:em.name});
if(em.name === 'serveView'){
this.$nextTick(()=>{
eventBus.$emit('queryBack',{name:em.page});
})
}else{
this.$nextTick(()=>{
eventBus.$emit('userBack',{name:em.page});
})
}
}
})
});
return bubble
},
getRandomColor() {

View File

@ -1,11 +1,17 @@
<template>
<el-container>
<el-header class="serveTitle">维保期限信息查询</el-header>
<el-header class="serveTitle">查找历史记录</el-header>
<el-main class="serveMain">
<div class="searchMain searchMainNoTop">
<div class="searchItem">
<div class="name">关键字</div><el-input class="textInput" type="text" v-model="keyword" :size="size" clearable placeholder="请输入"></el-input>
</div>
<div class="searchItem">
<div class="name">查询类型</div>
<el-select class="textInput" type="text" v-model="params.type.value" :size="size" clearable placeholder="请选择">
<el-option :value="item.value" :label="item.label" v-for="(item,index) in setMap.typeList" :key="index"></el-option>
</el-select>
</div>
<div class="searchItem searchBtn">
<el-button :size="size" type="primary" icon="el-icon-search" @click="upSearch">查询</el-button>
</div>
@ -14,7 +20,7 @@
<scTable class="serveTable" ref="table" :apiObj="list.apiObj" :column="list.column" :params="params" stripe :size="size">
<el-table-column type="index" label="序号"></el-table-column>
<template v-for="(item,index) in list.column" :key="index">
<el-table-column :label="item.label" :prop="item.prop" :width="item.width" show-overflow-tooltip>
<el-table-column :label="item.label" :prop="item.prop" :width="item.width" >
<template #default="scope">
<span v-if="item.prop === 'type'">
<span v-for="(em,index) in setMap.typeList" :key="index">
@ -43,8 +49,8 @@ export default {
list:{
apiObj: this.$API.customer.customerMyQuery,
column:[
{label:'问题类型',prop:'type',width:140,hide: false},
{label:'问题内容',prop:'content',hide: false},
{label:'查询类型',prop:'type',width:140,hide: false},
{label:'查询内容',prop:'content',width:1000,hide: false},
{label:'日期',prop:'created_at',width:200,hide: false},
],
},
@ -57,6 +63,10 @@ export default {
content:{
operator:"like",
value:""
},
type:{
operator:"=",
value:""
}
}
}
@ -67,7 +77,11 @@ export default {
methods:{
upSearch(){
for(let i in this.params){
if(i!='type'){
this.params[i].value = this.keyword===""?"":"%"+this.keyword+"%";
}else{
this.params[i].value = this.params[i].value?this.params[i].value:"";
}
}
this.$refs.table.upData(this.params);
},

View File

@ -92,7 +92,6 @@ export default {
},
methods:{
getQueryBack(res){
console.log(res,366)
this.$nextTick(()=>{
this.page = res.name;
})

View File

@ -62,7 +62,6 @@
</div>
</template>
</el-dropdown>
</div>
</div>
</div>

View File

@ -41,7 +41,7 @@ export default {
statusList:[]
},
list:{
apiObj: this.$API.customer.periodQuery,
apiObj: {},
column:[
{label:'序列号',prop:'serial_number',width:160,hide: false},
{label:'工单号',prop:'repair_order_no',width:200,hide: false},
@ -66,6 +66,7 @@ export default {
for(let i in this.params){
this.params[i].value = this.keyword===""?"":"%"+this.keyword+"%";
}
this.list.apiObj = this.$API.customer.periodQuery;
this.$refs.table.upData(this.params);
},
async getStatusList() {

View File

@ -2,7 +2,15 @@
<el-container class="mainBox mainHeaderNoBorderPadding">
<el-header>
<div class="left-panel">
<el-button type="primary" :size="size" icon="el-icon-plus" @click="add">新增BOM</el-button>
<el-button type="primary" v-auth="'addBom'" :size="size" icon="el-icon-plus" @click="add">新增BOM</el-button>
<scImport ref="scImport" :size="size" title="批量导入BOM" @parentParams="importUpload" @importSuccess="importSuccess">
<template #header>
<el-button v-auth="'bomImport'" type="primary" :size="size" plain @click="importFile">批量导入</el-button>
</template>
<template #download>
<div v-auth="'bomListImportTemplate'" @click="importTemplate">下载导入模版</div>
</template>
</scImport>
</div>
<div class="right-panel">
<scExport :size="size" @exportData="exportData" @updateShow="exportChangeShow" :show="exportShow" type="33">
@ -23,18 +31,39 @@
<scTable ref="table" :apiObj="list.apiObj" :column="list.column" row-key="id" stripe :size="size" @selection-change="selectionChange">
<el-table-column type="selection" align="center" width="40"></el-table-column>
<sc-table-column label="序号" align="center" type="index"></sc-table-column>
<template #disable_status="scope">
<el-switch :size="size" v-model="scope.row.disable_status" @change="changeSwitch($event, scope.row)" :loading="scope.row.$switch_status" :active-value="true" :inactive-value="false"></el-switch>
</template>
<el-table-column label="操作" fixed="right" align="center" width="160">
<template #default="scope">
<el-dropdown>
<el-button class="noBorderBtn" icon="el-icon-more" :size="size"></el-button>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item @click="table_show(scope.row, 'show')" icon="sc-icon-See">查看</el-dropdown-item>
<div v-auth="'updateMe'">
<el-dropdown-item @click="table_edit(scope.row, 'edit')" icon="sc-icon-Edit">编辑</el-dropdown-item>
</div>
<div v-auth="'deleteBom'">
<el-dropdown-item @click="table_del(scope.row, 'delete')" icon="sc-icon-Delete">删除</el-dropdown-item>
</div>
</el-dropdown-menu>
</template>
</el-dropdown>
</template>
</el-table-column>
</scTable>
</el-main>
</el-container>
<save-dialog v-if="dialog.save" ref="saveDialog" @success="handleSuccess" @closed="dialog.save=false"></save-dialog>
</template>
<script>
import saveDialog from './save'
export default {
name:"bom",
components: {
saveDialog
},
data() {
return {
@ -95,6 +124,35 @@ export default {
this.params = params;
},
//
importFile(){
this.$nextTick(()=>{
this.$refs.scImport.importFile();
})
},
async importTemplate() {
const res = await this.$API.setup.bom.template.post();
const blob = new Blob([res]);
const text = new Date().getTime();
const eLink = document.createElement('a');
eLink.download = "BOM导入模版_"+text+'.xlsx';
eLink.style.display = 'none';
eLink.href = URL.createObjectURL(blob);
document.body.appendChild(eLink);
eLink.click();
URL.revokeObjectURL(eLink.href);
document.body.removeChild(eLink);
},
async importUpload(params) {
const res = await this.$API.setup.bom.import.post(params);
if(res.code == 200){
this.$message.success('上传成功,开始导入数据');
}
},
importSuccess(){
this.$refs.table.refresh()
},
//
add(){
this.dialog.save = true;
@ -117,6 +175,9 @@ export default {
this.$refs.showDialog.open('show').setData(row);
})
},
handleSuccess(){
this.$refs.table.refresh();
},
//
async table_del(row){
this.$confirm(`确定删除 ${row.name} 吗?`, '提示', {
@ -132,6 +193,9 @@ export default {
}
}).catch(()=>{})
},
changeSwitch(){
},
//
selectionChange(selection){

View File

@ -0,0 +1,209 @@
<template>
<el-dialog :title="titleMap[mode]" v-model="visible" :width="500" draggable destroy-on-close @closed="$emit('closed')">
<el-scrollbar max-height="500" style="padding: 0 20px;">
<el-form class="form" :model="form" :rules="rules" :disabled="mode=='show'" ref="dialogForm" label-width="100px" label-position="right">
<el-form-item label="BOM版本" prop="login_name">
<el-input v-model="form.login_name" placeholder="请填写登录账号" :disabled="mode!='add'?true:false" clearable></el-input>
<p class="el-form-item-msg" v-if="mode == 'edit'">账号信息用于登录系统不允许修改</p>
</el-form-item>
<el-form-item label="BOM简称" prop="password" v-if="mode == 'add'">
<el-input type="password" v-model="form.password" placeholder="请填写密码" clearable show-password></el-input>
</el-form-item>
<el-form-item label="BOM分类" prop="company_full_name">
<el-select v-model="form.company_full_name" placeholder="请填写公司名称" clearable>
<el-option v-for="(item,index) in companyList" :key="index" :label="item.full_name" :value="item.full_name"></el-option>
</el-select>
</el-form-item>
<el-form-item label="BOM用途" prop="mobile">
<el-input v-model="form.mobile" placeholder="请填写联系电话" clearable></el-input>
</el-form-item>
<el-form-item label="父项物料编码" prop="email">
<el-input v-model="form.email" placeholder="请填写电子邮件" clearable></el-input>
</el-form-item>
<el-form-item label="父项物料民称" prop="email">
<el-input v-model="form.email" placeholder="请填写电子邮件" clearable></el-input>
</el-form-item>
<el-form-item label="父项物料单位" prop="email">
<el-input v-model="form.email" placeholder="请填写电子邮件" clearable></el-input>
</el-form-item>
<el-form-item label="子项物料编码" prop="email">
<el-input v-model="form.email" placeholder="请填写电子邮件" clearable></el-input>
</el-form-item>
<el-form-item label="子项物料民称" prop="email">
<el-input v-model="form.email" placeholder="请填写电子邮件" clearable></el-input>
</el-form-item>
<el-form-item label="子项物料单位" prop="email">
<el-input v-model="form.email" placeholder="请填写电子邮件" clearable></el-input>
</el-form-item>
<el-form-item label="次项" prop="email">
<el-input v-model="form.email" placeholder="请填写电子邮件" clearable></el-input>
</el-form-item>
<el-form-item label="子项类型" prop="email">
<el-input v-model="form.email" placeholder="请填写电子邮件" clearable></el-input>
</el-form-item>
<el-form-item label="用量分子" prop="email">
<el-input v-model="form.email" placeholder="请填写电子邮件" clearable></el-input>
</el-form-item>
<el-form-item label="用量分母" prop="email">
<el-input v-model="form.email" placeholder="请填写电子邮件" clearable></el-input>
</el-form-item>
</el-form>
</el-scrollbar>
<template #footer>
<el-button @click="visible=false" > </el-button>
<el-button v-if="mode!='show'" type="primary" :loading="isSave" @click="submit()"> </el-button>
</template>
</el-dialog>
</template>
<script>
export default {
emits: ['success', 'closed'],
data() {
return {
mode: "add",
titleMap: {
add: '新增BOM',
edit: '编辑BOM',
show: '查看'
},
visible: false,
isSave: false,
//
form: {
id:"",
login_name: "",
name:"",
emp_id:"",
mobile:"",
email:"",
avatar: "",
password:"",
dept_id: "",
role_ids: [],
company_full_name:""
},
//
rules: {
avatar:[
{required: false, message: '请上传头像'}
],
login_name: [
{required: true, message: '请输入登录账号'}
],
name: [
{required: true, message: '请输入昵称'}
],
emp_id:[
{required: true, message: '请输入工号'}
],
mobile: [
{required: true, message: '请输入联系方式'}
],
email: [
{required: true, message: '请输入邮箱地址'}
],
password: [
{required: true, message: '请输入登录密码'},
{validator: (rule, value, callback) => {
if (this.form.password2 !== '') {
this.$refs.dialogForm.validateField('password2');
}
callback();
}}
],
password_cnf: [
{required: true, message: '请再次输入密码'},
{validator: (rule, value, callback) => {
if (value !== this.form.password) {
callback(new Error('两次输入密码不一致!'));
}else{
callback();
}
}}
],
dept_id: [
{required: false, message: '请选择所属分组'}
],
role_ids: [
{required: true, message: '请选择所属角色', trigger: 'change'}
]
},
companyList:[]
}
},
mounted() {
this.getCompanyList();
},
methods: {
async getCompanyList() {
let params = {
field:"full_name",
id:{
operator:"in",
value:[]
}
}
const res = await this.$API.system.user.userCompanyField.post(params);
if(res.code == 200){
this.companyList = res.data;
}
},
//
open(mode='add'){
this.mode = mode;
this.visible = true;
return this
},
parentParams(item){
this.form.avatar = item;
},
//
submit(){
this.$refs.dialogForm.validate(async (valid) => {
if (valid) {
this.isSave = true;
const res = await this.$API.setup.bom.add.post(this.form);
this.isSave = false;
if(res.code == 200){
this.$emit('success', this.form, this.mode)
this.visible = false;
this.$message.success("操作成功")
}
}else{
return false;
}
})
},
//
setData(data){
this.form.id = data.id
this.form.login_name = data.login_name
this.form.name = data.name
this.form.emp_id = data.emp_id
this.form.mobile = data.mobile
this.form.email = data.email
this.form.avatar = data.avatar
this.form.dept_id = data.dept_id
this.form.group = data.group
this.form.role_ids = data.user_roles && data.user_roles.role_ids?data.user_roles.role_ids:[]
this.form.company_full_name = data.company_info?data.company_info.full_name:''
}
}
}
</script>
<style lang="scss" scoped>
.form{
.cardBoxForm{
border-bottom: 1px solid #f7f7f7;
.title{
padding: 15px 0 8px 18px;
font-weight: bold;
}
}
.cardBoxForm:last-child{
border-bottom: 0;
}
}
</style>