You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
926 lines
33 KiB
926 lines
33 KiB
<template> |
|
<div class="container" v-if="!loading"> |
|
<!-- 产品新增 --> |
|
<basic-crumb></basic-crumb> |
|
<div class="title">产品新增</div> |
|
<!-- ========== 新增:搜索区域 ========== --> |
|
<div class="english_box"> |
|
<div class="top_bottom"> |
|
<el-form ref="searchForm" :model="searchForm" label-width="160px" :rules="formRules"> |
|
<el-row> |
|
<el-col :span="8"> |
|
<el-form-item style="margin-right:5px;" label="产品名称:" prop="nameCn"> |
|
<el-input placeholder="产品名称" v-model="searchForm.nameCn"></el-input> |
|
</el-form-item> |
|
</el-col> |
|
<el-col :span="8"> |
|
<el-form-item style="margin-right:5px;" label="备注:" prop="bizRemark"> |
|
<el-input placeholder="备注" v-model="searchForm.bizRemark"></el-input> |
|
</el-form-item> |
|
</el-col> |
|
<el-col :span="8" style="display:flex;justify-content: flex-end;"> |
|
<el-button type="primary" @click="handleSearch" class="el-button--big">搜索</el-button> |
|
<el-button @click="handleReset" class="el-button--big" style="margin: 0 0 0 40px;">清空</el-button> |
|
</el-col> |
|
</el-row> |
|
|
|
</el-form> |
|
</div> |
|
</div> |
|
|
|
<div class="btn_box"> |
|
<div > |
|
<el-button type="primary" @click="addTable" class="el-button--big" style="margin: 0 40px 0 0px;">新增一行</el-button> |
|
<el-button type="danger" @click="delTable" class="el-button--big">批量删除</el-button> |
|
<!-- <el-button type="primary" @click="handleMatch">一键匹配</el-button> --> |
|
|
|
</div> |
|
<div> |
|
<el-button type="primary" @click="saveProduct" class="el-button--big">保存产品</el-button> |
|
<el-button @click="handleCancle" class="el-button--big" style="margin: 0 0 0 40px;">取消</el-button> |
|
</div> |
|
</div> |
|
<div class="table-wrapper"> |
|
<el-table :data="tableData" ref="multipleTable" height="100%" |
|
|
|
:style="{ width: '100%'}" @row-click="rowClick" border |
|
@selection-change="selectionChangeProject" @select="selectChange" @select-all="handleSelectAll" > |
|
<!-- type="selection" --> |
|
<el-table-column type="selection" width="80px" align="center"></el-table-column> |
|
<!-- <el-table-column align="center" width="55px" > |
|
<template slot-scope="scope"> |
|
<div @click="deleteColumn(scope.row, scope.$index)" |
|
style="width:30px;height: 30px;background: #f56c6c;border-radius: 50%;cursor: pointer;display: flex;align-items: center;justify-content: center;"> |
|
<i style="color:#fff;font-size: 20px;" class="el-icon-delete"></i> |
|
</div> |
|
</template> |
|
</el-table-column> --> |
|
<el-table-column label="#" type="index" width="70" align="center"></el-table-column> |
|
<el-table-column prop="code" label="编号" align="center" width="240"> |
|
<!-- <template #header> |
|
<span><i style="color:red">*</i>物料编号</span> |
|
</template> --> |
|
<template #default="scope"> |
|
<el-input v-model="scope.row.code" |
|
disabled |
|
/> |
|
<!-- :disabled="scope.row.bizType == 2 && (scope.row.id && !scope.row.isEditing)" --> |
|
</template> |
|
</el-table-column> |
|
<!-- 错误样式:填写了其他字段 + 无名称 + 校验触发 → 显示红色 --> |
|
<el-table-column prop="nameCn" label="产品名称" align="center"> |
|
<template #default="scope"> |
|
<el-input v-model="scope.row.nameCn" |
|
:placeholder="hasOtherFields(scope.row) && !scope.row.nameCn && showError ? '请输入产品名称' : ''" |
|
:class="{ 'is-error': hasOtherFields(scope.row) && !scope.row.nameCn && showError }" |
|
:disabled="scope.row.bizType == 2 || (scope.row.id && !scope.row.isEditing)" /> |
|
</template> |
|
</el-table-column> |
|
<el-table-column prop="specCn" label="规格说明" align="center"> |
|
<template #default="scope"> |
|
<el-input v-model="scope.row.specCn" |
|
:disabled="scope.row.bizType == 2 || (scope.row.id && !scope.row.isEditing)" /> |
|
</template> |
|
</el-table-column> |
|
<el-table-column prop="unitCn" label="单位" align="center" width="80"> |
|
<template #default="scope"> |
|
<el-input v-model="scope.row.unitCn" |
|
:disabled="scope.row.bizType == 2 || (scope.row.id && !scope.row.isEditing)" /> |
|
</template> |
|
</el-table-column> |
|
<el-table-column prop="multiple" label="倍率" align="center" width="80"> |
|
<template #default="scope"> |
|
<!-- <el-input-number style="width:90%" v-model="scope.row.multiple" controls-position="right" @change="handleChange" |
|
:min="1"></el-input-number> --> |
|
<el-input v-model="scope.row.multiple" @input="handleScale(scope.row.multiple, scope.$index)" |
|
:disabled="scope.row.bizType == 2 || (scope.row.id && !scope.row.isEditing)"></el-input> |
|
</template> |
|
</el-table-column> |
|
<el-table-column prop="standardPrice" label="公司指导价" align="center" width="200"> |
|
<template #default="scope"> |
|
<el-input v-model="scope.row.standardPrice" v-if="scope.row.bizType == 1 || !scope.row.bizType" |
|
@input="handlePrice(scope.row.standardPrice, scope.$index)" |
|
@focus="clickPrice(scope.row.standardPrice, scope.$index)" |
|
@blur="blurPrice(scope.row.standardPrice, scope.$index)" |
|
:disabled="scope.row.id && !scope.row.isEditing" ></el-input> |
|
|
|
<!-- 有指定业务员 --> |
|
<el-input v-model="scope.row.bizPrice" v-if="scope.row.bizType == 2" |
|
@input="handlePrice(scope.row.bizPrice, scope.$index)" |
|
@focus="clickBizPrice(scope.row.standardPrice, scope.$index)" |
|
@blur="blurBizPrice(scope.row.standardPrice, scope.$index)" |
|
:disabled="scope.row.id && !scope.row.isEditing" |
|
></el-input> |
|
<!-- <el-input-number style="width:90%" v-if="scope.row.bizType == 1 || !scope.row.bizType" v-model="scope.row.standardPrice" controls-position="right" @change="handleChange" |
|
:min="1"></el-input-number> |
|
<el-input-number style="width:90%" v-if="scope.row.bizType == 2" v-model="scope.row.bizPrice" controls-position="right" @change="handleChange" |
|
:min="1"></el-input-number> --> |
|
</template> |
|
</el-table-column> |
|
<el-table-column prop="remarkCn" label="备注" align="center"> |
|
<template #default="scope"> |
|
<el-input v-if="scope.row.bizType == 1 || !scope.row.bizType" v-model="scope.row.remarkCn" |
|
:disabled="scope.row.bizType == 2 || (scope.row.id && !scope.row.isEditing)"></el-input> |
|
<el-input v-if="scope.row.bizType == 2" v-model="scope.row.bizRemark" |
|
:disabled="scope.row.bizType == 2 "></el-input> |
|
</template> |
|
</el-table-column> |
|
<el-table-column fixed="right" label="操作" align="center" width="250"> |
|
<template slot-scope="scope"> |
|
<el-button type="text" size="small" @click="startEdit(scope.row)">编辑</el-button> |
|
<el-button type="text" size="small" v-if="scope.row.bizType != 2" |
|
@click="editProduct(scope.row)">编辑实物</el-button> |
|
<!-- v-if="isSuperAdmin" --> |
|
<el-button type="text" size="small" @click="changePeople(scope.row, scope.$index)" v-if="scope.row.bizType == 2">{{ |
|
scope.row.saleUserRealName}}</el-button> |
|
<el-button type="text" size="small" @click="changePeople(scope.row, scope.$index)" v-if="scope.row.bizType !== 2 && isSuperAdmin">指定业务员</el-button> |
|
</template> |
|
</el-table-column> |
|
</el-table> |
|
</div> |
|
<el-dialog append-to-body title="指定业务员" :visible.sync="addDialog" width="550px"> |
|
<el-form ref="addForm" :model="addForm" label-width="120px" :rules="formRules"> |
|
<el-form-item label="业务员:" prop="saleUserId"> |
|
<el-select v-model="addForm.saleUserId" placeholder="请选择业务员" @change="changeSale"> |
|
<el-option v-for="item in saleData" :key="item.id" :value="item.id" :label="item.realName"></el-option> |
|
</el-select> |
|
</el-form-item> |
|
<el-form-item label="客户:" prop="customerId"> |
|
<el-select v-model="addForm.customerId" placeholder="请选择客户"> |
|
<el-option v-for="item in customerData" :key="item.id" :value="item.id" |
|
:label="item.companyName"></el-option> |
|
</el-select> |
|
</el-form-item> |
|
</el-form> |
|
<template #footer> |
|
<span class="dialog-footer"> |
|
<el-button @click="addDialog = false">取 消</el-button> |
|
<el-button type="primary" @click="submit">确 定</el-button> |
|
</span> |
|
</template> |
|
</el-dialog> |
|
</div> |
|
</template> |
|
|
|
<script> |
|
import { getProduct, changeProduct, deleteProduct, getSaleList, getCustomer, changeUser, matchData, deletePrice } from '@/api/product/product'; |
|
import basicCrumb from "@/components/basic-crumb/main" |
|
import { mapGetters } from "vuex"; |
|
export default { |
|
components: { |
|
basicCrumb, |
|
}, |
|
data() { |
|
return { |
|
tableData: [], |
|
selectionProjectList: [], |
|
subcategoryId: '', |
|
addDialog: false, |
|
addForm: {}, |
|
formRules: { |
|
saleUserId: [{ required: true, message: '请选择业务员', trigger: 'blur' }], |
|
customerId: [{ required: true, message: '请选择客户', trigger: 'blur' }], |
|
}, |
|
saleData: [], |
|
customerData: [], |
|
originData: [], |
|
pickData: [], |
|
showError: false, |
|
searchForm: { |
|
// nameCn: '', // 产品名称 |
|
// bizRemark: '' // 备注 |
|
}, |
|
loading: true, |
|
currentOperateRowCode:null |
|
|
|
} |
|
}, |
|
computed: { |
|
...mapGetters(["routeData","userInfo"]), |
|
isSuperAdmin() { |
|
// 将角色字符串按逗号分割成数组 |
|
const userRoles = this.userInfo.role_name.split(',').map(role => role.trim()) |
|
// 允许的角色列表 |
|
const allowedRoles = ['administrator', 'jinchao'] |
|
// 检查用户角色是否包含允许的角色 |
|
return userRoles.some(role => allowedRoles.includes(role)) |
|
} |
|
|
|
}, |
|
mounted() { |
|
let tmp = this.routeData.find(item => item.url == this.$route.path) |
|
let arr = this.routeData.filter(item => item.url != this.$route.path) |
|
this.$store.commit('SET_ROUTE_DATA', [...arr]) |
|
this.getProductList(this.$route.query.subcategoryId ? this.$route.query.subcategoryId : tmp.catalogId) |
|
this.getSaleData() |
|
// this.getCustomerData() |
|
}, |
|
methods: { |
|
scrollTableToTop() { |
|
if (this.$refs.multipleTable) { |
|
const scrollContainer = this.$refs.multipleTable.bodyWrapper; |
|
if (scrollContainer) { |
|
// 平滑滚动到顶部 |
|
scrollContainer.scrollTo({ |
|
top: 0, |
|
behavior: 'smooth' // 平滑动画 |
|
}); |
|
} |
|
} |
|
}, |
|
// 千分位格式化金额(保留两位小数) |
|
formatPrice(num) { |
|
// 空值/undefined/null 返回空 |
|
if (num === "" || num === undefined || num === null) { |
|
return ""; |
|
} |
|
// 非数字返回 0.00 |
|
if (isNaN(Number(num))) { |
|
return "0.00"; |
|
} |
|
// 转为数字并保留两位小数 |
|
const number = Number(num).toFixed(2); |
|
// 千分位格式化 |
|
return Number(number).toLocaleString("zh-CN", { |
|
minimumFractionDigits: 2, |
|
maximumFractionDigits: 2, |
|
useGrouping: true |
|
}); |
|
}, |
|
// 还原千分位金额为纯数字(保留两位小数) |
|
restorePrice(formattedNum) { |
|
if (!formattedNum ) return ""; |
|
// 移除千分位逗号 |
|
const pureNum = String(formattedNum).replace(/,/g, ''); |
|
// 非数字返回空,否则保留两位小数 |
|
return isNaN(Number(pureNum)) ? "" : Number(pureNum).toFixed(2); |
|
}, |
|
handleCancle() { |
|
this.$router.push({ |
|
path:'/wel' |
|
}) |
|
}, |
|
handleScale(value, index) { |
|
// 只允许数字和小数点(如果你想限制小数点后的位数,可以更复杂地处理) |
|
// // 移除非数字字符,只允许数字输入 |
|
console.log("value.replace(/[^\d]/g, '')=====================", value.replace(/[^\d]/g, '') <= 0 ? 1 : value.replace(/[^\d]/g, '')) |
|
// : value.replace(/[^\d]/g, '') > 100 ? 100 |
|
this.tableData[index].multiple = value.replace(/[^\d]/g, '') <= 0 ? 1 : value.replace(/[^\d]/g, ''); |
|
}, |
|
|
|
// 替换原有 handlePrice 方法 |
|
handlePrice(value, index, field = 'standardPrice') { |
|
// 空值/undefined/null 置空 |
|
if (value === '' || value === undefined || value === null) { |
|
this.$set(this.tableData[index], field, ''); |
|
return; |
|
} |
|
// 只保留数字和小数点 |
|
let cleaned = value.replace(/[^\d.]/g, ''); |
|
// 防止多个小数点 |
|
const parts = cleaned.split('.'); |
|
if (parts.length > 2) { |
|
cleaned = parts[0] + '.' + parts.slice(1).join(''); |
|
} |
|
// 限制小数位最多2位 |
|
if (cleaned.includes('.')) { |
|
const decimalPart = cleaned.split('.')[1]; |
|
if (decimalPart.length > 2) { |
|
cleaned = cleaned.slice(0, cleaned.indexOf('.') + 3); |
|
} |
|
} |
|
// 禁止以 . 开头 |
|
if (cleaned.startsWith('.')) { |
|
cleaned = '0' + cleaned; |
|
} |
|
// 禁止 0 后跟非小数数字(如 0123 → 0) |
|
if (/^0\d+$/.test(cleaned)) { |
|
cleaned = '0'; |
|
} |
|
// 动态赋值字段(standardPrice/bizPrice) |
|
this.$set(this.tableData[index], field, cleaned); |
|
}, |
|
clickPrice(value, index) { |
|
// 仅空值/undefined/null 置空,0值保留 |
|
if (value === '' || value === undefined || value === null) { |
|
this.$set(this.tableData[index], 'standardPrice', ''); |
|
return; |
|
} |
|
// 复用通用还原方法(0值会被还原为 0.00) |
|
const purePrice = this.restorePrice(value); |
|
this.$set(this.tableData[index], 'standardPrice', purePrice); |
|
}, |
|
|
|
blurPrice(value, index) { |
|
// 仅空值/undefined/null 置空,0值保留 |
|
if (value === '' || value === undefined || value === null) { |
|
this.$set(this.tableData[index], 'standardPrice', ''); |
|
return; |
|
} |
|
// 复用通用格式化方法(0值会被格式化为 0.00) |
|
const formattedPrice = this.formatPrice(value); |
|
this.$set(this.tableData[index], 'standardPrice', formattedPrice); |
|
}, |
|
|
|
clickBizPrice(value, index) { |
|
// 仅空值/undefined/null 置空,0值保留 |
|
if (value === '' || value === undefined || value === null) { |
|
this.$set(this.tableData[index], 'bizPrice', ''); |
|
return; |
|
} |
|
// 复用通用还原方法(0值会被还原为 0.00) |
|
const purePrice = this.restorePrice(value); |
|
this.$set(this.tableData[index], 'bizPrice', purePrice); |
|
}, |
|
|
|
blurBizPrice(value, index) { |
|
// 仅空值/undefined/null 置空,0值保留 |
|
if (value === '' || value === undefined || value === null) { |
|
this.$set(this.tableData[index], 'bizPrice', ''); |
|
return; |
|
} |
|
// 复用通用格式化方法(0值会被格式化为 0.00) |
|
const formattedPrice = this.formatPrice(value); |
|
this.$set(this.tableData[index], 'bizPrice', formattedPrice); |
|
}, |
|
toggleColumn() { |
|
this.$refs.multipleTable.toggleRowSelection(row); |
|
}, |
|
changeSale(val) { |
|
this.addForm = { |
|
...this.addForm, |
|
customerId: '' |
|
} |
|
getCustomer({ createUserId: val }).then(res => { |
|
this.customerData = res.data.data |
|
}) |
|
}, |
|
getSaleData() { |
|
getSaleList().then(res => { |
|
this.saleData = res.data.data |
|
if (this.saleData.length != 0) { |
|
getCustomer({ createUserId: this.saleData[0].id }).then(res => { |
|
this.customerData = res.data.data |
|
}) |
|
} |
|
}) |
|
}, |
|
getCustomerData() { |
|
getCustomer().then(res => { |
|
this.customerData = res.data.data |
|
}) |
|
}, |
|
getProductList(id) { |
|
// this.loading = true; |
|
this.subcategoryId = id |
|
let query = { |
|
catalogId: id, |
|
size: 9999, |
|
current: 1 |
|
} |
|
if(this.searchForm.nameCn){ |
|
query.nameCn = this.searchForm.nameCn |
|
} |
|
if(this.searchForm.bizRemark){ |
|
query.bizRemark = this.searchForm.bizRemark |
|
} |
|
|
|
getProduct(query).then(res => { |
|
this.tableData = res.data.data.records |
|
this.tableData.map(item => { |
|
item.isEditing = false; |
|
if (this.currentOperateRowCode && item.code === this.currentOperateRowCode && item.bizType == 2) { |
|
item.isEditing = true; |
|
} |
|
|
|
if (item.bizType == 2) { |
|
|
|
item.bizPrice = this.formatPrice(item.bizPrice); |
|
} else { |
|
|
|
item.standardPrice = this.formatPrice(item.standardPrice); |
|
} |
|
}) |
|
if (this.tableData.length < 10) { |
|
const needValue = 10 - this.tableData.length |
|
for (let i = 0; i < needValue; i++) |
|
this.tableData.push({ multiple: 1, isEditing: false }) |
|
} |
|
this.originData = JSON.parse(JSON.stringify(res.data.data.records)) |
|
this.loading = false; |
|
this.currentOperateRowCode =null |
|
}) |
|
|
|
}, |
|
// ========== 辅助方法:初始化展示数据(补空行) ========== |
|
initTableData(sourceData) { |
|
// 复制源数据作为展示数据基础 |
|
this.tableData = [...sourceData] |
|
// 不足10行补空行 |
|
if (this.tableData.length < 10) { |
|
const needAdd = 10 - this.tableData.length |
|
for (let i = 0; i < needAdd; i++) { |
|
this.tableData.push({ multiple: 1, isEditing: false }) |
|
} |
|
} |
|
}, |
|
|
|
// ========== 核心:搜索功能(筛选原始数据 → 更新展示数据) ========== |
|
handleSearch() { |
|
this.getProductList(this.$route.query.subcategoryId ) |
|
this.$nextTick(() => { |
|
this.scrollTableToTop(); |
|
}); |
|
}, |
|
|
|
// ========== 核心:重置功能(恢复原始数据 → 更新展示数据) ========== |
|
handleReset() { |
|
// 1. 清空搜索表单 |
|
this.searchForm = { nameCn: '', bizRemark: '' } |
|
// 2. 重置表单校验状态 |
|
if (this.$refs.searchForm) { |
|
this.$refs.searchForm.resetFields() |
|
} |
|
this.getProductList(this.$route.query.subcategoryId ) |
|
this.$nextTick(() => { |
|
this.scrollTableToTop(); |
|
}); |
|
|
|
}, |
|
|
|
// 插入一行 |
|
addTable() { |
|
// 新增一行 |
|
const record = { _select: false, multiple: 1, isEditing: false, standardPrice: '', bizPrice: '' }; |
|
this.tableData.push(record) |
|
this.$nextTick(() => { |
|
this.$refs.multipleTable.bodyWrapper.scrollTop = this.$refs.multipleTable.bodyWrapper.scrollHeight; |
|
}) |
|
}, |
|
selectionChangeProject(list) { |
|
// console.log(list,"list") |
|
this.selectionProjectList = list |
|
}, |
|
handleSelectAll(selection) { |
|
// selection有值=全选,无值=反选/取消全选 |
|
const isAllSelected = selection.length > 0; |
|
this.tableData.forEach(row => { |
|
row._select = isAllSelected; // 同步自定义_select |
|
}); |
|
}, |
|
selectChange(list, val) { |
|
val._select = !val._select |
|
// console.log("val", val) |
|
// console.log("selectChange", list) |
|
}, |
|
delTable() { |
|
let arr = this.tableData.filter(item => item._select) |
|
if (arr.length === 0) { |
|
this.$message.error('请至少选择一条数据进行操作!'); |
|
return; |
|
} |
|
if (arr.length != 0) { |
|
this.$confirm('确定将选择数据删除?', { |
|
confirmButtonText: '确定', |
|
cancelButtonText: '取消', |
|
type: 'warning', |
|
}).then(() => { |
|
let deleteArr = this.tableData.filter(item => !item._select) |
|
|
|
let delNoIdArr = deleteArr.filter(item => !item.id) |
|
let noIdArr = arr.filter(item => !item.id) |
|
|
|
let idArr = arr.filter(item => item.id && item.id != '') |
|
if (idArr.length != 0) { |
|
deleteProduct({ ids: idArr.map(item => item.id).join(','), catalogId: this.subcategoryId }).then(res => { |
|
if (res.data.code == 200) { |
|
this.$message.success('删除成功') |
|
getProduct({ current: 1, size: 9999, catalogId: this.subcategoryId }).then(result => { |
|
this.tableData = [...result.data.data.records, ...deleteArr] |
|
}) |
|
} |
|
}) |
|
} else { |
|
this.tableData = deleteArr |
|
} |
|
}) |
|
} else { |
|
this.$message.error('请至少选择一条数据进行操作!') |
|
} |
|
}, |
|
deleteColumn(row, index) { |
|
this.$confirm('确定将选择数据删除?', { |
|
confirmButtonText: '确定', |
|
cancelButtonText: '取消', |
|
type: 'warning', |
|
}).then(() => { |
|
if (row.id) { |
|
console.log('row------------', row) |
|
if (row.bizType == 2) { |
|
deletePrice({ ids: row.bizPriceId }).then(res => { |
|
if (res.data.code == 200) { |
|
this.$message.success('删除成功') |
|
getProduct({ current: 1, size: 9999, catalogId: this.subcategoryId }).then(result => { |
|
// this.tableData = [...result.data.data.records,...deleteArr] |
|
this.tableData.splice(index, 1); |
|
}) |
|
} |
|
}) |
|
} else { |
|
deleteProduct({ ids: row.id, catalogId: this.subcategoryId }).then(res => { |
|
if (res.data.code == 200) { |
|
this.$message.success('删除成功') |
|
getProduct({ current: 1, size: 9999, catalogId: this.subcategoryId }).then(result => { |
|
// this.tableData = [...result.data.data.records,...deleteArr] |
|
console.log("result",result) |
|
this.tableData.splice(index, 1); |
|
}) |
|
} |
|
}) |
|
} |
|
|
|
} else { |
|
this.$message.success('删除成功') |
|
this.tableData.splice(index, 1); |
|
} |
|
}) |
|
}, |
|
saveProduct() { |
|
// 只校验:有数据(nameCn/code/specCn等任意字段有值)但名称为空的行 |
|
const invalidRows = this.tableData.filter(row => { |
|
const isEffectiveRow = row.nameCn || row.code || row.specCn || row.unitCn || row.standardPrice || row.bizPrice; |
|
// 有效行但名称为空 → 校验不通过 |
|
return isEffectiveRow && !row.nameCn; |
|
}); |
|
if (invalidRows.length > 0) { |
|
this.showError = true |
|
this.$message.error(`有 ${invalidRows.length} 行数据未填写完整!`); |
|
return; |
|
} |
|
let arr = this.tableData.filter(item => item && (item.nameCn && item.nameCn != '') ) |
|
arr.map(item => { |
|
item.catalogId = this.subcategoryId, |
|
item.bizPrice = this.restorePrice(item.bizPrice); |
|
item.standardPrice = this.restorePrice(item.standardPrice); |
|
}) |
|
console.log('tableData-------------------',) |
|
changeProduct(arr).then(res => { |
|
if (res.data.code == 200) { |
|
this.$message.success('保存成功') |
|
this.getProductList(this.subcategoryId) |
|
} |
|
}) |
|
}, |
|
startEdit(row) { |
|
// 保存原始数据用于取消编辑时恢复 |
|
row.originalData = JSON.parse(JSON.stringify(row)); |
|
// 设置编辑状态 |
|
row.isEditing = !row.isEditing; |
|
this.$forceUpdate(); |
|
this.tableData = [...this.tableData]; |
|
}, |
|
|
|
editProduct(row) { |
|
// if(!row.id){ |
|
// this.$message.error('请先保存产品!') |
|
// return |
|
// if (row.nameCn && !row.code) { |
|
// this.$message.error('请填写产品编号!') |
|
// return |
|
// } |
|
if (!row.nameCn) { |
|
this.$message.error('请填写产品名称!') |
|
return |
|
} |
|
// } |
|
|
|
// if(!row.id){ |
|
// || (item.code && item.code != '') |
|
let arr = this.tableData.filter(item => item && (item.nameCn && item.nameCn != '') ) |
|
arr.map(item => { |
|
item.catalogId = this.subcategoryId |
|
item.bizPrice = this.restorePrice(item.bizPrice); |
|
item.standardPrice = this.restorePrice(item.standardPrice); |
|
}) |
|
changeProduct(arr).then(res =>{ |
|
if(res.data.code == 200){ |
|
// this.$message.success('保存成功') |
|
// this.getProductList(this.subcategoryId) |
|
getProduct({ |
|
catalogId:this.subcategoryId, |
|
size:9999, |
|
current:1 |
|
}).then(res =>{ |
|
this.tableData = res.data.data.records |
|
this.tableData.map(item =>{ |
|
if(item.bizType == 2){ |
|
item.bizPrice = this.formatPrice(item.bizPrice); |
|
}else{ |
|
item.standardPrice = this.formatPrice(item.standardPrice); |
|
} |
|
}) |
|
if(this.tableData.length < 10){ |
|
const needValue = 10 - this.tableData.length |
|
for(let i = 0;i < needValue;i++) |
|
this.tableData.push({multiple:1}) |
|
} |
|
this.originData = JSON.parse(JSON.stringify(res.data.data.records)) |
|
// console.log("this.tableData", this.tableData) |
|
// console.log("row.nameCn", row.nameCn) |
|
let tmp = this.tableData.find(item => item.nameCn == row.nameCn) |
|
// console.log("row.tmp", tmp) |
|
this.$router.push({ path: '/edit',query:{ |
|
name:row.nameCn, |
|
code:row.code, |
|
id:tmp.id, |
|
subcategoryId:this.subcategoryId |
|
}}); |
|
let arr = [] |
|
arr.push({ |
|
name:row.nameCn, |
|
url:'/add', |
|
catalogId:this.subcategoryId, |
|
query:{ |
|
subcategoryId:this.subcategoryId |
|
} |
|
}) |
|
this.$store.commit('SET_ROUTE_DATA',[...this.routeData,...arr]) |
|
}) |
|
|
|
} |
|
}) |
|
|
|
}, |
|
// 指定业务员 |
|
changePeople(row, index) { |
|
if (!row.id) { |
|
// if (row.nameCn && !row.code) { |
|
// this.$message.error('请填写产品编号!') |
|
// return |
|
// } |
|
if (row.code ) { |
|
this.$message.error('请填写产品名称!') |
|
return |
|
} |
|
let arr = this.tableData.filter(item => item && (item.nameCn && item.nameCn != '') ) |
|
arr.map(item => { |
|
item.catalogId = this.subcategoryId |
|
item.bizPrice = item.bizPrice && item.bizPrice != 0 ? (item.bizPrice + '').replace(/,/g, '') : '' |
|
item.standardPrice = item.standardPrice && item.standardPrice != 0 ? (item.standardPrice + '').replace(/,/g, '') : '' |
|
}) |
|
|
|
changeProduct(arr).then(res => { |
|
if (res.data.code == 200) { |
|
getProduct({ |
|
catalogId: this.subcategoryId, |
|
size: 9999, |
|
current: 1 |
|
}).then(res => { |
|
this.tableData = res.data.data.records |
|
this.tableData.map(item => { |
|
if (item.bizType == 2) { |
|
item.bizPrice = this.formatPrice(item.bizPrice); |
|
} else { |
|
item.standardPrice = this.formatPrice(item.standardPrice); |
|
} |
|
}) |
|
if (this.tableData.length < 10) { |
|
const needValue = 10 - this.tableData.length |
|
for (let i = 0; i < needValue; i++) |
|
this.tableData.push({ multiple: 1 }) |
|
} |
|
this.originData = JSON.parse(JSON.stringify(res.data.data.records)) |
|
this.addForm.productId = this.tableData[index].id |
|
this.addForm.bizPrice = this.tableData[index].standardPrice && this.tableData[index].standardPrice != 0 ? this.tableData[index].standardPrice.replace(/,/g, '') : this.tableData[index].standardPrice |
|
this.addForm = { |
|
...this.addForm, |
|
saleUserId: this.saleData.length != 0 ? this.saleData[0].id : '', |
|
customerId: this.customerData != 0 ? this.customerData[0].id : '' |
|
} |
|
getCustomer({ createUserId: this.addForm.saleUserId }).then(res => { |
|
this.customerData = res.data.data |
|
this.addDialog = true |
|
}) |
|
}) |
|
} |
|
}) |
|
} else { |
|
this.addForm.bizPrice = row.standardPrice && row.standardPrice != 0 ? (row.standardPrice + '').replace(/,/g, '') : row.standardPrice |
|
if (row.bizType == 2) { |
|
this.addForm = { |
|
...this.addForm, |
|
saleUserId: row.saleUserId, |
|
customerId: row.customerId, |
|
productId: row.id, |
|
id: row.bizPriceId, |
|
bizPrice: row.bizPrice && row.bizPrice != 0 ? row.bizPrice.replace(/,/g, '') : row.bizPrice |
|
} |
|
} else { |
|
this.addForm = { |
|
...this.addForm, |
|
saleUserId: this.saleData.length != 0 ? this.saleData[0].id : '', |
|
customerId: this.customerData != 0 ? this.customerData[0].id : '', |
|
productId: row.id, |
|
} |
|
} |
|
this.currentOperateRowCode = row.code |
|
getCustomer({ createUserId: this.addForm.saleUserId }).then(res => { |
|
this.customerData = res.data.data |
|
this.addDialog = true |
|
|
|
}) |
|
|
|
} |
|
}, |
|
submit() { |
|
this.$refs.addForm.validate(valid => { |
|
console.log('add-----------------', this.addForm) |
|
|
|
if (valid) { |
|
changeUser(this.addForm).then(res => { |
|
if (res.data.code == 200) { |
|
this.$message.success('设置成功') |
|
this.getProductList(this.subcategoryId) |
|
this.addDialog = false |
|
} |
|
}) |
|
} |
|
}) |
|
}, |
|
|
|
// 判断当前行是否填写了除code外的其他字段(specCn/unitCn/multiple/standardPrice/bizPrice/remarkCn等) |
|
hasOtherFields(row) { |
|
// 列出需要判断的「非code字段」,只要有一个有值就返回true |
|
return !! ( |
|
row.specCn || // 规格说明 |
|
row.unitCn || // 单位 |
|
row.multiple && row.multiple !== 1 || // 倍率(默认值1不算填写) |
|
row.standardPrice || // 公司指导价 |
|
row.bizPrice || // 业务价格(bizType=2时) |
|
row.remarkCn || // 备注 |
|
row.bizRemark // 业务备注(bizType=2时) |
|
); |
|
}, |
|
|
|
mergeArraysByIdOrName(A, B) { |
|
// 创建 A 的索引映射,便于快速查找 |
|
const idMap = new Map(); // id -> 对象(仅当 id 存在时) |
|
const nameMap = new Map(); // name -> 对象(所有对象都建 name 索引) |
|
|
|
for (const item of A) { |
|
if (item.id != null) { |
|
idMap.set(item.id, item); |
|
} |
|
if (item.nameCn != null) { |
|
nameMap.set(item.nameCn, item); |
|
} |
|
} |
|
|
|
// 遍历 B,尝试覆盖 A 中的对象 |
|
for (const bItem of B) { |
|
let targetInA = null; |
|
|
|
if (bItem.id != null) { |
|
// 优先按 id 匹配 |
|
const candidate = idMap.get(bItem.id); |
|
if (candidate && candidate.nameCn === bItem.nameCn) { |
|
targetInA = candidate; |
|
} |
|
} else if (bItem.nameCn != null) { |
|
// 没有 id 时,按 name 匹配 |
|
targetInA = nameMap.get(bItem.nameCn); |
|
} |
|
|
|
// 如果找到匹配项,则覆盖属性(保留原引用) |
|
if (targetInA) { |
|
Object.assign(targetInA, bItem); |
|
} else { |
|
A.push(bItem) |
|
} |
|
} |
|
|
|
return A; // A 被原地修改,也可返回 |
|
} |
|
} |
|
} |
|
</script> |
|
|
|
<style scoped lang="scss"> |
|
.container { |
|
width: 99%; |
|
height: 99% !important; |
|
background: rgb(255, 255, 255); |
|
margin: 0 auto; |
|
margin-top: 8px; |
|
padding: 20px !important; |
|
display: flex; |
|
flex-direction: column; |
|
overflow: hidden; |
|
|
|
.table-wrapper { |
|
flex: 1; |
|
// max-height: 600px; |
|
overflow: auto; |
|
|
|
} |
|
.title { |
|
// font-size: 30px; |
|
font-size: 1.5vw; |
|
margin-top: 20px; |
|
width: 100%; |
|
text-align: center; |
|
} |
|
|
|
.english_box { |
|
width: 98%; |
|
padding: 36px 36px 0 10px; |
|
margin: 0 auto; |
|
border: 1px solid #ccc; |
|
border-radius: 10px; |
|
|
|
&.info_box { |
|
margin-top: 10px; |
|
} |
|
|
|
.top_box { |
|
display: flex; |
|
justify-content: space-between; |
|
align-items: center; |
|
padding-bottom: 10px; |
|
border-bottom: 1px solid #ccc; |
|
|
|
&.info_top { |
|
border: none; |
|
} |
|
|
|
&.info_top { |
|
border: none; |
|
} |
|
|
|
.top_left { |
|
// font-size: 26px; |
|
font-size: 1.4vw; |
|
} |
|
} |
|
|
|
.top_bottom { |
|
margin-top: 10px; |
|
|
|
.el-col { |
|
margin-bottom: 0px; |
|
} |
|
|
|
|
|
} |
|
} |
|
|
|
.btn_box { |
|
margin-bottom: 12px; |
|
margin: 15px 10px; |
|
display: flex; |
|
justify-content: space-between; |
|
|
|
|
|
} |
|
|
|
/* 手动添加红色边框样式 */ |
|
.is-error { |
|
background: red; |
|
|
|
::v-deep .el-input__inner { |
|
box-shadow: 0 0 0 1px #f56c6c inset !important; |
|
} |
|
} |
|
|
|
|
|
|
|
.is-error ::v-deep input::placeholder { |
|
color: #ff6b6b; |
|
opacity: 1; |
|
} |
|
|
|
// ::v-deep .el-table{ |
|
// font-size: 24px; |
|
// } |
|
|
|
// ::v-deep .el-input__inner{ |
|
// font-size: 24px; |
|
// } |
|
|
|
// ::v-deep .el-button{ |
|
// font-size: 24px; |
|
// } |
|
// ::v-deep .el-table .el-table-column--selection .el-checkbox .el-checkbox__inner{ |
|
// width: 25px !important; |
|
// height: 25px !important; |
|
// display: flex !important; |
|
// justify-content: center; |
|
// align-content: center !important; |
|
// &::after { |
|
// width: 11px !important; |
|
// height: 14px !important; |
|
// } |
|
// } |
|
|
|
} |
|
</style>
|
|
|