子组件:
<template>
<div class="product-base-info-form">
<a-form-model
ref="productBaseInfoRef"
:model="form"
:rules="rules"
labelAlign="left"
:label-col="labelCol"
:wrapper-col="wrapperCol"
:colon="false"
>
<!-- 在frameId为容器的情况下 -->
<div v-if="frameId === STOCK_FRAME_TYPE.CONTAINER" :gutter="12">
<div v-if="!disabled">
<a-form-model-item
prop="icon"
:label-col="labelColItem"
:wrapper-col="{ span: 4 }"
>
<a-select v-model="form.icon" placeholder="图标">
<a-select-option
:key="index"
:value="item"
v-for="(item, index) in productIcons"
>
<!-- <a-icon :type="item" style="font-size: 16px" /> -->
<svg-icon :icon-class="item" :style="{ fontSize: '16px' }" />
</a-select-option>
</a-select>
</a-form-model-item>
<section class="column-item">
<p class="lable">产品名称</p>
<a-form-model-item
class="right"
prop="name"
:label-col="labelColItem"
:wrapper-col="{ span: 8 }"
>
<a-input v-model="form.name" placeholder="名称"></a-input>
</a-form-model-item>
</section>
<section class="column-item">
<p class="lable">编码(Prefix)</p>
<a-form-model-item
class="right"
prop="prefix"
:label-col="labelColItem"
:wrapper-col="{ span: 8 }"
>
<a-input v-model="form.prefix" placeholder="prefix"></a-input>
</a-form-model-item>
</section>
</div>
<a-form-model-item label="容器单位" prop="unitId">
<span v-if="disabled">
{{ unitOptions.filter(item => item.id == form.unitId)[0].unitName }}
</span>
<a-select
v-else
@dropdownVisibleChange="dropdownVisibleChange"
v-model="form.unitId"
placeholder="请选择"
>
<a-select-option
:key="item.id"
:value="item.id"
v-for="item in unitOptions"
>
{{ item.unitName }}
</a-select-option>
<template v-slot:notFoundContent v-if="spinning">
<a-spin :spinning="spinning"></a-spin>
</template>
</a-select>
</a-form-model-item>
<a-form-model-item label="上限容量" prop="capacity">
<span v-if="disabled">{{ form.capacity }}</span>
<a-input v-else v-model="form.capacity"></a-input>
</a-form-model-item>
</div>
<!-- 在frameId不为容器的情况下 -->
<!-- frameId !== STOCK_FRAME_TYPE.CONTAINER -->
<!-- 可编辑状态 -->
<div v-else>
<div v-if="!disabled">
<a-form-model-item
prop="icon"
:label-col="labelColItem"
:wrapper-col="{ span: 6 }"
label="图标"
>
<a-select v-model="form.icon" placeholder="图标">
<a-select-option
:key="index"
:value="item"
v-for="(item, index) in productIcons"
>
<!-- <a-icon :type="item" style="font-size: 16px" /> -->
<svg-icon :icon-class="item" :style="{ fontSize: '16px' }" />
</a-select-option>
</a-select>
</a-form-model-item>
<a-form-model-item
class="right"
prop="name"
:label-col="labelColItem"
:wrapper-col="{ span: 8 }"
label="产品名称"
>
<a-input v-model="form.name" placeholder="名称"></a-input>
</a-form-model-item>
<a-form-model-item
class="right"
prop="prefix"
:label-col="labelColItem"
:wrapper-col="{ span: 8 }"
label="编码(Prefix)"
>
<a-input v-model="form.prefix" placeholder="prefix"></a-input>
</a-form-model-item>
</div>
</div>
<!-- <div class="custom-fields"> -->
<!-- 动态字段 -->
<a-form-model-item
v-for="item in productValues" // 动态字段
:label="item.paramName"
:prop="item.id"
:key="item.id"
:label-col="labelColItem"
:wrapper-col="wrapperColItem"
>
<div
v-if="
paramTypeColumn.text === item.paramType ||
paramTypeColumn.integer === item.paramType ||
paramTypeColumn.float === item.paramType
"
>
<template v-if="disabled">
<span v-if="item.isMultipleValue === 2">{{
form[item.id][0]
}}</span>
<a-tag v-else :key="index" v-for="(ele, index) in form[item.id]">
{{ ele }}
</a-tag>
</template>
<template v-else>
<a-input
v-if="item.isMultipleValue === 2"
v-model="form[item.id][0]"
></a-input>
<a-select
v-else
v-model="form[item.id]"
:dropdownStyle="{ display: 'none' }"
:dropdownMenuStyle="{ display: 'none' }"
mode="tags"
></a-select>
</template>
</div>
<div v-else-if="paramTypeColumn.textArea === item.paramType">
<span v-if="disabled">{{ form[item.id][0] }}</span>
<a-input
v-else
:auto-size="{ minRows: 3, maxRows: 5 }"
v-model="form[item.id][0]"
type="textarea"
></a-input>
</div>
<div v-else-if="paramTypeColumn.radioSelect === item.paramType">
<span v-if="disabled">{{ form[item.id][0] }}</span>
<a-select v-else v-model="form[item.id][0]">
<a-select-option
:key="element"
v-for="element in item.preDefinedValues"
>
{{ element }}
</a-select-option>
</a-select>
</div>
<div v-else-if="paramTypeColumn.multiSelect === item.paramType">
<div v-if="disabled">
<a-tag :key="index" v-for="(ele, index) in form[item.id]">
{{ ele }}
</a-tag>
</div>
<a-select v-else mode="multiple" v-model="form[item.id]">
<a-select-option
:key="element"
v-for="element in item.preDefinedValues"
>
{{ element }}
</a-select-option>
</a-select>
</div>
<div v-else-if="paramTypeColumn.time === item.paramType">
<span v-if="disabled">{{
item.paramValues[0] &&
moment(item.paramValues[0]).format('YYYY-MM-DD HH:mm:ss')
}}</span>
<a-date-picker
v-else
v-model="item.paramValues[0]"
:showTime="true"
></a-date-picker>
</div>
<div v-else-if="paramTypeColumn.link === item.paramType">
<!-- <span>产品链接类型。。。</span> -->
<!-- 展示产品链接 -->
<div v-if="disabled">
<div class="link-item-box">
<li
class="link-type"
:key="ele.referenceId"
v-for="ele in item.paramValues"
@click="showProductLinkDetail(ele)"
>
<a-icon type="link" />{{ ele.referenceName }}
</li>
</div>
</div>
<div v-else>
<a-button @click="selectProduct(item.paramValues)" size="small"
><a-icon type="fullscreen" />选择产品</a-button
>
<div class="link-item-box">
<li
class="link-type"
:key="ele.referenceId"
v-for="ele in item.paramValues"
@click="showProductLinkDetail(ele)"
>
<a-icon type="link" /> {{ ele.referenceName }}
</li>
</div>
</div>
</div>
<div v-else-if="paramTypeColumn.cycle === item.paramType">
<div v-if="disabled">
<span
v-if="item.paramValues[0].value && item.paramValues[0].cycleType"
>{{
`${item.paramValues[0].value} ${
CycleTypeInfo[item.paramValues[0].cycleType]
}`
}}</span
>
</div>
<!-- 周期 -->
<CycleTypeCom
v-else
:info="item.paramValues[0]"
style="width: 260px"
/>
</div>
<div v-else-if="paramTypeColumn.container === item.paramType">
<!-- 选择的关联容器 -->
<span v-if="disabled">
<!-- {{ item.paramValues[0] ? item.paramValues[0].containerName : '' }} -->
<!-- {{ form[item.id][0] ? form[item.id][0].containerName : '' }} -->
{{ form[item.id][0].containerName }}
</span>
<a-select v-else v-model="form[item.id][0].containerName" show-search>
<!-- 关联容器列表 -->
<a-select-option
:key="element.id"
v-for="element in ContainerOptions"
:value="element.name"
>
{{ element.name }}
</a-select-option>
</a-select>
</div>
</a-form-model-item>
<!-- </div> -->
</a-form-model>
<product-link-modal ref="productLinkModalRef"></product-link-modal>
<product-base-info-modal
ref="productBaseInfoModalRef"
></product-base-info-modal>
</div>
</template>
<script>
import moment from 'moment'
import { queryStockSchemasDetail } from '@/api/material/locationSetting'
import {
handleMaterialValidateCodePlus,
validateInteger,
validateFloat,
validateFloatNumber,
validateArrRequired
} from '@/common/inspectFunction'
import {
paramTypeColumn,
productIcons,
STOCK_FRAME_TYPE,
VOLUME_TYPE_UNIT,
CycleTypeInfo
} from '@/common/global'
import { getFullUnitInfo } from '@/api/system/unit'
import ProductBaseInfoModal from './ProductBaseInfoModal'
import ProductLinkModal from './ProductLinkModal'
import CycleTypeCom from './fieldRuleSetting/CycleTypeCom'
export default {
props: {
productValues: {
type: Array,
default() {
return []
}
},
productSelfInfo: {
type: Object,
default() {
return {}
}
},
icons: {
type: Array,
default() {
return []
}
},
frameId: {
type: String,
default() {
return ''
}
}
},
components: {
ProductBaseInfoModal,
ProductLinkModal,
CycleTypeCom
},
data() {
return {
CycleTypeInfo,
productIcons: this.icons,
labelCol: { span: 8 },
wrapperCol: { span: 12 },
labelColItem: { span: 8 },
wrapperColItem: { span: 12 },
paramTypeColumn: Object.freeze(paramTypeColumn),
baseInfo: {
prefix: '',
name: '',
icon: '',
unitId: undefined,
capacity: undefined,
version: undefined
},
form: {
prefix: '',
name: '',
icon: '',
unitId: undefined,
capacity: '',
version: undefined
},
showForm: {},
rules: {
prefix: [
{ required: true, message: '请填写编号', trigger: 'blur' },
{
min: 1,
max: 32,
message: '编号长度在1-32个字符之间',
trigger: 'change'
},
{
validator: this.handleMaterialValidateCodePlus,
message: '编号格式不正确',
trigger: 'change'
}
],
unitId: [{ required: true, message: '请填写单位', trigger: 'blur' }],
capacity: [
{
validator: this.validateFloatNumber,
message: '容量格式不正确',
trigger: 'change'
}
],
name: [
{ required: true, message: '必填', trigger: 'change' },
{
min: 1,
max: 32,
message: '名称长度在1-32个字符之间',
trigger: 'change'
}
]
},
disabled: true,
// 后端需要的paramType
paramTypeObj: {},
STOCK_FRAME_TYPE: Object.freeze(STOCK_FRAME_TYPE),
unitOptions: [],
ContainerOptions: [],
// tmpContainerId: '',
spinning: true,
checkContainer: false
}
},
methods: {
moment,
// 下拉菜单触发的回调
dropdownVisibleChange(open) {
// this.spinning = true
open && _.isEmpty(this.unitOptions) && this.getFullUnitInfo()
},
/**
* 获取数据库预选单位
*/
async getFullUnitInfo() {
this.spinning = true
const res = await getFullUnitInfo({
artifacts: [VOLUME_TYPE_UNIT],
pageSize: -1
}).finally(() => {
this.spinning = false
})
if (res.code === '200') {
this.unitOptions = res.data
}
},
/**
* 获取数据库容器
*/
async getFullContainerInfo() {
this.ContainerOptions = []
const res = await queryStockSchemasDetail({
stockFrameId: '3',
pageSize: -1
})
if (res.code === '200') {
this.ContainerOptions = res.data.result
// return res.data.result
}
},
/**
* 自定义编码规则
*/
handleMaterialValidateCodePlus,
/**
* 整数自定义验证
*/
validateInteger,
/**
* 浮点数自定义验证
*/
validateFloat,
validateFloatNumber,
validateArrRequired,
/**
* 验证表单数据规则是否匹配
*/
validateFormData() {
let flag = false
this.$refs.productBaseInfoRef.validate(valid => {
flag = valid
})
return flag
},
/**
* 选择产品
*/
selectProduct(paramValues) {
this.$refs.productLinkModalRef.openSelectProductInfoModal(paramValues)
},
/**
* 展示产品详情
*/
showProductLinkDetail(item) {
this.$refs.productBaseInfoModalRef.openProductInfoModal({
id: item.referenceId
})
},
/**
* 父组件会调用它来传输产品基本信息和产品种类自定义字段
*/
async getFullData(callback) {
if (!this.validateFormData()) {
return
// callback(false)
}
// const target = _.cloneDeep(this.form)
const target = _.cloneDeep(this.showForm)
let targetArr = []
// {...this.baseInfo} = target
Object.keys(this.baseInfo).forEach(key => {
this.baseInfo[key] = target[key]
delete target[key]
})
Object.keys(target).forEach(key => {
targetArr.push({
id: key,
paramValues: target[key],
paramType: this.paramTypeObj[key]
})
})
await callback({ ...this.baseInfo, productValues: targetArr })
},
/**
* 改变为可以编辑的状态
*/
changeIsShowStatus() {
this.disabled = false
},
/**
* 改变为不可编辑的状态
*/
changeNoShowStatus() {
this.disabled = true
},
/**
* 清除 form 表单 多余信息
*/
resetFormInfo() {
this.$refs.productBaseInfoRef &&
this.$refs.productBaseInfoRef.resetFields &&
this.$refs.productBaseInfoRef.resetFields()
const baseInfoKeys = Object.keys(this.baseInfo)
Object.keys(this.form)
.filter(item => {
return !baseInfoKeys.includes(item)
})
.forEach(key => {
delete this.form[key]
})
}
},
created() {
this.frameId === STOCK_FRAME_TYPE.CONTAINER &&
this.dropdownVisibleChange(true)
},
watch: {
productValues: {
// 切换产品后动态字段信息变化后清除表单动态字段信息给动态字段赋值新的信息并添加到
// form中并在rules中添加新的验证规则。
handler(newProductValues) {
// console.log(newProductValues);
// this.tmpContainerId = ''
this.resetFormInfo()
this.getFullContainerInfo()
newProductValues.forEach(element => {
this.paramTypeObj[element.id] = element.paramType
this.$set(this.form, element.id, element.paramValues || [])
// 给预设容器默认值防止v-model取不到值
if (element.paramType === this.paramTypeColumn.container) {
if (!this.form[element.id][0]) {
this.$set(this.form, element.id, [{
containerId: '',
containerName: ''
}])
}
}
// 控制位置容器数没有值预设容器不必填
if (element.fieldName === "位置容器数") {
this.checkContainer = true
}
// 必填项
if (element.isRequired === 1) {
const requiredInfo = [
{ validator: this.validateArrRequired, trigger: 'change' },
{ required: true, message: '必填', trigger: 'change' }
]
!this.rules[element.id] &&
this.$set(this.rules, element.id, requiredInfo)
if (
this.rules[element.id] &&
this.rules[element.id].findIndex(item => item.required) < 0
) {
this.rules[element.id].push(...requiredInfo)
}
// this.rules[element.id] = [{ required: true, message: '必填', trigger: 'change' }]
}
// 整数
if (element.paramType === this.paramTypeColumn.integer) {
!this.rules[element.id] &&
this.$set(this.rules, element.id, [
{ validator: this.validateInteger }
])
this.rules[element.id] &&
this.rules[element.id].push({
validator: this.validateInteger
})
}
// 浮点数
if (element.paramType === this.paramTypeColumn.float) {
!this.rules[element.id] &&
this.$set(this.rules, element.id, [
{ validator: this.validateFloat }
])
this.rules[element.id] &&
this.rules[element.id].push({
validator: this.validateFloat
})
}
// 覆盖预设容器的规则
if (this.checkContainer && element.paramType === this.paramTypeColumn.container) {
this.rules[element.id] &&
this.$set(this.rules, element.id, [])
// this.rules[element.id] &&
// this.rules[element.id].push([])
this.checkContainer = false
}
})
},
immediate: true
},
productSelfInfo: {
// 切换产品后给表单基本信息新值
handler(newProductSelfInfo) {
this.form.name = newProductSelfInfo.name
this.form.prefix = newProductSelfInfo.prefix
this.form.icon = newProductSelfInfo.icon
this.form.unitId = newProductSelfInfo.unitId
this.form.capacity = newProductSelfInfo.capacity
this.form.version = newProductSelfInfo.version
},
immediate: true,
deep: true
},
frameId: {
handler(newFramaId) {
newFramaId === STOCK_FRAME_TYPE.CONTAINER &&
this.dropdownVisibleChange(true)
},
immediate: true
},
disabled: {
handler(newDisabled) {
this.showForm = _.cloneDeep(this.form);
console.log(this.showForm);
if (newDisabled) {
// 如果是非编辑状态
} else {
// 如果是编辑状态
}
},
immediate: true
}
}
}
</script>
<style lang="scss" scoped>
.product-base-info-form {
.link-item-box {
.link-type {
margin: 0 2px;
display: inline-block;
}
}
& > .columns {
display: flex;
flex-flow: column;
section.column-item {
display: flex;
flex-flow: row wrap;
justify-content: space-between;
align-items: center;
p.lable {
flex-grow: 1;
color: #8c8c8c;
font-size: 14px;
user-select: none;
}
.right {
width: 304px;
}
}
}
}
.custom-fields,
.columns {
margin-right: 25px;
::v-deep div.ant-row.ant-form-item {
display: flex !important;
flex-flow: row wrap;
justify-content: space-between;
align-items: center;
}
::v-deep div.ant-col.ant-col-8.ant-form-item-label.ant-form-item-label-left {
background-color: red;
flex-grow: 1;
color: #8c8c8c;
font-size: 14px;
user-select: none;
}
::v-deep .ant-col.ant-col-12.ant-form-item-control-wrapper {
width: 304px;
input.ant-input {
width: 304px;
}
}
}
</style>
父组件:
<!-- TODO -->
<template>
<div class="product-info-detail-right">
<!-- 具体产品详细信息 -->
<a-spin :spinning="isLoading">
<a-col :span="10">
<div class="product-info-content">
<div class="product-info-content-head">
<a-space>
<span
><!-- <a-icon :type="productSelfInfo.icon" /> -->
<svg-icon :icon-class="productSelfInfo.icon" />
{{ productSelfInfo.name }}</span
>
<span
:style="{
fontWeight: 'normal',
fontSize: '12px',
color: '#bfbfbf',
}"
>PREFIX: {{ productSelfInfo.prefix }}</span
>
</a-space>
<div>
<a-button
v-if="operatorName[1] === 'edit'"
@click="(e) => changeCradStatus(1, e)"
size="small"
icon="edit"
/>
</div>
</div>
<div
:class="
operatorName[1] === 'ok'
? 'product-info-content-card'
: 'product-info-content-card rquired-no-star'
"
>
<product-base-info-form
ref="productBaseInfoFormRef"
:productSelfInfo="productSelfInfo"
:productValues="frameParams"
:icons="schemaIcons"
:frameId="frameId"
></product-base-info-form>
<div class="product-info-content-card-footer">
<a-space v-if="operatorName[1] === 'ok'">
<a-button size="small" @click="(e) => backCradEditStatus(1, e)"
>取消</a-button
>
<a-button
type="primary"
size="small"
@click="(e) => changeCradStatus(1, e)"
>提交</a-button
>
</a-space>
</div>
</div>
<div class="product-info-content-card">
<div class="product-info-content-card-header">
<span>附加信息</span>
<div>
<a-button
v-if="operatorName[2] === 'edit'"
@click="(e) => changeCradStatus(2, e)"
size="small"
icon="edit"
/>
</div>
</div>
<a-descriptions
v-if="operatorName[2] === 'edit'"
:column="1"
size="small"
bordered
>
<a-descriptions-item
:label="item.paramName"
:key="item.id"
v-for="item in customFields"
>
<span class="info-value">{{ item.paramValue }}</span>
</a-descriptions-item>
</a-descriptions>
<div v-show="operatorName[2] === 'ok'">
<a-alert message="进入编辑状态,暂未保存更新" banner />
<product-custom-fields
ref="productCustomFieldsRef"
@getData="getSchemaFieldsData"
:customFields="customFields"
></product-custom-fields>
<div class="product-info-content-card-footer">
<a-space>
<a-button
size="small"
@click="(e) => backCradEditStatus(2, e)"
>取消</a-button
>
<a-button
type="primary"
size="small"
@click="(e) => changeCradStatus(2, e)"
>提交</a-button
>
</a-space>
</div>
</div>
</div>
</div>
</a-col>
<a-col :span="14">
<div>
<a-tabs
:default-active-key="titleKey"
@change="(key) => onTabChange(key, 'titleKey')"
size="small"
>
<a-tab-pane key="1" tab="相关库位">
<batch-info-table-list
:parentId="productInfoId"
></batch-info-table-list>
</a-tab-pane>
<a-tab-pane key="2" tab="库位设置" force-render>
<div class="bmy-tab-pane-content">
<storage-location
ref="storageLocationRef"
@getData="getStorageLocationFieldsData"
:customFields="storageFields"
:showMode="showMode.productKey"
>
</storage-location>
<div class="product-info-content-card-footer">
<a-space>
<a-button
type="primary"
size="small"
@click="(e) => changeCradStatus(3, e)"
>提交</a-button
>
</a-space>
</div>
</div>
</a-tab-pane>
</a-tabs>
</div>
</a-col>
</a-spin>
</div>
</template>
<script>
import { schemaIcons } from "@/common/global";
import {
queryStockFramesDetailBySchemaId,
updateStockSchema,
updateStockSchemaFields,
} from "@/api/material/locationSetting";
import ProductCustomFields from "@/views/materialcenter/productManagement/components/ProductCustomFields";
import ProductBaseInfoForm from "@/views/materialcenter/productManagement/components/ProductBaseInfoForm";
import BatchInfoTableList from "./StockInstanceTable";
import { CUSTOM_FIELD_SHOW_MODE } from "@/views/materialcenter/productManagement/components/comm/constValues";
export default {
props: {
productInfo: {
type: Object,
default() {
return {};
},
},
getLeftStockFrameOrSchema: Function,
},
components: {
ProductCustomFields,
StorageLocation: ProductCustomFields,
ProductBaseInfoForm,
BatchInfoTableList,
},
data() {
return {
schemaIcons: Object.freeze(schemaIcons), // icon 图标
operatorName: {
1: "edit",
2: "edit",
},
isLoading: false,
productInfoId: "",
productSelfInfo: {
name: "",
prefix: "",
icon: "",
capacity: undefined,
unitId: undefined,
version: undefined,
},
customFields: [],
frameParams: [],
tabListTitle: [
{
key: "1",
tab: "元件字段",
},
{
key: "2",
tab: "库位字段",
},
],
titleKey: "1",
showMode: Object.freeze(CUSTOM_FIELD_SHOW_MODE),
schemaCustomFieldsData: {},
storageFieldsData: {},
storageFields: [],
frameId: "",
};
},
methods: {
/**
* 切换 元件/库位字段卡片视图
*/
onTabChange(key, type) {
this[type] = key;
},
/**
* 改变卡片状态,会让子组件切换状态
*/
changeCradStatus(key, e) {
if (key === 3) {
this.editBaseInfoOrFields(key);
return;
}
if (this.operatorName[key] === "edit") {
this.operatorName[key] = "ok";
// 会让子组件切换状态
key === 1 ? this.$refs.productBaseInfoFormRef.changeIsShowStatus() : "";
} else {
// this.operatorName[key] = 'edit'
// 编辑基本信息/编辑产品字段
this.editBaseInfoOrFields(key);
}
},
/**
* 调用编辑基本信息/产品字段
* key 1.基本信息 2.产品字段 3.库位/批次字段
*/
editBaseInfoOrFields(key) {
switch (key) {
case 1:
//切换卡片时调用
this.editProductBaseInfo();
break;
case 3:
case 2:
this.editProductFields();
break;
default:
break;
}
},
/**
* 编辑产品字段 确认时
*/
editProductFields() {
this.$refs.productCustomFieldsRef.getData();
this.$refs.storageLocationRef.getData();
this.updateProductFields({
id: this.productInfoId,
customParams: this.schemaCustomFieldsData,
stockParams: this.storageFieldsData,
});
},
/**
* 编辑产品基本信息
*/
editProductBaseInfo() {
this.$refs.productBaseInfoFormRef.getFullData((data) => {
data.frameParams = data.productValues;
delete data.productValues;
data &&
this.updateProductInfo({
stockFrameId: this.frameId,
id: this.productInfoId,
...data,
});
});
},
/**
* 更新产品基本信息 含产品种类字段的 values
* fixme 这个函数到底是干嘛的。。。。
*/
// 编辑状态确认时更新信息
async updateProductInfo(data) {
const res = await updateStockSchema(data);
if (res.code === "200") {
this.productSelfInfo.version = res.data.version;
this.productSelfInfo.name = this.$refs.productBaseInfoFormRef.form.name;
this.productSelfInfo.prefix =this.$refs.productBaseInfoFormRef.form.prefix;
this.productSelfInfo.icon = this.$refs.productBaseInfoFormRef.form.icon;
this.operatorName[1] = "edit";
this.$refs.productBaseInfoFormRef.changeNoShowStatus();
// this.$emit('updateProductName')
// 更新库位元件名称 => 手动调用接口
this.getLeftStockFrameOrSchema();
}
},
/**
* 更新产品自定义字段
*/
async updateProductFields(data) {
const res = await updateStockSchemaFields(data);
if (res.code === "200") {
this.operatorName[2] = "edit";
// 发起请求
this.getFullProductInfoDetail({ id: this.productInfoId });
}
},
/**
* 从编辑状态返回
*/
backCradEditStatus(key, e) {
if (this.operatorName[key] === "ok") {
this.operatorName[key] = "edit";
key === 1 ? this.$refs.productBaseInfoFormRef.changeNoShowStatus() : "";
}
},
/**
* 获取产品字段属性数据
*/
getSchemaFieldsData(data, deletingFieldIds) {
// 产品字段 修改是否编辑
// this.updateProductFields({
// id: this.productInfoId,
// params: data,
// deletingFieldIds,
// })
this.schemaCustomFieldsData = {
params: data,
deletingFieldIds,
};
},
/**
* 获取库位字段信息
*/
getStorageLocationFieldsData(data, deletingFieldIds) {
this.storageFieldsData = {
params: data,
deletingFieldIds,
};
},
/**
* 获取产品信息详情
*/
async getFullProductInfoDetail(data) {
this.isLoading = true;
const res = await queryStockFramesDetailBySchemaId(data).finally(() => {
this.isLoading = false;
});
if (res.code === "200") {
this.customFields = res.data.customParams;
this.frameId = res.data.frameId;
this.frameParams = res.data.frameParams;
this.storageFields = res.data.stockParams;
Object.keys(this.productSelfInfo).forEach((key) => {
this.productSelfInfo[key] = res.data[key];
});
// 深克隆 => productBaseInfoForm 组件监听
this.productSelfInfo = _.cloneDeep(this.productSelfInfo);
}
},
resetCartView() {
this.operatorName = {
1: "edit",
2: "edit",
};
this.$refs.productBaseInfoFormRef &&
this.$refs.productBaseInfoFormRef.changeNoShowStatus &&
this.$refs.productBaseInfoFormRef.changeNoShowStatus();
},
},
watch: {
"productInfo.id": {
handler(newVal) {
this.productInfoId = newVal;
this.resetCartView();
this.getFullProductInfoDetail({ id: newVal });
},
immediate: true,
},
},
};
</script>
<style lang="scss" scoped>
.product-info-detail-right {
height: 100%;
// background-color: red;
padding: 16px;
.forbidden {
pointer-events: none;
}
.product-fields {
height: 350px;
overflow-y: scroll;
}
.product-forbidden {
cursor: not-allowed;
}
.batch-info {
height: 500px;
overflow-y: scroll;
}
.product-fields::-webkit-scrollbar {
display: none;
}
}
.product-info-detail-right {
height: 100%;
// background-color: red;
padding: 16px;
.forbidden {
pointer-events: none;
}
.product-fields {
height: 350px;
overflow-y: scroll;
::v-deep.ant-card-head {
border: none;
}
}
.product-forbidden {
cursor: not-allowed;
}
.batch-info {
height: 500px;
overflow-y: scroll;
}
.product-fields::-webkit-scrollbar {
display: none;
}
}
.product-info-content {
height: calc(100vh - 48px);
overflow-y: auto;
margin-right: 8px;
padding-right: 8px;
border-right: 1px solid #f0f0f0;
.product-info-content-head {
display: flex;
justify-content: space-between;
padding: 0 8px 8px 0;
span {
font-size: 16px;
font-weight: 700;
}
}
.product-info-content-card {
padding: 24px 8px 8px 24px;
.product-info-content-card-header {
display: flex;
justify-content: space-between;
margin-bottom: 8px;
span {
color: #8c8c8c;
font-weight: 500;
}
}
}
.info-value {
color: #262626;
}
::v-deep.ant-form-item {
margin-bottom: 8px;
color: rgba(0, 0, 0, 0.85);
}
::v-deep.ant-form-item-label-left {
label {
color: #8c8c8c;
font-weight: 500;
}
}
.rquired-no-star {
::v-deep.ant-form-item-required::before {
content: none;
}
}
}
.product-info-content-card-footer {
display: flex;
justify-content: flex-end;
}
.bmy-tab-pane-content {
padding: 8px 24px;
}
</style>
<!-- TODO -->
<template>
<div class="product-info-detail-right">
<!-- 具体产品详细信息 -->
<a-spin :spinning="isLoading">
<a-col :span="10">
<div class="product-info-content">
<div class="product-info-content-head">
<a-space>
<span
><!-- <a-icon :type="productSelfInfo.icon" /> -->
<svg-icon :icon-class="productSelfInfo.icon" />
{{ productSelfInfo.name }}</span
>
<span
:style="{
fontWeight: 'normal',
fontSize: '12px',
color: '#bfbfbf',
}"
>PREFIX: {{ productSelfInfo.prefix }}</span
>
</a-space>
<div>
<a-button
v-if="operatorName[1] === 'edit'"
@click="(e) => changeCradStatus(1, e)"
size="small"
icon="edit"
/>
</div>
</div>
<div
:class="
operatorName[1] === 'ok'
? 'product-info-content-card'
: 'product-info-content-card rquired-no-star'
"
>
<product-base-info-form
ref="productBaseInfoFormRef"
:productSelfInfo="productSelfInfo"
:productValues="frameParams"
:icons="schemaIcons"
:frameId="frameId"
></product-base-info-form>
<div class="product-info-content-card-footer">
<a-space v-if="operatorName[1] === 'ok'">
<a-button size="small" @click="(e) => backCradEditStatus(1, e)"
>取消</a-button
>
<a-button
type="primary"
size="small"
@click="(e) => changeCradStatus(1, e)"
>提交</a-button
>
</a-space>
</div>
</div>
<div class="product-info-content-card">
<div class="product-info-content-card-header">
<span>附加信息</span>
<div>
<a-button
v-if="operatorName[2] === 'edit'"
@click="(e) => changeCradStatus(2, e)"
size="small"
icon="edit"
/>
</div>
</div>
<a-descriptions
v-if="operatorName[2] === 'edit'"
:column="1"
size="small"
bordered
>
<a-descriptions-item
:label="item.paramName"
:key="item.id"
v-for="item in customFields"
>
<span class="info-value">{{ item.paramValue }}</span>
</a-descriptions-item>
</a-descriptions>
<div v-show="operatorName[2] === 'ok'">
<a-alert message="进入编辑状态,暂未保存更新" banner />
<product-custom-fields
ref="productCustomFieldsRef"
@getData="getSchemaFieldsData"
:customFields="customFields"
></product-custom-fields>
<div class="product-info-content-card-footer">
<a-space>
<a-button
size="small"
@click="(e) => backCradEditStatus(2, e)"
>取消</a-button
>
<a-button
type="primary"
size="small"
@click="(e) => changeCradStatus(2, e)"
>提交</a-button
>
</a-space>
</div>
</div>
</div>
</div>
</a-col>
<a-col :span="14">
<div>
<a-tabs
:default-active-key="titleKey"
@change="(key) => onTabChange(key, 'titleKey')"
size="small"
>
<a-tab-pane key="1" tab="相关库位">
<batch-info-table-list
:parentId="productInfoId"
></batch-info-table-list>
</a-tab-pane>
<a-tab-pane key="2" tab="库位设置" force-render>
<div class="bmy-tab-pane-content">
<storage-location
ref="storageLocationRef"
@getData="getStorageLocationFieldsData"
:customFields="storageFields"
:showMode="showMode.productKey"
>
</storage-location>
<div class="product-info-content-card-footer">
<a-space>
<a-button
type="primary"
size="small"
@click="(e) => changeCradStatus(3, e)"
>提交</a-button
>
</a-space>
</div>
</div>
</a-tab-pane>
</a-tabs>
</div>
</a-col>
<!-- <a-row :gutter="16">
<a-col :span="12">
<a-card
class="card product-fields"
title="基本信息"
:class="{ 'product-forbidden': operatorName[1] === 'edit' }"
>
<a slot="extra" @click="(e) => changeCradStatus(1, e)">{{
operatorName[1] === "edit" ? "编辑" : "确认"
}}</a>
<product-base-info-form
ref="productBaseInfoFormRef"
:productSelfInfo="productSelfInfo"
:productValues="frameParams"
:icons="schemaIcons"
:frameId="frameId"
:class="{ forbidden: operatorName[1] === 'edit' }"
></product-base-info-form>
</a-card>
</a-col>
<a-col :span="12">
<a-card
class="card product-fields"
:class="{ 'product-forbidden': operatorName[2] === 'edit' }"
:tab-list="tabListTitle"
:active-tab-key="titleKey"
@tabChange="(key) => onTabChange(key, 'titleKey')"
>
<a
class="link-button"
slot="tabBarExtraContent"
@click="(e) => changeCradStatus(2, e)"
>{{ operatorName[2] === "edit" ? "编辑" : "确认" }}</a
>
<a-alert
v-if="operatorName[2] === 'ok'"
message="进入编辑状态,暂未保存更新"
banner
/>
<product-custom-fields
v-show="titleKey === '1'"
ref="productCustomFieldsRef"
@getData="getSchemaFieldsData"
:customFields="customFields"
:class="{ forbidden: operatorName[2] === 'edit' }"
></product-custom-fields>
<storage-location
v-show="titleKey === '2'"
ref="storageLocationRef"
@getData="getStorageLocationFieldsData"
:class="{ forbidden: operatorName[2] === 'edit' }"
:customFields="storageFields"
:showMode="showMode.productKey"
>
</storage-location>
</a-card>
</a-col>
</a-row>
<a-row style="margin-top: 16px">
<a-col :span="24">
<a-card class="card batch-info" title="相关库位"> </a-card>
</a-col>
</a-row> -->
</a-spin>
</div>
</template>
<script>
import { schemaIcons } from "@/common/global";
import {
queryStockFramesDetailBySchemaId,
updateStockSchema,
updateStockSchemaFields,
} from "@/api/material/locationSetting";
import ProductCustomFields from "@/views/materialcenter/productManagement/components/ProductCustomFields";
import ProductBaseInfoForm from "@/views/materialcenter/productManagement/components/ProductBaseInfoForm";
import BatchInfoTableList from "./StockInstanceTable";
import { CUSTOM_FIELD_SHOW_MODE } from "@/views/materialcenter/productManagement/components/comm/constValues";
export default {
props: {
productInfo: {
type: Object,
default() {
return {};
},
},
getLeftStockFrameOrSchema: Function,
},
components: {
ProductCustomFields,
StorageLocation: ProductCustomFields,
ProductBaseInfoForm,
BatchInfoTableList,
},
data() {
return {
schemaIcons: Object.freeze(schemaIcons), // icon 图标
operatorName: {
1: "edit",
2: "edit",
},
isLoading: false,
productInfoId: "",
productSelfInfo: {
name: "",
prefix: "",
icon: "",
capacity: undefined,
unitId: undefined,
version: undefined,
},
customFields: [],
frameParams: [],
tabListTitle: [
{
key: "1",
tab: "元件字段",
},
{
key: "2",
tab: "库位字段",
},
],
titleKey: "1",
showMode: Object.freeze(CUSTOM_FIELD_SHOW_MODE),
schemaCustomFieldsData: {},
storageFieldsData: {},
storageFields: [],
frameId: "",
};
},
methods: {
/**
* 切换 元件/库位字段卡片视图
*/
onTabChange(key, type) {
this[type] = key;
},
/**
* 改变卡片状态
*/
changeCradStatus(key, e) {
if (key === 3) {
this.editBaseInfoOrFields(key);
return;
}
if (this.operatorName[key] === "edit") {
this.operatorName[key] = "ok";
key === 1 ? this.$refs.productBaseInfoFormRef.changeIsShowStatus() : "";
} else {
// this.operatorName[key] = 'edit'
// 编辑基本信息/编辑产品字段
this.editBaseInfoOrFields(key);
}
},
/**
* 调用编辑基本信息/产品字段
* key 1.基本信息 2.产品字段 3.库位/批次字段
*/
editBaseInfoOrFields(key) {
switch (key) {
case 1:
this.editProductBaseInfo();
break;
case 3:
case 2:
this.editProductFields();
break;
default:
break;
}
},
/**
* 编辑产品字段 确认时
*/
editProductFields() {
this.$refs.productCustomFieldsRef.getData();
this.$refs.storageLocationRef.getData();
this.updateProductFields({
id: this.productInfoId,
customParams: this.schemaCustomFieldsData,
stockParams: this.storageFieldsData,
});
},
/**
* 编辑产品基本信息
*/
editProductBaseInfo() {
this.$refs.productBaseInfoFormRef.getFullData(async (data) => {
data.frameParams = data.productValues;
delete data.productValues;
data &&
await this.updateProductInfo({
stockFrameId: this.frameId,
id: this.productInfoId,
...data,
});
});
},
/**
* 更新产品基本信息 含产品种类字段的 values
* fixme 这个函数到底是干嘛的。。。。
*/
async updateProductInfo(data) {
const res = await updateStockSchema(data);
if (res.code === "200") {
this.productSelfInfo.version = res.data.version;
this.productSelfInfo.name = this.$refs.productBaseInfoFormRef.form.name;
this.productSelfInfo.prefix =this.$refs.productBaseInfoFormRef.form.prefix;
this.productSelfInfo.icon = this.$refs.productBaseInfoFormRef.form.icon;
this.operatorName[1] = "edit";
this.$refs.productBaseInfoFormRef.changeNoShowStatus();
// this.$emit('updateProductName')
// 更新库位元件名称 => 手动调用接口
this.getLeftStockFrameOrSchema();
}
},
/**
* 更新产品自定义字段
*/
async updateProductFields(data) {
const res = await updateStockSchemaFields(data);
if (res.code === "200") {
this.operatorName[2] = "edit";
// 发起请求
this.getFullProductInfoDetail({ id: this.productInfoId });
}
},
/**
* 从编辑状态返回
*/
backCradEditStatus(key, e) {
if (this.operatorName[key] === "ok") {
this.operatorName[key] = "edit";
key === 1 ? this.$refs.productBaseInfoFormRef.changeNoShowStatus() : "";
}
},
/**
* 获取产品字段属性数据
*/
getSchemaFieldsData(data, deletingFieldIds) {
// 产品字段 修改是否编辑
// this.updateProductFields({
// id: this.productInfoId,
// params: data,
// deletingFieldIds,
// })
this.schemaCustomFieldsData = {
params: data,
deletingFieldIds,
};
},
/**
* 获取库位字段信息
*/
getStorageLocationFieldsData(data, deletingFieldIds) {
this.storageFieldsData = {
params: data,
deletingFieldIds,
};
},
/**
* 获取产品信息详情
*/
async getFullProductInfoDetail(data) {
this.isLoading = true;
const res = await queryStockFramesDetailBySchemaId(data).finally(() => {
this.isLoading = false;
});
if (res.code === "200") {
this.customFields = res.data.customParams;
this.frameId = res.data.frameId;
this.frameParams = res.data.frameParams;
this.storageFields = res.data.stockParams;
Object.keys(this.productSelfInfo).forEach((key) => {
this.productSelfInfo[key] = res.data[key];
});
// 深克隆 => productBaseInfoForm 组件监听
this.productSelfInfo = _.cloneDeep(this.productSelfInfo);
}
},
resetCartView() {
this.operatorName = {
1: "edit",
2: "edit",
};
this.$refs.productBaseInfoFormRef &&
this.$refs.productBaseInfoFormRef.changeNoShowStatus &&
this.$refs.productBaseInfoFormRef.changeNoShowStatus();
},
},
watch: {
"productInfo.id": {
handler(newVal) {
this.productInfoId = newVal;
this.resetCartView();
this.getFullProductInfoDetail({ id: newVal });
},
immediate: true,
},
},
};
</script>
<style lang="scss" scoped>
.product-info-detail-right {
height: 100%;
// background-color: red;
padding: 16px;
.forbidden {
pointer-events: none;
}
.product-fields {
height: 350px;
overflow-y: scroll;
}
.product-forbidden {
cursor: not-allowed;
}
.batch-info {
height: 500px;
overflow-y: scroll;
}
.product-fields::-webkit-scrollbar {
display: none;
}
}
.product-info-detail-right {
height: 100%;
// background-color: red;
padding: 16px;
.forbidden {
pointer-events: none;
}
.product-fields {
height: 350px;
overflow-y: scroll;
::v-deep.ant-card-head {
border: none;
}
}
.product-forbidden {
cursor: not-allowed;
}
.batch-info {
height: 500px;
overflow-y: scroll;
}
.product-fields::-webkit-scrollbar {
display: none;
}
}
.product-info-content {
height: calc(100vh - 48px);
overflow-y: auto;
margin-right: 8px;
padding-right: 8px;
border-right: 1px solid #f0f0f0;
.product-info-content-head {
display: flex;
justify-content: space-between;
padding: 0 8px 8px 0;
span {
font-size: 16px;
font-weight: 700;
}
}
.product-info-content-card {
padding: 24px 8px 8px 24px;
.product-info-content-card-header {
display: flex;
justify-content: space-between;
margin-bottom: 8px;
span {
color: #8c8c8c;
font-weight: 500;
}
}
}
.info-value {
color: #262626;
}
::v-deep.ant-form-item {
margin-bottom: 8px;
color: rgba(0, 0, 0, 0.85);
}
::v-deep.ant-form-item-label-left {
label {
color: #8c8c8c;
font-weight: 500;
}
}
.rquired-no-star {
::v-deep.ant-form-item-required::before {
content: none;
}
}
}
.product-info-content-card-footer {
display: flex;
justify-content: flex-end;
}
.bmy-tab-pane-content {
padding: 8px 24px;
}
</style>
<template>
<a-modal
v-if="visible"
:title="title"
:visible="visible"
@ok="handleOk"
@cancel="handleCancel"
:width="800"
:height="900"
:destoryOnClose="true"
:bodyStyle="{ padding: '0px 10px', minHeight: '500px' }"
>
<a-tabs default-active-key="1">
<a-tab-pane key="1" tab="基本信息" style="padding-left: 10px">
<a-row>
<a-form-model
ref="createBatchInfoRef"
:model="form"
:labelCol="{ span: 10 }"
:wrapperCol="{ span: 14 }"
:rules="rules"
>
<a-row :gutter="16">
<a-col :span="12">
<a-form-model-item label="种类" prop="frameName">
<a-input disabled v-model="form.frameName"></a-input>
</a-form-model-item>
</a-col>
<a-col :span="12">
<a-form-model-item label="图标" prop="icon">
<a-select v-model="form.icon">
<a-select-option
:value="item"
:key="index"
v-for="(item, index) in schemaIcons"
>
<!-- <a-icon :type="item" style="font-size: 16px" /> -->
<svg-icon
:icon-class="item"
:style="{ fontSize: '16px' }"
/>
</a-select-option>
</a-select>
</a-form-model-item>
</a-col>
<a-col :span="12">
<a-form-model-item label="编码" prop="prefix">
<a-input v-model="form.prefix"></a-input>
</a-form-model-item>
</a-col>
<a-col :span="12">
<a-form-model-item label="元件名称" prop="name">
<a-input v-model="form.name"></a-input>
</a-form-model-item>
</a-col>
<a-col :span="12" v-if="CONTAINER_TYPE === stockFrameInfo.id">
<a-form-model-item label="单位" prop="unitId">
<a-select
@dropdownVisibleChange="dropdownVisibleChange"
v-model="form.unitId"
placeholder="请选择"
>
<a-select-option
:key="item.id"
:value="item.id"
v-for="item in unitOptions"
>
{{ item.unitName }}
</a-select-option>
<template v-slot:notFoundContent v-if="spinning">
<a-spin :spinning="spinning"></a-spin>
</template>
</a-select>
</a-form-model-item>
</a-col>
<a-col :span="12" v-if="CONTAINER_TYPE === stockFrameInfo.id">
<a-form-model-item label="容量" prop="capacity">
<a-input v-model="form.capacity"></a-input>
</a-form-model-item>
</a-col>
<a-col
:key="item.id"
:span="12"
v-for="item in stockFrameAttribute"
>
<template v-if="item.paramType !== paramTypeColumn.container">
<a-form-model-item :label="item.paramName" :prop="item.id">
<template
v-if="
paramTypeColumn.text === item.paramType ||
paramTypeColumn.integer === item.paramType ||
paramTypeColumn.float === item.paramType
"
>
<a-input
v-if="item.isMultipleValue === 2"
v-model="form[item.id][0]"
></a-input>
<a-select
v-else
v-model="form[item.id]"
:dropdownStyle="{ display: 'none' }"
:dropdownMenuStyle="{ display: 'none' }"
mode="tags"
></a-select>
</template>
<template
v-else-if="paramTypeColumn.textArea === item.paramType"
>
<a-input
:auto-size="{ minRows: 3, maxRows: 5 }"
class="default-input"
v-model="form[item.id][0]"
type="textarea"
></a-input>
</template>
<template
v-else-if="paramTypeColumn.radioSelect === item.paramType"
>
<a-select v-model="form[item.id][0]">
<a-select-option
:key="element"
v-for="element in item.preDefinedValues"
>
{{ element }}
</a-select-option>
</a-select>
</template>
<template
v-else-if="paramTypeColumn.multiSelect === item.paramType"
>
<a-select mode="multiple" v-model="form[item.id]">
<a-select-option
:key="element"
v-for="element in item.preDefinedValues"
>
{{ element }}
</a-select-option>
</a-select>
</template>
<template v-else-if="paramTypeColumn.time === item.paramType">
<a-date-picker
v-model="item.paramValues[0]"
:showTime="true"
></a-date-picker>
</template>
<template v-else-if="paramTypeColumn.link === item.paramType">
<span
class="link-type"
:key="ele.referenceId"
v-for="ele in item.paramValues"
@click="showProductLinkDetail(ele)"
><a-icon type="link" /> {{ ele.referenceName }}</span
>
</template>
<!-- <template
v-else-if="paramTypeColumn.container === item.paramType && isShowContainerType"
>
<a-select
allowClear
@dropdownVisibleChange="dropdownVisibleChange2"
@change="
id => {
handleChangeContainer(id, form[item.id])
}
"
>
<a-select-option
:key="element.id"
v-for="element in ContainerOptions"
:value="element.id"
>
{{ element.name }}
</a-select-option>
<template v-slot:notFoundContent v-if="spinning">
<a-spin :spinning="spinning"></a-spin>
</template>
</a-select>
</template> -->
</a-form-model-item>
</template>
<template v-else-if="
(item.paramType === paramTypeColumn.container && isShowContainerType) ||
(item.paramType === paramTypeColumn.container && stockFrameInfo.name === '盒') ||
(item.paramType === paramTypeColumn.container && stockFrameInfo.name === '板')
">
<a-form-model-item :label="item.paramName" :prop="item.id">
<a-select
allowClear
@dropdownVisibleChange="dropdownVisibleChange2"
@change="
id => {
handleChangeContainer(id, form[item.id])
}
"
>
<a-select-option
:key="element.id"
v-for="element in ContainerOptions"
:value="element.id"
>
{{ element.name }}
</a-select-option>
<template v-slot:notFoundContent v-if="spinning">
<a-spin :spinning="spinning"></a-spin>
</template>
</a-select>
</a-form-model-item>
</template>
</a-col>
</a-row>
</a-form-model>
</a-row>
<span>元件字段:</span>
<custom-fields
@getData="getCustomFieldsData"
ref="customFieldsRef"
></custom-fields>
<span>库位字段:</span>
<storage-fields
ref="storageFieldsRef"
@getData="getStorageLocationFieldsData"
:showMode="showMode.productKey"
>
</storage-fields>
</a-tab-pane>
<a-tab-pane
key="2"
tab="规则设置"
style="padding-left: 10px"
></a-tab-pane>
</a-tabs>
</a-modal>
</template>
<script>
import {
queryStockFrameFields,
saveStockSchema,
queryStockSchemasDetail
} from '@/api/material/locationSetting'
import { getFullUnitInfo } from '@/api/system/unit'
import {
handleValidateCodePlus,
validateInteger,
validateFloat,
validateFloatNumber,
validateArrRequired
} from '@/common/inspectFunction'
import { paramTypeColumn, schemaIcons, VOLUME_TYPE_UNIT } from '@/common/global'
import CustomFields from '@/views/materialcenter/productManagement/components/ProductCustomFields'
import { CUSTOM_FIELD_SHOW_MODE } from '@/views/materialcenter/productManagement/components/comm/constValues'
const CONTAINER_TYPE = '3'
// const CONTAINER_TYPE_HE = '2'
// const CONTAINER_TYPE_BAN = '4'
export default {
components: {
CustomFields,
StorageFields: CustomFields
},
props: {
leftSuccess: Function,
schemaRightSuccess: Function
},
data() {
return {
schemaIcons: Object.freeze(schemaIcons),
source: '',
stockFrameInfo: {},
visible: false,
title: '新建元件',
paramTypeColumn: Object.freeze(paramTypeColumn),
baseInfo: {
frameName: '',
icon: '',
prefix: '',
name: '',
unitId: undefined,
capacity: undefined
},
form: {
frameName: '',
icon: '',
prefix: '',
name: '',
unitId: undefined,
capacity: undefined
},
rules: {
prefix: [
{
min: 1,
max: 64,
required: true,
message: '编码的长度在1~64位之间',
trigger: 'change'
},
{
validator: this.handleValidateCodePlus,
message: '编号格式不正确',
trigger: 'change'
}
],
name: [
{
min: 1,
max: 32,
required: true,
message: '元件名称的长度在1~32位之间',
trigger: 'change'
}
],
capacity: [
{
validator: this.validateFloatNumber
},
{
required: true,
message: '容量为必填',
trigger: 'blur'
}
],
unitId: [
{
required: true,
message: '请填写单位',
trigger: 'blur'
}
]
},
stockFrameAttribute: [],
// 后端需要的paramType
paramTypeObj: {},
showMode: Object.freeze(CUSTOM_FIELD_SHOW_MODE),
customFieldsData: [],
storageFieldData: [],
unitOptions: [], // 单位选项
CONTAINER_TYPE,
// CONTAINER_TYPE_HE,
// CONTAINER_TYPE_BAN,
spinning: true,
ContainerOptions: [], //容器选项
tempContainer: '',
checkContainer: false,
isShowContainerType: false,
}
},
methods: {
dropdownVisibleChange(open) {
// this.spinning = true
open && _.isEmpty(this.unitOptions) && this.getFullUnitInfo()
},
/**
* 获取数据库预选单位
*/
async getFullUnitInfo() {
this.spinning = true
const res = await getFullUnitInfo({
artifacts: [VOLUME_TYPE_UNIT],
pageSize: -1
}).finally(() => {
this.spinning = false
})
if (res.code === '200') {
this.unitOptions = res.data
}
},
dropdownVisibleChange2(open) {
open && _.isEmpty(this.ContainerOptions) && this.getFullContainerInfo()
},
/**
* 获取数据库容器
*/
async getFullContainerInfo() {
this.spinning = true
const res = await queryStockSchemasDetail({
stockFrameId: '3',
pageSize: -1
}).finally(() => {
this.spinning = false
})
if (res.code === '200') {
this.ContainerOptions = res.data.result
}
},
/**
* 自定义编码规则
*/
handleValidateCodePlus,
/**
* 整数自定义验证
*/
validateInteger,
/**
* 浮点数自定义验证
*/
validateFloat,
validateFloatNumber,
/**
* 后端给的值是数组
* 自定义必填
*/
validateArrRequired,
/**
* 动态表单校验
*/
dynamicValidate(element) {
// 必填项
// console.log(element);
// 位置容器数没有值预设容器不必填
// if (element.fieldName === "位置容器数") {
// this.checkContainer = true
// }
if (element.isRequired === 1) {
const requiredInfo = [
{ validator: this.validateArrRequired, trigger: 'change' },
{ required: true, message: '必填', trigger: 'change' }
]
!this.rules[element.id] &&
this.$set(this.rules, element.id, requiredInfo)
if (
this.rules[element.id] &&
this.rules[element.id].findIndex(item => item.required) < 0
) {
this.rules[element.id].push(...requiredInfo)
}
// this.rules[element.id] = [{ required: true, message: '必填', trigger: 'change' }]
}
// 整数
if (element.paramType === this.paramTypeColumn.integer) {
!this.rules[element.id] &&
this.$set(this.rules, element.id, [
{ validator: this.validateInteger }
])
this.rules[element.id] &&
this.rules[element.id].push({
validator: this.validateInteger
})
}
// 浮点数
if (element.paramType === this.paramTypeColumn.float) {
!this.rules[element.id] &&
this.$set(this.rules, element.id, [{ validator: this.validateFloat }])
this.rules[element.id] &&
this.rules[element.id].push({
validator: this.validateFloat
})
}
// if (this.checkContainer && element.paramType === this.paramTypeColumn.container) {
// this.rules[element.id] &&
// this.$set(this.rules, element.id, [])
// // this.rules[element.id] &&
// // this.rules[element.id].push([])
// this.checkContainer = false
// }
},
/**
* 获取自定义字段数据
*/
getCustomFieldsData(data) {
this.customFieldsData = data
},
/**
* 获取元件为库位设置的字段信息
*/
getStorageLocationFieldsData(data) {
this.storageFieldData = data
},
/**
* 保存库位元件
*/
async saveStockSchema(data) {
const res = await saveStockSchema(data)
if (res.code === '200') {
this.judgeCallback()
this.handleCancel()
}
},
/**
* 判断需要执行的回调
*/
judgeCallback() {
switch (this.source) {
case 'storageComponentLeft':
this.leftSuccess(this.stockFrameInfo)
break
case 'storageSchemaListRight':
this.schemaRightSuccess()
break
default:
break
}
},
/**
* 获取自定义字段和设置字段的数据
*/
getCustomFieldsDataAndSettingData() {
this.$refs.customFieldsRef.getData()
this.$refs.storageFieldsRef.getData()
},
/**
* 获取种类字段数据
*/
getFrameParams() {
let targetArr = []
const target = _.cloneDeep(this.form)
Object.keys(this.baseInfo).forEach(key => {
this.baseInfo[key] = target[key]
delete target[key]
})
Object.keys(target).forEach(key => {
targetArr.push({
id: key,
paramValues: target[key],
paramType: this.paramTypeObj[key]
})
})
// console.log(targetArr);
return targetArr
},
/**
* TODO
* 模态框确定
*/
handleOk() {
this.$refs.createBatchInfoRef.validate(valid => {
if (valid) {
this.getCustomFieldsDataAndSettingData()
const frameParams = this.getFrameParams()
this.saveStockSchema({
...this.baseInfo,
frameParams: frameParams,
customParams: {
params: this.customFieldsData
},
stockParams: {
params: this.storageFieldData
},
stockFrameId: this.stockFrameInfo.id
})
}
})
},
/**
* 模态框取消
*/
handleCancel() {
this.visible = false
this.$refs.createBatchInfoRef.resetFields()
this.isShowContainerType = false
this.form = {
frameName: '',
icon: '',
prefix: '',
name: '',
unitId: undefined,
capacity: undefined
}
this.stockFrameAttribute = []
},
/**
* 根据库位种类id获取库位种类属性信息
*/
async queryStockFrameFields(data) {
const res = await queryStockFrameFields(data)
if (res.code === '200') {
this.stockFrameAttribute = res.data
this.stockFrameAttribute.forEach(element => {
this.paramTypeObj[element.id] = element.paramType
this.$set(this.form, element.id, element.paramValues || [])
// 校验规则
this.dynamicValidate(element)
// console.log(this.form);
})
}
},
/**
* 打开模态框
*/
openCreateStockShemaModal(data, source) {
this.tempContainer = ''
this.source = source || ''
this.visible = true
this.stockFrameInfo = data
this.form.frameName = this.stockFrameInfo.name
this.queryStockFrameFields({ id: this.stockFrameInfo.id })
},
/**
* 改变预选容器
*/
handleChangeContainer(id, target) { // 这里改回去
if (id) {
const findContainer = this.ContainerOptions.find(v => v.id === id)
this.tempContainer = id
const { id: containerId, name: containerName } = findContainer
target[0] = { containerId, containerName }
} else {
target[0] = {containerId: null, containerName: ""}
// target = []
}
}
},
watch: {
form: {
handler() {
// Object.keys()
const targetId = this.stockFrameAttribute.find(item => item.paramName === '位置容器数')?.id
// console.log(targetId, this.form[targetId]?.length > 0 && this.form[targetId][0] !== '')
;(this.form[targetId]?.length > 0 && this.form[targetId][0] !== '') ? (this.isShowContainerType = true) : (this.isShowContainerType = false)
},
deep: true,
}
},
}
</script>
<style lang="scss" scoped></style>
<template>
<div class="product-base-info-form">
<!-- {{ copyForm }} -- {{ form }} -- {{ disabled }} -->
<!-- {{ showForm }} -->
<a-form-model
ref="productBaseInfoRef"
:model="showForm"
:rules="rules"
labelAlign="left"
:label-col="labelCol"
:wrapper-col="wrapperCol"
:colon="false"
>
如果STOCK_FRAME_TYPE是容器
<div v-if="frameId === STOCK_FRAME_TYPE.CONTAINER" :gutter="12">
<div v-if="!disabled">
<a-form-model-item
prop="icon"
:label-col="labelColItem"
:wrapper-col="{ span: 4 }"
>
<a-select v-model="showForm.icon" placeholder="图标">
<a-select-option
:key="index"
:value="item"
v-for="(item, index) in productIcons"
>
<!-- <a-icon :type="item" style="font-size: 16px" /> -->
<svg-icon :icon-class="item" :style="{ fontSize: '16px' }" />
</a-select-option>
</a-select>
</a-form-model-item>
<section class="column-item">
<p class="lable">产品名称</p>
<a-form-model-item
class="right"
prop="name"
:label-col="labelColItem"
:wrapper-col="{ span: 8 }"
>
<a-input v-model="showForm.name" placeholder="名称"></a-input>
</a-form-model-item>
</section>
<section class="column-item">
<p class="lable">编码(Prefix)</p>
<a-form-model-item
class="right"
prop="prefix"
:label-col="labelColItem"
:wrapper-col="{ span: 8 }"
>
<a-input v-model="showForm.prefix" placeholder="prefix"></a-input>
</a-form-model-item>
</section>
</div>
<a-form-model-item label="容器单位" prop="unitId">
<span v-if="disabled">
{{ unitOptions.filter(item => item.id == showForm.unitId)[0].unitName }}
</span>
<a-select
v-else
@dropdownVisibleChange="dropdownVisibleChange"
v-model="showForm.unitId"
placeholder="请选择"
>
<a-select-option
:key="item.id"
:value="item.id"
v-for="item in unitOptions"
>
{{ item.unitName }}
</a-select-option>
<template v-slot:notFoundContent v-if="spinning">
<a-spin :spinning="spinning"></a-spin>
</template>
</a-select>
</a-form-model-item>
<a-form-model-item label="上限容量" prop="capacity">
<span v-if="disabled">{{ showForm.capacity }}</span>
<a-input v-else v-model="showForm.capacity"></a-input>
</a-form-model-item>
</div>
<!-- frameId !== STOCK_FRAME_TYPE.CONTAINER -->
<!-- 可编辑状态 -->
如果STOCK_FRAME_TYPE不是容器,是盒板位置
<div v-else>
如果是编辑状态才显示图标、产品名称、编码
<div v-if="!disabled">
<a-form-model-item
prop="icon"
:label-col="labelColItem"
:wrapper-col="{ span: 6 }"
label="图标"
>
<a-select v-model="showForm.icon" placeholder="图标">
<a-select-option
:key="index"
:value="item"
v-for="(item, index) in productIcons"
>
<!-- <a-icon :type="item" style="font-size: 16px" /> -->
<svg-icon :icon-class="item" :style="{ fontSize: '16px' }" />
</a-select-option>
</a-select>
</a-form-model-item>
<a-form-model-item
class="right"
prop="name"
:label-col="labelColItem"
:wrapper-col="{ span: 8 }"
label="产品名称"
>
<a-input v-model="showForm.name" placeholder="名称"></a-input>
</a-form-model-item>
<a-form-model-item
class="right"
prop="prefix"
:label-col="labelColItem"
:wrapper-col="{ span: 8 }"
label="编码(Prefix)"
>
<a-input v-model="showForm.prefix" placeholder="prefix"></a-input>
</a-form-model-item>
</div>
</div>
动态字段
<a-form-model-item
v-for="item in productValues"
:label="item.paramName"
:prop="item.id"
:key="item.id"
:label-col="labelColItem"
:wrapper-col="wrapperColItem"
>
<!-- 不是容器的渲染在这里 -->
<template v-if="item.paramType !== paramTypeColumn.container">
<div v-if="paramTypeColumn.text === item.paramType || paramTypeColumn.integer === item.paramType || paramTypeColumn.float === item.paramType">
<template v-if="disabled">
<span v-if="item.isMultipleValue === 2">{{
showForm[item.id][0]
}}</span>
<a-tag v-else :key="index" v-for="(ele, index) in showForm[item.id]">
{{ ele }}
</a-tag>
</template>
<template v-else>
<a-input
v-if="item.isMultipleValue === 2"
v-model="showForm[item.id][0]"
></a-input>
<a-select
v-else
v-model="showForm[item.id]"
:dropdownStyle="{ display: 'none' }"
:dropdownMenuStyle="{ display: 'none' }"
mode="tags"
></a-select>
</template>
</div>
<div v-else-if="paramTypeColumn.textArea === item.paramType">
<span v-if="disabled">{{ showForm[item.id][0] }}</span>
<a-input
v-else
:auto-size="{ minRows: 3, maxRows: 5 }"
v-model="showForm[item.id][0]"
type="textarea"
></a-input>
</div>
<div v-else-if="paramTypeColumn.radioSelect === item.paramType">
<span v-if="disabled">{{ showForm[item.id][0] }}</span>
<a-select v-else v-model="showForm[item.id][0]">
<a-select-option
:key="element"
v-for="element in item.preDefinedValues"
>
{{ element }}
</a-select-option>
</a-select>
</div>
<div v-else-if="paramTypeColumn.multiSelect === item.paramType">
<div v-if="disabled">
<a-tag :key="index" v-for="(ele, index) in showForm[item.id]">
{{ ele }}
</a-tag>
</div>
<a-select v-else mode="multiple" v-model="showForm[item.id]">
<a-select-option
:key="element"
v-for="element in item.preDefinedValues"
>
{{ element }}
</a-select-option>
</a-select>
</div>
<div v-else-if="paramTypeColumn.time === item.paramType">
<span v-if="disabled">{{
item.paramValues[0] &&
moment(item.paramValues[0]).format('YYYY-MM-DD HH:mm:ss')
}}</span>
<a-date-picker
v-else
v-model="item.paramValues[0]"
:showTime="true"
></a-date-picker>
</div>
<div v-else-if="paramTypeColumn.link === item.paramType">
<!-- <span>产品链接类型。。。</span> -->
<!-- 展示产品链接 -->
<div v-if="disabled">
<div class="link-item-box">
<li
class="link-type"
:key="ele.referenceId"
v-for="ele in item.paramValues"
@click="showProductLinkDetail(ele)"
>
<a-icon type="link" />{{ ele.referenceName }}
</li>
</div>
</div>
<div v-else>
<a-button @click="selectProduct(item.paramValues)" size="small"
><a-icon type="fullscreen" />选择产品</a-button
>
<div class="link-item-box">
<li
class="link-type"
:key="ele.referenceId"
v-for="ele in item.paramValues"
@click="showProductLinkDetail(ele)"
>
<a-icon type="link" /> {{ ele.referenceName }}
</li>
</div>
</div>
</div>
<div v-else-if="paramTypeColumn.cycle === item.paramType">
<div v-if="disabled">
<span
v-if="item.paramValues[0].value && item.paramValues[0].cycleType"
>{{
`${item.paramValues[0].value} ${
CycleTypeInfo[item.paramValues[0].cycleType]
}`
}}</span
>
</div>
<!-- 周期 -->
<CycleTypeCom
v-else
:info="item.paramValues[0]"
style="width: 260px"
/>
</div>
</template>
<!-- 是容器的单独渲染在这里,且isShowContainerType为真 -->
<template v-else-if="item.paramType === paramTypeColumn.container && isShowContainerType">
<!-- 选择的关联容器 -->
<span v-if="disabled">
{{ showForm[item.id][0].containerName }}
</span>
<a-select v-else :default-value="showForm[item.id][0].containerId" @change="(id) => handleChangeContainer(id, showForm[item.id])" show-search>
<!-- 关联容器列表 -->
<a-select-option
:key="element.id"
v-for="element in ContainerOptions"
:value="element.id"
>
{{ element.name }}
</a-select-option>
<template v-slot:notFoundContent v-if="spinning">
<a-spin :spinning="spinning"></a-spin>
</template>
</a-select>
</template>
</a-form-model-item>
<!-- </div> -->
</a-form-model>
<product-link-modal ref="productLinkModalRef"></product-link-modal>
<product-base-info-modal
ref="productBaseInfoModalRef"
></product-base-info-modal>
</div>
</template>
<script>
import moment from 'moment'
import { queryStockSchemasDetail } from '@/api/material/locationSetting'
import {
handleMaterialValidateCodePlus,
validateInteger,
validateFloat,
validateFloatNumber,
validateArrRequired
} from '@/common/inspectFunction'
import {
paramTypeColumn,
productIcons,
STOCK_FRAME_TYPE,
VOLUME_TYPE_UNIT,
CycleTypeInfo
} from '@/common/global'
import { getFullUnitInfo } from '@/api/system/unit'
import ProductBaseInfoModal from './ProductBaseInfoModal'
import ProductLinkModal from './ProductLinkModal'
import CycleTypeCom from './fieldRuleSetting/CycleTypeCom'
export default {
props: {
productValues: {
type: Array,
default() {
return []
}
},
productSelfInfo: {
type: Object,
default() {
return {}
}
},
icons: {
type: Array,
default() {
return []
}
},
frameId: {
type: String,
default() {
return ''
}
}
},
components: {
ProductBaseInfoModal,
ProductLinkModal,
CycleTypeCom
},
data() {
return {
CycleTypeInfo,
productIcons: this.icons,
labelCol: { span: 8 },
wrapperCol: { span: 12 },
labelColItem: { span: 8 },
wrapperColItem: { span: 12 },
paramTypeColumn: Object.freeze(paramTypeColumn),
baseInfo: {
prefix: '',
name: '',
icon: '',
unitId: undefined,
capacity: undefined,
version: undefined
},
form: {
prefix: '',
name: '',
icon: '',
unitId: undefined,
capacity: '',
version: undefined
},
showForm: {},
rules: {
prefix: [
{ required: true, message: '请填写编号', trigger: 'blur' },
{
min: 1,
max: 32,
message: '编号长度在1-32个字符之间',
trigger: 'change'
},
{
validator: this.handleMaterialValidateCodePlus,
message: '编号格式不正确',
trigger: 'change'
}
],
unitId: [{ required: true, message: '请填写单位', trigger: 'blur' }],
capacity: [
{
validator: this.validateFloatNumber,
message: '容量格式不正确',
trigger: 'change'
}
],
name: [
{ required: true, message: '必填', trigger: 'change' },
{
min: 1,
max: 32,
message: '名称长度在1-32个字符之间',
trigger: 'change'
}
]
},
disabled: true,
// 后端需要的paramType
paramTypeObj: {},
STOCK_FRAME_TYPE: Object.freeze(STOCK_FRAME_TYPE),
unitOptions: [],
ContainerOptions: [],
// tmpContainerId: '',
spinning: true,
checkContainer: false,
isShowContainerType: false,
}
},
methods: {
moment,
dropdownVisibleChange(open) {
// this.spinning = true
open && _.isEmpty(this.unitOptions) && this.getFullUnitInfo()
},
/**
* 获取数据库预选单位
*/
async getFullUnitInfo() {
this.spinning = true
const res = await getFullUnitInfo({
artifacts: [VOLUME_TYPE_UNIT],
pageSize: -1
}).finally(() => {
this.spinning = false
})
if (res.code === '200') {
this.unitOptions = res.data
}
},
/**
* 获取数据库容器
*/
async getFullContainerInfo() {
this.ContainerOptions = []
this.spinning = true
const res = await queryStockSchemasDetail({
stockFrameId: '3',
pageSize: -1
}).finally(() => {
this.spinning = false
})
if (res.code === '200') {
this.ContainerOptions = res.data.result
// return res.data.result
}
},
/**
* 自定义编码规则
*/
handleMaterialValidateCodePlus,
/**
* 整数自定义验证
*/
validateInteger,
/**
* 浮点数自定义验证
*/
validateFloat,
validateFloatNumber,
validateArrRequired,
/**
* 验证表单数据规则是否匹配
*/
validateFormData() {
let flag = false
this.$refs.productBaseInfoRef.validate(valid => {
flag = valid
})
return flag
},
/**
* 选择产品
*/
selectProduct(paramValues) {
this.$refs.productLinkModalRef.openSelectProductInfoModal(paramValues)
},
/**
* 展示产品详情
*/
showProductLinkDetail(item) {
this.$refs.productBaseInfoModalRef.openProductInfoModal({
id: item.referenceId
})
},
/**
* 传输产品基本信息和产品种类自定义字段
*/
async getFullData(callback) {
if (!this.validateFormData()) {
return
// callback(false)
}
const target = _.cloneDeep(this.showForm)
let targetArr = []
// {...this.baseInfo} = target
Object.keys(this.baseInfo).forEach(key => {
this.baseInfo[key] = target[key]
delete target[key]
})
// console.log(target);
Object.keys(target).forEach(key => {
targetArr.push({
id: key,
paramValues: target[key],
paramType: this.paramTypeObj[key]
})
})
const _form = { ..._.cloneDeep(this.showForm), version: this.showForm.version + 1 }
await callback({ ...this.baseInfo, productValues: targetArr })
this.form = _form
// this.changeNoShowStatus()
},
/**
* 改变为可以编辑的状态
*/
changeIsShowStatus() {
this.disabled = false
},
/**
* 改变为不可编辑的状态
*/
changeNoShowStatus() {
this.disabled = true
},
/**
* 清除 form 表单 多余信息
*/
resetFormInfo() {
this.$refs.productBaseInfoRef &&
this.$refs.productBaseInfoRef.resetFields &&
this.$refs.productBaseInfoRef.resetFields()
const baseInfoKeys = Object.keys(this.baseInfo)
Object.keys(this.form)
.filter(item => {
return !baseInfoKeys.includes(item)
})
.forEach(key => {
delete this.form[key]
})
},
/**
* 改变 container
*/
handleChangeContainer(id, target) {
const findContainer = this.ContainerOptions.find(v => v.id === id)
this.tempContainer = id
const { id: containerId, name: containerName } = findContainer
target[0] = { containerId, containerName }
}
},
created() {
this.frameId === STOCK_FRAME_TYPE.CONTAINER &&
this.dropdownVisibleChange(true)
},
watch: {
productValues: {
handler(newProductValues) {
// console.log(newProductValues);
// this.tmpContainerId = ''
this.resetFormInfo()
this.getFullContainerInfo()
newProductValues.forEach(element => {
this.paramTypeObj[element.id] = element.paramType
this.$set(this.form, element.id, element.paramValues || [])
// 给预设容器默认值防止v-model取不到值 !删掉
if (element.paramType === this.paramTypeColumn.container) {
if (!this.form[element.id][0]) {
this.$set(this.form, element.id, [{
containerId: '',
containerName: ''
}])
}
}
// 控制位置容器数没有值预设容器不必填 !删掉
if (element.fieldName === "位置容器数") {
this.checkContainer = true
}
// 必填项
if (element.isRequired === 1) {
const requiredInfo = [
{ validator: this.validateArrRequired, trigger: 'change' },
{ required: true, message: '必填', trigger: 'change' }
]
!this.rules[element.id] &&
this.$set(this.rules, element.id, requiredInfo)
if (
this.rules[element.id] &&
this.rules[element.id].findIndex(item => item.required) < 0
) {
this.rules[element.id].push(...requiredInfo)
}
// this.rules[element.id] = [{ required: true, message: '必填', trigger: 'change' }]
}
// 整数
if (element.paramType === this.paramTypeColumn.integer) {
!this.rules[element.id] &&
this.$set(this.rules, element.id, [
{ validator: this.validateInteger }
])
this.rules[element.id] &&
this.rules[element.id].push({
validator: this.validateInteger
})
}
// 浮点数
if (element.paramType === this.paramTypeColumn.float) {
!this.rules[element.id] &&
this.$set(this.rules, element.id, [
{ validator: this.validateFloat }
])
this.rules[element.id] &&
this.rules[element.id].push({
validator: this.validateFloat
})
}
// 覆盖预设容器的规则 !删掉
if (this.checkContainer && element.paramType === this.paramTypeColumn.container) {
this.rules[element.id] &&
this.$set(this.rules, element.id, [])
// this.rules[element.id] &&
// this.rules[element.id].push([])
this.checkContainer = false
}
})
},
immediate: true
},
productSelfInfo: {
handler(newProductSelfInfo) {
this.form.name = newProductSelfInfo.name
this.form.prefix = newProductSelfInfo.prefix
this.form.icon = newProductSelfInfo.icon
this.form.unitId = newProductSelfInfo.unitId
this.form.capacity = newProductSelfInfo.capacity
this.form.version = newProductSelfInfo.version
},
immediate: true,
deep: true
},
frameId: {
handler(newFramaId) {
newFramaId === STOCK_FRAME_TYPE.CONTAINER &&
this.dropdownVisibleChange(true)
},
immediate: true
},
disabled: {
handler(newDisabled) {
this.showForm = this.disabled ? this.form : this.copyForm
if (newDisabled) {
this.showForm = this.form
this.copyForm = _.cloneDeep(this.form)
} else {
this.showForm = _.cloneDeep(this.copyForm)
}
}
},
form: {
handler() {
this.copyForm = _.cloneDeep(this.form)
this.showForm = _.cloneDeep(this.form)
const targetId = this.productValues.find(item => item.paramName === '位置容器数')?.id
// console.log(targetId, this.form[targetId]?.length > 0 && this.form[targetId][0] !== '')
;(this.form[targetId]?.length > 0 && this.form[targetId][0] !== '') ? (this.isShowContainerType = true) : (this.isShowContainerType = false)
},
deep: true,
immediate: true
}
}
}
</script>
<style lang="scss" scoped>
.product-base-info-form {
.link-item-box {
.link-type {
margin: 0 2px;
display: inline-block;
}
}
& > .columns {
display: flex;
flex-flow: column;
section.column-item {
display: flex;
flex-flow: row wrap;
justify-content: space-between;
align-items: center;
p.lable {
flex-grow: 1;
color: #8c8c8c;
font-size: 14px;
user-select: none;
}
.right {
width: 304px;
}
}
}
}
.custom-fields,
.columns {
margin-right: 25px;
::v-deep div.ant-row.ant-form-item {
display: flex !important;
flex-flow: row wrap;
justify-content: space-between;
align-items: center;
}
::v-deep div.ant-col.ant-col-8.ant-form-item-label.ant-form-item-label-left {
background-color: red;
flex-grow: 1;
color: #8c8c8c;
font-size: 14px;
user-select: none;
}
::v-deep .ant-col.ant-col-12.ant-form-item-control-wrapper {
width: 304px;
input.ant-input {
width: 304px;
}
}
}
</style>
<template>
<div class="product-base-info-form">
<!-- {{ copyForm }} -- {{ form }} -- {{ disabled }} -->
<!-- {{ showForm }} -->
<a-form-model
ref="productBaseInfoRef"
:model="showForm"
:rules="rules"
labelAlign="left"
:label-col="labelCol"
:wrapper-col="wrapperCol"
:colon="false"
>
<div v-if="frameId === STOCK_FRAME_TYPE.CONTAINER" :gutter="12">
<div v-if="!disabled">
<a-form-model-item
prop="icon"
:label-col="labelColItem"
:wrapper-col="{ span: 4 }"
>
<a-select v-model="showForm.icon" placeholder="图标">
<a-select-option
:key="index"
:value="item"
v-for="(item, index) in productIcons"
>
<!-- <a-icon :type="item" style="font-size: 16px" /> -->
<svg-icon :icon-class="item" :style="{ fontSize: '16px' }" />
</a-select-option>
</a-select>
</a-form-model-item>
<section class="column-item">
<p class="lable">产品名称</p>
<a-form-model-item
class="right"
prop="name"
:label-col="labelColItem"
:wrapper-col="{ span: 8 }"
>
<a-input v-model="showForm.name" placeholder="名称"></a-input>
</a-form-model-item>
</section>
<section class="column-item">
<p class="lable">编码(Prefix)</p>
<a-form-model-item
class="right"
prop="prefix"
:label-col="labelColItem"
:wrapper-col="{ span: 8 }"
>
<a-input v-model="showForm.prefix" placeholder="prefix"></a-input>
</a-form-model-item>
</section>
</div>
<a-form-model-item label="容器单位" prop="unitId">
<span v-if="disabled">
{{ unitOptions.filter(item => item.id == showForm.unitId)[0].unitName }}
</span>
<a-select
v-else
@dropdownVisibleChange="dropdownVisibleChange"
v-model="showForm.unitId"
placeholder="请选择"
>
<a-select-option
:key="item.id"
:value="item.id"
v-for="item in unitOptions"
>
{{ item.unitName }}
</a-select-option>
<template v-slot:notFoundContent v-if="spinning">
<a-spin :spinning="spinning"></a-spin>
</template>
</a-select>
</a-form-model-item>
<a-form-model-item label="上限容量" prop="capacity">
<span v-if="disabled">{{ showForm.capacity }}</span>
<a-input v-else v-model="showForm.capacity"></a-input>
</a-form-model-item>
</div>
<!-- frameId !== STOCK_FRAME_TYPE.CONTAINER -->
<!-- 可编辑状态 -->
<div v-else>
<div v-if="!disabled">
<a-form-model-item
prop="icon"
:label-col="labelColItem"
:wrapper-col="{ span: 6 }"
label="图标"
>
<a-select v-model="showForm.icon" placeholder="图标">
<a-select-option
:key="index"
:value="item"
v-for="(item, index) in productIcons"
>
<!-- <a-icon :type="item" style="font-size: 16px" /> -->
<svg-icon :icon-class="item" :style="{ fontSize: '16px' }" />
</a-select-option>
</a-select>
</a-form-model-item>
<a-form-model-item
class="right"
prop="name"
:label-col="labelColItem"
:wrapper-col="{ span: 8 }"
label="产品名称"
>
<a-input v-model="showForm.name" placeholder="名称"></a-input>
</a-form-model-item>
<a-form-model-item
class="right"
prop="prefix"
:label-col="labelColItem"
:wrapper-col="{ span: 8 }"
label="编码(Prefix)"
>
<a-input v-model="showForm.prefix" placeholder="prefix"></a-input>
</a-form-model-item>
</div>
</div>
<!-- <div class="custom-fields"> -->
<a-form-model-item
v-for="item in productValues"
:label="item.paramName"
:prop="item.id"
:key="item.id"
:label-col="labelColItem"
:wrapper-col="wrapperColItem"
>
<!-- 不是容器的渲染在这里 -->
<template v-if="item.paramType !== paramTypeColumn.container">
<div
v-if="
paramTypeColumn.text === item.paramType ||
paramTypeColumn.integer === item.paramType ||
paramTypeColumn.float === item.paramType
"
>
<template v-if="disabled">
<span v-if="item.isMultipleValue === 2">{{
showForm[item.id][0]
}}</span>
<a-tag v-else :key="index" v-for="(ele, index) in showForm[item.id]">
{{ ele }}
</a-tag>
</template>
<template v-else>
<a-input
v-if="item.isMultipleValue === 2"
v-model="showForm[item.id][0]"
></a-input>
<a-select
v-else
v-model="showForm[item.id]"
:dropdownStyle="{ display: 'none' }"
:dropdownMenuStyle="{ display: 'none' }"
mode="tags"
></a-select>
</template>
</div>
<div v-else-if="paramTypeColumn.textArea === item.paramType">
<span v-if="disabled">{{ showForm[item.id][0] }}</span>
<a-input
v-else
:auto-size="{ minRows: 3, maxRows: 5 }"
v-model="showForm[item.id][0]"
type="textarea"
></a-input>
</div>
<div v-else-if="paramTypeColumn.radioSelect === item.paramType">
<span v-if="disabled">{{ showForm[item.id][0] }}</span>
<a-select v-else v-model="showForm[item.id][0]">
<a-select-option
:key="element"
v-for="element in item.preDefinedValues"
>
{{ element }}
</a-select-option>
</a-select>
</div>
<div v-else-if="paramTypeColumn.multiSelect === item.paramType">
<div v-if="disabled">
<a-tag :key="index" v-for="(ele, index) in showForm[item.id]">
{{ ele }}
</a-tag>
</div>
<a-select v-else mode="multiple" v-model="showForm[item.id]">
<a-select-option
:key="element"
v-for="element in item.preDefinedValues"
>
{{ element }}
</a-select-option>
</a-select>
</div>
<div v-else-if="paramTypeColumn.time === item.paramType">
<span v-if="disabled">{{
item.paramValues[0] &&
moment(item.paramValues[0]).format('YYYY-MM-DD HH:mm:ss')
}}</span>
<a-date-picker
v-else
v-model="item.paramValues[0]"
:showTime="true"
></a-date-picker>
</div>
<div v-else-if="paramTypeColumn.link === item.paramType">
<!-- <span>产品链接类型。。。</span> -->
<!-- 展示产品链接 -->
<div v-if="disabled">
<div class="link-item-box">
<li
class="link-type"
:key="ele.referenceId"
v-for="ele in item.paramValues"
@click="showProductLinkDetail(ele)"
>
<a-icon type="link" />{{ ele.referenceName }}
</li>
</div>
</div>
<div v-else>
<a-button @click="selectProduct(item.paramValues)" size="small"
><a-icon type="fullscreen" />选择产品</a-button
>
<div class="link-item-box">
<li
class="link-type"
:key="ele.referenceId"
v-for="ele in item.paramValues"
@click="showProductLinkDetail(ele)"
>
<a-icon type="link" /> {{ ele.referenceName }}
</li>
</div>
</div>
</div>
<div v-else-if="paramTypeColumn.cycle === item.paramType">
<div v-if="disabled">
<span
v-if="item.paramValues[0].value && item.paramValues[0].cycleType"
>{{
`${item.paramValues[0].value} ${
CycleTypeInfo[item.paramValues[0].cycleType]
}`
}}</span
>
</div>
<!-- 周期 -->
<CycleTypeCom
v-else
:info="item.paramValues[0]"
style="width: 260px"
/>
</div>
</template>
<template v-else-if="
(item.paramType === paramTypeColumn.container && isShowContainerType) ||
(item.paramType === paramTypeColumn.container && frameId === STOCK_FRAME_TYPE.BOX) ||
(item.paramType === paramTypeColumn.container && frameId === STOCK_FRAME_TYPE.PLATE)
">
<!-- 选择的关联容器 -->
<span v-if="disabled">
{{ showForm[item.id][0].containerName }}
</span>
<a-select v-else :default-value="showForm[item.id][0].containerId" @change="(id) => handleChangeContainer(id, showForm[item.id])" show-search>
<!-- 关联容器列表 -->
<a-select-option
:key="element.id"
v-for="element in ContainerOptions"
:value="element.id"
>
{{ element.name }}
</a-select-option>
<template v-slot:notFoundContent v-if="spinning">
<a-spin :spinning="spinning"></a-spin>
</template>
</a-select>
</template>
</a-form-model-item>
<!-- </div> -->
</a-form-model>
<product-link-modal ref="productLinkModalRef"></product-link-modal>
<product-base-info-modal
ref="productBaseInfoModalRef"
></product-base-info-modal>
</div>
</template>
<script>
import moment from 'moment'
import { queryStockSchemasDetail } from '@/api/material/locationSetting'
import {
handleMaterialValidateCodePlus,
validateInteger,
validateFloat,
validateFloatNumber,
validateArrRequired
} from '@/common/inspectFunction'
import {
paramTypeColumn,
productIcons,
STOCK_FRAME_TYPE,
VOLUME_TYPE_UNIT,
CycleTypeInfo
} from '@/common/global'
import { getFullUnitInfo } from '@/api/system/unit'
import ProductBaseInfoModal from './ProductBaseInfoModal'
import ProductLinkModal from './ProductLinkModal'
import CycleTypeCom from './fieldRuleSetting/CycleTypeCom'
export default {
props: {
productValues: {
type: Array,
default() {
return []
}
},
productSelfInfo: {
type: Object,
default() {
return {}
}
},
icons: {
type: Array,
default() {
return []
}
},
frameId: {
type: String,
default() {
return ''
}
}
},
components: {
ProductBaseInfoModal,
ProductLinkModal,
CycleTypeCom
},
data() {
return {
CycleTypeInfo,
productIcons: this.icons,
labelCol: { span: 8 },
wrapperCol: { span: 12 },
labelColItem: { span: 8 },
wrapperColItem: { span: 12 },
paramTypeColumn: Object.freeze(paramTypeColumn),
baseInfo: {
prefix: '',
name: '',
icon: '',
unitId: undefined,
capacity: undefined,
version: undefined
},
form: {
prefix: '',
name: '',
icon: '',
unitId: undefined,
capacity: '',
version: undefined
},
showForm: {},
rules: {
prefix: [
{ required: true, message: '请填写编号', trigger: 'blur' },
{
min: 1,
max: 32,
message: '编号长度在1-32个字符之间',
trigger: 'change'
},
{
validator: this.handleMaterialValidateCodePlus,
message: '编号格式不正确',
trigger: 'change'
}
],
unitId: [{ required: true, message: '请填写单位', trigger: 'blur' }],
capacity: [
{
validator: this.validateFloatNumber,
message: '容量格式不正确',
trigger: 'change'
}
],
name: [
{ required: true, message: '必填', trigger: 'change' },
{
min: 1,
max: 32,
message: '名称长度在1-32个字符之间',
trigger: 'change'
}
]
},
disabled: true,
// 后端需要的paramType
paramTypeObj: {},
STOCK_FRAME_TYPE: Object.freeze(STOCK_FRAME_TYPE),
unitOptions: [],
ContainerOptions: [],
// tmpContainerId: '',
spinning: true,
// checkContainer: false,
isShowContainerType: false,
}
},
methods: {
moment,
dropdownVisibleChange(open) {
// this.spinning = true
open && _.isEmpty(this.unitOptions) && this.getFullUnitInfo()
},
/**
* 获取数据库预选单位
*/
async getFullUnitInfo() {
this.spinning = true
const res = await getFullUnitInfo({
artifacts: [VOLUME_TYPE_UNIT],
pageSize: -1
}).finally(() => {
this.spinning = false
})
if (res.code === '200') {
this.unitOptions = res.data
}
},
/**
* 获取数据库容器
*/
async getFullContainerInfo() {
this.ContainerOptions = []
this.spinning = true
const res = await queryStockSchemasDetail({
stockFrameId: '3',
pageSize: -1
}).finally(() => {
this.spinning = false
})
if (res.code === '200') {
this.ContainerOptions = res.data.result
// return res.data.result
}
},
/**
* 自定义编码规则
*/
handleMaterialValidateCodePlus,
/**
* 整数自定义验证
*/
validateInteger,
/**
* 浮点数自定义验证
*/
validateFloat,
validateFloatNumber,
validateArrRequired,
/**
* 验证表单数据规则是否匹配
*/
validateFormData() {
let flag = false
this.$refs.productBaseInfoRef.validate(valid => {
flag = valid
})
return flag
},
/**
* 选择产品
*/
selectProduct(paramValues) {
this.$refs.productLinkModalRef.openSelectProductInfoModal(paramValues)
},
/**
* 展示产品详情
*/
showProductLinkDetail(item) {
this.$refs.productBaseInfoModalRef.openProductInfoModal({
id: item.referenceId
})
},
/**
* 传输产品基本信息和产品种类自定义字段
*/
async getFullData(callback) {
if (!this.validateFormData()) {
return
// callback(false)
}
const target = _.cloneDeep(this.showForm)
let targetArr = []
// {...this.baseInfo} = target
Object.keys(this.baseInfo).forEach(key => {
this.baseInfo[key] = target[key]
delete target[key]
})
// console.log(target);
Object.keys(target).forEach(key => {
targetArr.push({
id: key,
paramValues: target[key],
paramType: this.paramTypeObj[key]
})
})
const _form = { ..._.cloneDeep(this.showForm), version: this.showForm.version + 1 }
await callback({ ...this.baseInfo, productValues: targetArr })
this.form = _form
// this.changeNoShowStatus()
},
/**
* 改变为可以编辑的状态
*/
changeIsShowStatus() {
this.disabled = false
},
/**
* 改变为不可编辑的状态
*/
changeNoShowStatus() {
this.disabled = true
},
/**
* 清除 form 表单 多余信息
*/
resetFormInfo() {
this.$refs.productBaseInfoRef &&
this.$refs.productBaseInfoRef.resetFields &&
this.$refs.productBaseInfoRef.resetFields()
const baseInfoKeys = Object.keys(this.baseInfo)
Object.keys(this.form)
.filter(item => {
return !baseInfoKeys.includes(item)
})
.forEach(key => {
delete this.form[key]
})
},
/**
* 改变 container
*/
handleChangeContainer(id, target) {
const findContainer = this.ContainerOptions.find(v => v.id === id)
const { id: containerId, name: containerName } = findContainer
target[0] = { containerId, containerName }
}
},
created() {
this.frameId === STOCK_FRAME_TYPE.CONTAINER &&
this.dropdownVisibleChange(true)
},
watch: {
productValues: {
handler(newProductValues) {
// console.log(newProductValues);
// this.tmpContainerId = ''
this.resetFormInfo()
this.getFullContainerInfo()
newProductValues.forEach(element => {
this.paramTypeObj[element.id] = element.paramType
this.$set(this.form, element.id, element.paramValues || [])
// 给预设容器默认值防止v-model取不到值
if (element.paramType === this.paramTypeColumn.container) {
if (!this.form[element.id][0]) {
this.$set(this.form, element.id, [{
containerId: null,
containerName: ''
}])
}
}
// 控制位置容器数没有值预设容器不必填
// if (element.fieldName === "位置容器数") {
// this.checkContainer = true
// }
// 必填项
if (element.isRequired === 1) {
const requiredInfo = [
{ validator: this.validateArrRequired, trigger: 'change' },
{ required: true, message: '必填', trigger: 'change' }
]
!this.rules[element.id] &&
this.$set(this.rules, element.id, requiredInfo)
if (
this.rules[element.id] &&
this.rules[element.id].findIndex(item => item.required) < 0
) {
this.rules[element.id].push(...requiredInfo)
}
// this.rules[element.id] = [{ required: true, message: '必填', trigger: 'change' }]
}
// 整数
if (element.paramType === this.paramTypeColumn.integer) {
!this.rules[element.id] &&
this.$set(this.rules, element.id, [
{ validator: this.validateInteger }
])
this.rules[element.id] &&
this.rules[element.id].push({
validator: this.validateInteger
})
}
// 浮点数
if (element.paramType === this.paramTypeColumn.float) {
!this.rules[element.id] &&
this.$set(this.rules, element.id, [
{ validator: this.validateFloat }
])
this.rules[element.id] &&
this.rules[element.id].push({
validator: this.validateFloat
})
}
// 覆盖预设容器的规则
// if (this.checkContainer && element.paramType === this.paramTypeColumn.container) {
// this.rules[element.id] &&
// this.$set(this.rules, element.id, [])
// // this.rules[element.id] &&
// // this.rules[element.id].push([])
// this.checkContainer = false
// }
})
},
immediate: true
},
productSelfInfo: {
handler(newProductSelfInfo) {
this.form.name = newProductSelfInfo.name
this.form.prefix = newProductSelfInfo.prefix
this.form.icon = newProductSelfInfo.icon
this.form.unitId = newProductSelfInfo.unitId
this.form.capacity = newProductSelfInfo.capacity
this.form.version = newProductSelfInfo.version
},
immediate: true,
deep: true
},
frameId: {
handler(newFramaId) {
newFramaId === STOCK_FRAME_TYPE.CONTAINER &&
this.dropdownVisibleChange(true)
},
immediate: true
},
disabled: {
handler(newDisabled) {
this.showForm = this.disabled ? this.form : this.copyForm
if (newDisabled) {
this.showForm = this.form
this.copyForm = _.cloneDeep(this.form)
} else {
this.showForm = _.cloneDeep(this.copyForm)
}
}
},
form: {
handler() {
this.copyForm = _.cloneDeep(this.form)
this.showForm = _.cloneDeep(this.form)
// Object.keys()
const targetId = this.productValues.find(item => item.paramName === '位置容器数')?.id
// console.log(targetId, this.form[targetId]?.length > 0 && this.form[targetId][0] !== '')
if (this.showForm[targetId]?.length > 0 && this.showForm[targetId][0] !== '') {
this.isShowContainerType = true
} else {
this.showForm[targetId]?.length > 0 && this.showForm[targetId][0] === '' && this.showForm[targetId].splice(0)
this.isShowContainerType = false
}
},
deep: true,
immediate: true
},
isShowContainerType: {
handler() {
if(!this.isShowContainerType) {
const containerId = this.productValues.find(item => item.paramName === '预设容器')?.id
this.showForm[containerId] = []
}
}
}
}
}
</script>
<style lang="scss" scoped>
.product-base-info-form {
.link-item-box {
.link-type {
margin: 0 2px;
display: inline-block;
}
}
& > .columns {
display: flex;
flex-flow: column;
section.column-item {
display: flex;
flex-flow: row wrap;
justify-content: space-between;
align-items: center;
p.lable {
flex-grow: 1;
color: #8c8c8c;
font-size: 14px;
user-select: none;
}
.right {
width: 304px;
}
}
}
}
.custom-fields,
.columns {
margin-right: 25px;
::v-deep div.ant-row.ant-form-item {
display: flex !important;
flex-flow: row wrap;
justify-content: space-between;
align-items: center;
}
::v-deep div.ant-col.ant-col-8.ant-form-item-label.ant-form-item-label-left {
background-color: red;
flex-grow: 1;
color: #8c8c8c;
font-size: 14px;
user-select: none;
}
::v-deep .ant-col.ant-col-12.ant-form-item-control-wrapper {
width: 304px;
input.ant-input {
width: 304px;
}
}
}
</style>
最终版:
在disable为真或假的时候展示两套状态,用的是showForm展示,在disable为真时,showForm是form,为假时,showForm为深克隆copyForm。
<template>
<div class="product-base-info-form">
<!-- {{ copyForm }} -- {{ form }} -- {{ disabled }} -->
<!-- {{ showForm }} -->
<a-form-model
ref="productBaseInfoRef"
:model="showForm"
:rules="rules"
labelAlign="left"
:label-col="labelCol"
:wrapper-col="wrapperCol"
:colon="false"
>
<a-row>
<a-col>
<div v-if="frameId === STOCK_FRAME_TYPE.CONTAINER" :gutter="12">
<div v-if="!disabled">
<a-form-model-item
prop="icon"
:label-col="labelColItem"
:wrapper-col="{ span: 4 }"
>
<a-select v-model="showForm.icon" placeholder="图标">
<a-select-option
:key="index"
:value="item"
v-for="(item, index) in productIcons"
>
<!-- <a-icon :type="item" style="font-size: 16px" /> -->
<svg-icon :icon-class="item" :style="{ fontSize: '16px' }" />
</a-select-option>
</a-select>
</a-form-model-item>
<section class="column-item">
<p class="lable">产品名称</p>
<a-form-model-item
class="right"
prop="name"
:label-col="labelColItem"
:wrapper-col="{ span: 8 }"
>
<a-input v-model="showForm.name" placeholder="名称"></a-input>
</a-form-model-item>
</section>
<section class="column-item">
<p class="lable">编码(Prefix)</p>
<a-form-model-item
class="right"
prop="prefix"
:label-col="labelColItem"
:wrapper-col="{ span: 8 }"
>
<a-input v-model="showForm.prefix" placeholder="prefix"></a-input>
</a-form-model-item>
</section>
</div>
<a-form-model-item label="容器单位" prop="unitId">
<span v-if="disabled">
{{ unitOptions.filter(item => item.id == showForm.unitId)[0].unitName }}
</span>
<a-select
v-else
@dropdownVisibleChange="dropdownVisibleChange"
v-model="showForm.unitId"
placeholder="请选择"
>
<a-select-option
:key="item.id"
:value="item.id"
v-for="item in unitOptions"
>
{{ item.unitName }}
</a-select-option>
<template v-slot:notFoundContent v-if="spinning">
<a-spin :spinning="spinning"></a-spin>
</template>
</a-select>
</a-form-model-item>
<a-form-model-item label="上限容量" prop="capacity">
<span v-if="disabled">{{ showForm.capacity }}</span>
<a-input v-else v-model="showForm.capacity"></a-input>
</a-form-model-item>
</div>
<!-- frameId !== STOCK_FRAME_TYPE.CONTAINER -->
<!-- 可编辑状态 -->
<div v-else>
<div v-if="!disabled">
<a-form-model-item
prop="icon"
:label-col="labelColItem"
:wrapper-col="{ span: 6 }"
label="图标"
>
<a-select v-model="showForm.icon" placeholder="图标">
<a-select-option
:key="index"
:value="item"
v-for="(item, index) in productIcons"
>
<!-- <a-icon :type="item" style="font-size: 16px" /> -->
<svg-icon :icon-class="item" :style="{ fontSize: '16px' }" />
</a-select-option>
</a-select>
</a-form-model-item>
<a-form-model-item
class="right"
prop="name"
:label-col="labelColItem"
:wrapper-col="{ span: 8 }"
label="产品名称"
>
<a-input v-model="showForm.name" placeholder="名称"></a-input>
</a-form-model-item>
<a-form-model-item
class="right"
prop="prefix"
:label-col="labelColItem"
:wrapper-col="{ span: 8 }"
label="编码(Prefix)"
>
<a-input v-model="showForm.prefix" placeholder="prefix"></a-input>
</a-form-model-item>
</div>
</div>
</a-col>
<a-col
v-for="item in productValues"
:key="item.id"
:label-col="labelColItem"
:wrapper-col="wrapperColItem">
<!-- 不是容器的渲染在这里 -->
<template v-if="item.paramType !== paramTypeColumn.container">
<a-form-model-item
:label="item.paramName" :prop="item.id"
>
<div
v-if="
paramTypeColumn.text === item.paramType ||
paramTypeColumn.integer === item.paramType ||
paramTypeColumn.float === item.paramType
"
>
<template v-if="disabled">
<span v-if="item.isMultipleValue === 2">{{
showForm[item.id][0]
}}</span>
<a-tag v-else :key="index" v-for="(ele, index) in showForm[item.id]">
{{ ele }}
</a-tag>
</template>
<template v-else>
<a-input
v-if="item.isMultipleValue === 2"
v-model="showForm[item.id][0]"
></a-input>
<a-select
v-else
v-model="showForm[item.id]"
:dropdownStyle="{ display: 'none' }"
:dropdownMenuStyle="{ display: 'none' }"
mode="tags"
></a-select>
</template>
</div>
<div v-else-if="paramTypeColumn.textArea === item.paramType">
<span v-if="disabled">{{ showForm[item.id][0] }}</span>
<a-input
v-else
:auto-size="{ minRows: 3, maxRows: 5 }"
v-model="showForm[item.id][0]"
type="textarea"
></a-input>
</div>
<div v-else-if="paramTypeColumn.radioSelect === item.paramType">
<span v-if="disabled">{{ showForm[item.id][0] }}</span>
<a-select v-else v-model="showForm[item.id][0]">
<a-select-option
:key="element"
v-for="element in item.preDefinedValues"
>
{{ element }}
</a-select-option>
</a-select>
</div>
<div v-else-if="paramTypeColumn.multiSelect === item.paramType">
<div v-if="disabled">
<a-tag :key="index" v-for="(ele, index) in showForm[item.id]">
{{ ele }}
</a-tag>
</div>
<a-select v-else mode="multiple" v-model="showForm[item.id]">
<a-select-option
:key="element"
v-for="element in item.preDefinedValues"
>
{{ element }}
</a-select-option>
</a-select>
</div>
<div v-else-if="paramTypeColumn.time === item.paramType">
<span v-if="disabled">{{
item.paramValues[0] &&
moment(item.paramValues[0]).format('YYYY-MM-DD HH:mm:ss')
}}</span>
<a-date-picker
v-else
v-model="item.paramValues[0]"
:showTime="true"
></a-date-picker>
</div>
<div v-else-if="paramTypeColumn.link === item.paramType">
<!-- <span>产品链接类型。。。</span> -->
<!-- 展示产品链接 -->
<div v-if="disabled">
<div class="link-item-box">
<li
class="link-type"
:key="ele.referenceId"
v-for="ele in item.paramValues"
@click="showProductLinkDetail(ele)"
>
<a-icon type="link" />{{ ele.referenceName }}
</li>
</div>
</div>
<div v-else>
<a-button @click="selectProduct(item.paramValues)" size="small"
><a-icon type="fullscreen" />选择产品</a-button
>
<div class="link-item-box">
<li
class="link-type"
:key="ele.referenceId"
v-for="ele in item.paramValues"
@click="showProductLinkDetail(ele)"
>
<a-icon type="link" /> {{ ele.referenceName }}
</li>
</div>
</div>
</div>
<div v-else-if="paramTypeColumn.cycle === item.paramType">
<div v-if="disabled">
<span
v-if="item.paramValues[0].value && item.paramValues[0].cycleType"
>{{
`${item.paramValues[0].value} ${
CycleTypeInfo[item.paramValues[0].cycleType]
}`
}}</span
>
</div>
<!-- 周期 -->
<CycleTypeCom
v-else
:info="item.paramValues[0]"
style="width: 260px"
/>
</div>
</a-form-model-item>
</template>
<template v-if="
(item.paramType === paramTypeColumn.container && isShowContainerType) ||
(item.paramType === paramTypeColumn.container && frameId === STOCK_FRAME_TYPE.BOX) ||
(item.paramType === paramTypeColumn.container && frameId === STOCK_FRAME_TYPE.PLATE)
">
<a-form-model-item
:label="item.paramName" :prop="item.id"
>
<!-- 选择的关联容器 -->
<span v-if="disabled">
{{ showForm[item.id][0].containerName }}
</span>
<a-select v-else :default-value="showForm[item.id][0].containerId" @change="(id) => handleChangeContainer(id, showForm[item.id])" show-search>
<!-- 关联容器列表 -->
<a-select-option
:key="element.id"
v-for="element in ContainerOptions"
:value="element.id"
>
{{ element.name }}
</a-select-option>
<template v-slot:notFoundContent v-if="spinning">
<a-spin :spinning="spinning"></a-spin>
</template>
</a-select>
</a-form-model-item>
</template>
</a-col>
</a-row>
<!-- </div> -->
</a-form-model>
<product-link-modal ref="productLinkModalRef"></product-link-modal>
<product-base-info-modal
ref="productBaseInfoModalRef"
></product-base-info-modal>
</div>
</template>
<script>
import moment from 'moment'
import { queryStockSchemasDetail } from '@/api/material/locationSetting'
import {
handleMaterialValidateCodePlus,
validateInteger,
validateFloat,
validateFloatNumber,
validateArrRequired
} from '@/common/inspectFunction'
import {
paramTypeColumn,
productIcons,
STOCK_FRAME_TYPE,
VOLUME_TYPE_UNIT,
CycleTypeInfo
} from '@/common/global'
import { getFullUnitInfo } from '@/api/system/unit'
import ProductBaseInfoModal from './ProductBaseInfoModal'
import ProductLinkModal from './ProductLinkModal'
import CycleTypeCom from './fieldRuleSetting/CycleTypeCom'
export default {
props: {
productValues: {
type: Array,
default() {
return []
}
},
productSelfInfo: {
type: Object,
default() {
return {}
}
},
icons: {
type: Array,
default() {
return []
}
},
frameId: {
type: String,
default() {
return ''
}
}
},
components: {
ProductBaseInfoModal,
ProductLinkModal,
CycleTypeCom
},
data() {
return {
CycleTypeInfo,
productIcons: this.icons,
labelCol: { span: 8 },
wrapperCol: { span: 12 },
labelColItem: { span: 8 },
wrapperColItem: { span: 12 },
paramTypeColumn: Object.freeze(paramTypeColumn),
baseInfo: {
prefix: '',
name: '',
icon: '',
unitId: undefined,
capacity: undefined,
version: undefined
},
form: {
prefix: '',
name: '',
icon: '',
unitId: undefined,
capacity: '',
version: undefined
},
showForm: {},
rules: {
prefix: [
{ required: true, message: '请填写编号', trigger: 'blur' },
{
min: 1,
max: 32,
message: '编号长度在1-32个字符之间',
trigger: 'change'
},
{
validator: this.handleMaterialValidateCodePlus,
message: '编号格式不正确',
trigger: 'change'
}
],
unitId: [{ required: true, message: '请填写单位', trigger: 'blur' }],
capacity: [
{
validator: this.validateFloatNumber,
message: '容量格式不正确',
trigger: 'change'
}
],
name: [
{ required: true, message: '必填', trigger: 'change' },
{
min: 1,
max: 32,
message: '名称长度在1-32个字符之间',
trigger: 'change'
}
]
},
disabled: true,
// 后端需要的paramType
paramTypeObj: {},
STOCK_FRAME_TYPE: Object.freeze(STOCK_FRAME_TYPE),
unitOptions: [],
ContainerOptions: [],
// tmpContainerId: '',
spinning: true,
// checkContainer: false,
isShowContainerType: false,
}
},
methods: {
moment,
dropdownVisibleChange(open) {
// this.spinning = true
open && _.isEmpty(this.unitOptions) && this.getFullUnitInfo()
},
/**
* 获取数据库预选单位
*/
async getFullUnitInfo() {
this.spinning = true
const res = await getFullUnitInfo({
artifacts: [VOLUME_TYPE_UNIT],
pageSize: -1
}).finally(() => {
this.spinning = false
})
if (res.code === '200') {
this.unitOptions = res.data
}
},
/**
* 获取数据库容器
*/
async getFullContainerInfo() {
this.ContainerOptions = []
this.spinning = true
const res = await queryStockSchemasDetail({
stockFrameId: '3',
pageSize: -1
}).finally(() => {
this.spinning = false
})
if (res.code === '200') {
this.ContainerOptions = res.data.result
// return res.data.result
}
},
/**
* 自定义编码规则
*/
handleMaterialValidateCodePlus,
/**
* 整数自定义验证
*/
validateInteger,
/**
* 浮点数自定义验证
*/
validateFloat,
validateFloatNumber,
validateArrRequired,
/**
* 验证表单数据规则是否匹配
*/
validateFormData() {
let flag = false
this.$refs.productBaseInfoRef.validate(valid => {
flag = valid
})
return flag
},
/**
* 选择产品
*/
selectProduct(paramValues) {
this.$refs.productLinkModalRef.openSelectProductInfoModal(paramValues)
},
/**
* 展示产品详情
*/
showProductLinkDetail(item) {
this.$refs.productBaseInfoModalRef.openProductInfoModal({
id: item.referenceId
})
},
/**
* 传输产品基本信息和产品种类自定义字段
*/
async getFullData(callback) {
if (!this.validateFormData()) {
return
// callback(false)
}
const target = _.cloneDeep(this.showForm)
let targetArr = []
// {...this.baseInfo} = target
Object.keys(this.baseInfo).forEach(key => {
this.baseInfo[key] = target[key]
delete target[key]
})
// console.log(target);
Object.keys(target).forEach(key => {
targetArr.push({
id: key,
paramValues: target[key],
paramType: this.paramTypeObj[key]
})
})
const _form = { ..._.cloneDeep(this.showForm), version: this.showForm.version + 1 }
await callback({ ...this.baseInfo, productValues: targetArr })
this.form = _form
// this.changeNoShowStatus()
},
/**
* 改变为可以编辑的状态
*/
changeIsShowStatus() {
this.disabled = false
},
/**
* 改变为不可编辑的状态
*/
changeNoShowStatus() {
this.disabled = true
},
/**
* 清除 form 表单 多余信息
*/
resetFormInfo() {
this.$refs.productBaseInfoRef &&
this.$refs.productBaseInfoRef.resetFields &&
this.$refs.productBaseInfoRef.resetFields()
const baseInfoKeys = Object.keys(this.baseInfo)
Object.keys(this.form)
.filter(item => {
return !baseInfoKeys.includes(item)
})
.forEach(key => {
delete this.form[key]
})
},
/**
* 改变 container
*/
handleChangeContainer(id, target) {
const findContainer = this.ContainerOptions.find(v => v.id === id)
const { id: containerId, name: containerName } = findContainer
target[0] = { containerId, containerName }
}
},
created() {
this.frameId === STOCK_FRAME_TYPE.CONTAINER &&
this.dropdownVisibleChange(true)
},
watch: {
productValues: {
handler(newProductValues) {
// console.log(newProductValues);
// this.tmpContainerId = ''
this.resetFormInfo()
this.getFullContainerInfo()
newProductValues.forEach(element => {
this.paramTypeObj[element.id] = element.paramType
this.$set(this.form, element.id, element.paramValues || [])
// 给预设容器默认值防止v-model取不到值
if (element.paramType === this.paramTypeColumn.container) {
if (!this.form[element.id][0]) {
this.$set(this.form, element.id, [{
containerId: null,
containerName: ''
}])
}
}
// 控制位置容器数没有值预设容器不必填
// if (element.fieldName === "位置容器数") {
// this.checkContainer = true
// }
// 必填项
if (element.isRequired === 1) {
const requiredInfo = [
{ validator: this.validateArrRequired, trigger: 'change' },
{ required: true, message: '必填', trigger: 'change' }
]
!this.rules[element.id] &&
this.$set(this.rules, element.id, requiredInfo)
if (
this.rules[element.id] &&
this.rules[element.id].findIndex(item => item.required) < 0
) {
this.rules[element.id].push(...requiredInfo)
}
// this.rules[element.id] = [{ required: true, message: '必填', trigger: 'change' }]
}
// 整数
if (element.paramType === this.paramTypeColumn.integer) {
!this.rules[element.id] &&
this.$set(this.rules, element.id, [
{ validator: this.validateInteger }
])
this.rules[element.id] &&
this.rules[element.id].push({
validator: this.validateInteger
})
}
// 浮点数
if (element.paramType === this.paramTypeColumn.float) {
!this.rules[element.id] &&
this.$set(this.rules, element.id, [
{ validator: this.validateFloat }
])
this.rules[element.id] &&
this.rules[element.id].push({
validator: this.validateFloat
})
}
// 覆盖预设容器的规则
// if (this.checkContainer && element.paramType === this.paramTypeColumn.container) {
// this.rules[element.id] &&
// this.$set(this.rules, element.id, [])
// // this.rules[element.id] &&
// // this.rules[element.id].push([])
// this.checkContainer = false
// }
})
},
immediate: true
},
productSelfInfo: {
handler(newProductSelfInfo) {
this.form.name = newProductSelfInfo.name
this.form.prefix = newProductSelfInfo.prefix
this.form.icon = newProductSelfInfo.icon
this.form.unitId = newProductSelfInfo.unitId
this.form.capacity = newProductSelfInfo.capacity
this.form.version = newProductSelfInfo.version
},
immediate: true,
deep: true
},
frameId: {
handler(newFramaId) {
newFramaId === STOCK_FRAME_TYPE.CONTAINER &&
this.dropdownVisibleChange(true)
},
immediate: true
},
disabled: {
handler(newDisabled) {
this.showForm = this.disabled ? this.form : this.copyForm
if (newDisabled) {
this.showForm = this.form
this.copyForm = _.cloneDeep(this.form)
} else {
this.showForm = _.cloneDeep(this.copyForm)
}
}
},
form: {
handler() {
this.copyForm = _.cloneDeep(this.form)
this.showForm = _.cloneDeep(this.form)
},
deep: true,
immediate: true
},
showForm: {
handler() {
// Object.keys()
const targetId = this.productValues.find(item => item.paramName === '位置容器数')?.id
// console.log(targetId, this.form[targetId]?.length > 0 && this.form[targetId][0] !== '')
if (this.showForm[targetId]?.length > 0 && this.showForm[targetId][0] !== '') {
console.log('true');
this.isShowContainerType = true
} else {
this.showForm[targetId]?.length > 0 && this.showForm[targetId][0] === '' && this.showForm[targetId].splice(0)
console.log('false');
this.isShowContainerType = false
}
console.log(1);
},
deep: true
},
isShowContainerType: {
handler() {
if(!this.isShowContainerType) {
const containerId = this.productValues.find(item => item.paramType === 140)?.id
console.log(this.showForm);
this.showForm[containerId].length = 0
}
},
deep: true,
immediate: true
}
}
}
</script>
<style lang="scss" scoped>
.product-base-info-form {
.link-item-box {
.link-type {
margin: 0 2px;
display: inline-block;
}
}
& > .columns {
display: flex;
flex-flow: column;
section.column-item {
display: flex;
flex-flow: row wrap;
justify-content: space-between;
align-items: center;
p.lable {
flex-grow: 1;
color: #8c8c8c;
font-size: 14px;
user-select: none;
}
.right {
width: 304px;
}
}
}
}
.custom-fields,
.columns {
margin-right: 25px;
::v-deep div.ant-row.ant-form-item {
display: flex !important;
flex-flow: row wrap;
justify-content: space-between;
align-items: center;
}
::v-deep div.ant-col.ant-col-8.ant-form-item-label.ant-form-item-label-left {
background-color: red;
flex-grow: 1;
color: #8c8c8c;
font-size: 14px;
user-select: none;
}
::v-deep .ant-col.ant-col-12.ant-form-item-control-wrapper {
width: 304px;
input.ant-input {
width: 304px;
}
}
}
</style>
通过改变预设容器在template的位置,用v-if控制它显示还是隐藏,用一个变量控制,这个变量通过监视属性监听,在动态字段的位置容器数有值的情况下才展示。
<template>
<a-modal
v-if="visible"
:title="title"
:visible="visible"
@ok="handleOk"
@cancel="handleCancel"
:width="800"
:height="900"
:destoryOnClose="true"
:bodyStyle="{ padding: '0px 10px', minHeight: '500px' }"
>
<a-tabs default-active-key="1">
<a-tab-pane key="1" tab="基本信息" style="padding-left: 10px">
<a-row>
<a-form-model
ref="createBatchInfoRef"
:model="form"
:labelCol="{ span: 10 }"
:wrapperCol="{ span: 14 }"
:rules="rules"
>
<a-row :gutter="16">
<a-col :span="12">
<a-form-model-item label="种类" prop="frameName">
<a-input disabled v-model="form.frameName"></a-input>
</a-form-model-item>
</a-col>
<a-col :span="12">
<a-form-model-item label="图标" prop="icon">
<a-select v-model="form.icon">
<a-select-option
:value="item"
:key="index"
v-for="(item, index) in schemaIcons"
>
<!-- <a-icon :type="item" style="font-size: 16px" /> -->
<svg-icon
:icon-class="item"
:style="{ fontSize: '16px' }"
/>
</a-select-option>
</a-select>
</a-form-model-item>
</a-col>
<a-col :span="12">
<a-form-model-item label="编码" prop="prefix">
<a-input v-model="form.prefix"></a-input>
</a-form-model-item>
</a-col>
<a-col :span="12">
<a-form-model-item label="元件名称" prop="name">
<a-input v-model="form.name"></a-input>
</a-form-model-item>
</a-col>
<a-col :span="12" v-if="CONTAINER_TYPE === stockFrameInfo.id">
<a-form-model-item label="单位" prop="unitId">
<a-select
@dropdownVisibleChange="dropdownVisibleChange"
v-model="form.unitId"
placeholder="请选择"
>
<a-select-option
:key="item.id"
:value="item.id"
v-for="item in unitOptions"
>
{{ item.unitName }}
</a-select-option>
<template v-slot:notFoundContent v-if="spinning">
<a-spin :spinning="spinning"></a-spin>
</template>
</a-select>
</a-form-model-item>
</a-col>
<a-col :span="12" v-if="CONTAINER_TYPE === stockFrameInfo.id">
<a-form-model-item label="容量" prop="capacity">
<a-input v-model="form.capacity"></a-input>
</a-form-model-item>
</a-col>
<a-col
:key="item.id"
:span="12"
v-for="item in stockFrameAttribute"
>
<template v-if="item.paramType !== paramTypeColumn.container">
<a-form-model-item :label="item.paramName" :prop="item.id">
<template
v-if="
paramTypeColumn.text === item.paramType ||
paramTypeColumn.integer === item.paramType ||
paramTypeColumn.float === item.paramType
"
>
<a-input
v-if="item.isMultipleValue === 2"
v-model="form[item.id][0]"
></a-input>
<a-select
v-else
v-model="form[item.id]"
:dropdownStyle="{ display: 'none' }"
:dropdownMenuStyle="{ display: 'none' }"
mode="tags"
></a-select>
</template>
<template
v-else-if="paramTypeColumn.textArea === item.paramType"
>
<a-input
:auto-size="{ minRows: 3, maxRows: 5 }"
class="default-input"
v-model="form[item.id][0]"
type="textarea"
></a-input>
</template>
<template
v-else-if="paramTypeColumn.radioSelect === item.paramType"
>
<a-select v-model="form[item.id][0]">
<a-select-option
:key="element"
v-for="element in item.preDefinedValues"
>
{{ element }}
</a-select-option>
</a-select>
</template>
<template
v-else-if="paramTypeColumn.multiSelect === item.paramType"
>
<a-select mode="multiple" v-model="form[item.id]">
<a-select-option
:key="element"
v-for="element in item.preDefinedValues"
>
{{ element }}
</a-select-option>
</a-select>
</template>
<template v-else-if="paramTypeColumn.time === item.paramType">
<a-date-picker
v-model="item.paramValues[0]"
:showTime="true"
></a-date-picker>
</template>
<template v-else-if="paramTypeColumn.link === item.paramType">
<span
class="link-type"
:key="ele.referenceId"
v-for="ele in item.paramValues"
@click="showProductLinkDetail(ele)"
><a-icon type="link" /> {{ ele.referenceName }}</span
>
</template>
<!-- <template
v-else-if="paramTypeColumn.container === item.paramType && isShowContainerType"
>
<a-select
allowClear
@dropdownVisibleChange="dropdownVisibleChange2"
@change="
id => {
handleChangeContainer(id, form[item.id])
}
"
>
<a-select-option
:key="element.id"
v-for="element in ContainerOptions"
:value="element.id"
>
{{ element.name }}
</a-select-option>
<template v-slot:notFoundContent v-if="spinning">
<a-spin :spinning="spinning"></a-spin>
</template>
</a-select>
</template> -->
</a-form-model-item>
</template>
<template v-else-if="
(item.paramType === paramTypeColumn.container && isShowContainerType) ||
(item.paramType === paramTypeColumn.container && stockFrameInfo.name === '盒') ||
(item.paramType === paramTypeColumn.container && stockFrameInfo.name === '板')
">
<a-form-model-item :label="item.paramName" :prop="item.id">
<a-select
show-search
@dropdownVisibleChange="dropdownVisibleChange2"
@change="
id => {
handleChangeContainer(id, form[item.id])
}
"
>
<a-select-option
:key="element.id"
v-for="element in ContainerOptions"
:value="element.id"
>
{{ element.name }}
</a-select-option>
<template v-slot:notFoundContent v-if="spinning">
<a-spin :spinning="spinning"></a-spin>
</template>
</a-select>
</a-form-model-item>
</template>
</a-col>
</a-row>
</a-form-model>
</a-row>
<span>元件字段:</span>
<custom-fields
@getData="getCustomFieldsData"
ref="customFieldsRef"
></custom-fields>
<span>库位字段:</span>
<storage-fields
ref="storageFieldsRef"
@getData="getStorageLocationFieldsData"
:showMode="showMode.productKey"
>
</storage-fields>
</a-tab-pane>
<a-tab-pane
key="2"
tab="规则设置"
style="padding-left: 10px"
></a-tab-pane>
</a-tabs>
</a-modal>
</template>
<script>
import {
queryStockFrameFields,
saveStockSchema,
queryStockSchemasDetail
} from '@/api/material/locationSetting'
import { getFullUnitInfo } from '@/api/system/unit'
import {
handleValidateCodePlus,
validateInteger,
validateFloat,
validateFloatNumber,
validateArrRequired
} from '@/common/inspectFunction'
import { paramTypeColumn, schemaIcons, VOLUME_TYPE_UNIT } from '@/common/global'
import CustomFields from '@/views/materialcenter/productManagement/components/ProductCustomFields'
import { CUSTOM_FIELD_SHOW_MODE } from '@/views/materialcenter/productManagement/components/comm/constValues'
const CONTAINER_TYPE = '3'
export default {
components: {
CustomFields,
StorageFields: CustomFields
},
props: {
leftSuccess: Function,
schemaRightSuccess: Function
},
data() {
return {
schemaIcons: Object.freeze(schemaIcons),
source: '',
stockFrameInfo: {},
visible: false,
title: '新建元件',
paramTypeColumn: Object.freeze(paramTypeColumn),
baseInfo: {
frameName: '',
icon: '',
prefix: '',
name: '',
unitId: undefined,
capacity: undefined
},
form: {
frameName: '',
icon: '',
prefix: '',
name: '',
unitId: undefined,
capacity: undefined
},
rules: {
prefix: [
{
min: 1,
max: 64,
required: true,
message: '编码的长度在1~64位之间',
trigger: 'change'
},
{
validator: this.handleValidateCodePlus,
message: '编号格式不正确',
trigger: 'change'
}
],
name: [
{
min: 1,
max: 32,
required: true,
message: '元件名称的长度在1~32位之间',
trigger: 'change'
}
],
capacity: [
{
validator: this.validateFloatNumber
},
{
required: true,
message: '容量为必填',
trigger: 'blur'
}
],
unitId: [
{
required: true,
message: '请填写单位',
trigger: 'blur'
}
]
},
stockFrameAttribute: [],
// 后端需要的paramType
paramTypeObj: {},
showMode: Object.freeze(CUSTOM_FIELD_SHOW_MODE),
customFieldsData: [],
storageFieldData: [],
unitOptions: [], // 单位选项
CONTAINER_TYPE,
spinning: true,
ContainerOptions: [], //容器选项
tempContainer: '',
checkContainer: false,
isShowContainerType: false,
}
},
methods: {
dropdownVisibleChange(open) {
// this.spinning = true
open && _.isEmpty(this.unitOptions) && this.getFullUnitInfo()
},
/**
* 获取数据库预选单位
*/
async getFullUnitInfo() {
this.spinning = true
const res = await getFullUnitInfo({
artifacts: [VOLUME_TYPE_UNIT],
pageSize: -1
}).finally(() => {
this.spinning = false
})
if (res.code === '200') {
this.unitOptions = res.data
}
},
dropdownVisibleChange2(open) {
open && _.isEmpty(this.ContainerOptions) && this.getFullContainerInfo()
},
/**
* 获取数据库容器
*/
async getFullContainerInfo() {
this.spinning = true
const res = await queryStockSchemasDetail({
stockFrameId: '3',
pageSize: -1
}).finally(() => {
this.spinning = false
})
if (res.code === '200') {
this.ContainerOptions = res.data.result
}
},
/**
* 自定义编码规则
*/
handleValidateCodePlus,
/**
* 整数自定义验证
*/
validateInteger,
/**
* 浮点数自定义验证
*/
validateFloat,
validateFloatNumber,
/**
* 后端给的值是数组
* 自定义必填
*/
validateArrRequired,
/**
* 动态表单校验
*/
dynamicValidate(element) {
// 必填项
// console.log(element);
// 位置容器数没有值预设容器不必填
// if (element.fieldName === "位置容器数") {
// this.checkContainer = true
// }
if (element.isRequired === 1) {
const requiredInfo = [
{ validator: this.validateArrRequired, trigger: 'change' },
{ required: true, message: '必填', trigger: 'change' }
]
!this.rules[element.id] &&
this.$set(this.rules, element.id, requiredInfo)
if (
this.rules[element.id] &&
this.rules[element.id].findIndex(item => item.required) < 0
) {
this.rules[element.id].push(...requiredInfo)
}
// this.rules[element.id] = [{ required: true, message: '必填', trigger: 'change' }]
}
// 整数
if (element.paramType === this.paramTypeColumn.integer) {
!this.rules[element.id] &&
this.$set(this.rules, element.id, [
{ validator: this.validateInteger }
])
this.rules[element.id] &&
this.rules[element.id].push({
validator: this.validateInteger
})
}
// 浮点数
if (element.paramType === this.paramTypeColumn.float) {
!this.rules[element.id] &&
this.$set(this.rules, element.id, [{ validator: this.validateFloat }])
this.rules[element.id] &&
this.rules[element.id].push({
validator: this.validateFloat
})
}
// if (this.checkContainer && element.paramType === this.paramTypeColumn.container) {
// this.rules[element.id] &&
// this.$set(this.rules, element.id, [])
// // this.rules[element.id] &&
// // this.rules[element.id].push([])
// this.checkContainer = false
// }
},
/**
* 获取自定义字段数据
*/
getCustomFieldsData(data) {
this.customFieldsData = data
},
/**
* 获取元件为库位设置的字段信息
*/
getStorageLocationFieldsData(data) {
this.storageFieldData = data
},
/**
* 保存库位元件
*/
async saveStockSchema(data) {
const res = await saveStockSchema(data)
if (res.code === '200') {
this.judgeCallback()
this.handleCancel()
}
},
/**
* 判断需要执行的回调
*/
judgeCallback() {
switch (this.source) {
case 'storageComponentLeft':
this.leftSuccess(this.stockFrameInfo)
break
case 'storageSchemaListRight':
this.schemaRightSuccess()
break
default:
break
}
},
/**
* 获取自定义字段和设置字段的数据
*/
getCustomFieldsDataAndSettingData() {
this.$refs.customFieldsRef.getData()
this.$refs.storageFieldsRef.getData()
},
/**
* 获取种类字段数据
*/
getFrameParams() {
let targetArr = []
const target = _.cloneDeep(this.form)
Object.keys(this.baseInfo).forEach(key => {
this.baseInfo[key] = target[key]
delete target[key]
})
Object.keys(target).forEach(key => {
targetArr.push({
id: key,
paramValues: target[key],
paramType: this.paramTypeObj[key]
})
})
// console.log(targetArr);
return targetArr
},
/**
* TODO
* 模态框确定
*/
handleOk() {
this.$refs.createBatchInfoRef.validate(valid => {
if (valid) {
this.getCustomFieldsDataAndSettingData()
const frameParams = this.getFrameParams()
this.saveStockSchema({
...this.baseInfo,
frameParams: frameParams,
customParams: {
params: this.customFieldsData
},
stockParams: {
params: this.storageFieldData
},
stockFrameId: this.stockFrameInfo.id
})
}
})
},
/**
* 模态框取消
*/
handleCancel() {
this.visible = false
this.$refs.createBatchInfoRef.resetFields()
this.isShowContainerType = false
this.form = {
frameName: '',
icon: '',
prefix: '',
name: '',
unitId: undefined,
capacity: undefined
}
this.stockFrameAttribute = []
},
/**
* 根据库位种类id获取库位种类属性信息
*/
async queryStockFrameFields(data) {
const res = await queryStockFrameFields(data)
if (res.code === '200') {
this.stockFrameAttribute = res.data
this.stockFrameAttribute.forEach(element => {
this.paramTypeObj[element.id] = element.paramType
this.$set(this.form, element.id, element.paramValues || [])
// 校验规则
this.dynamicValidate(element)
// console.log(this.form);
})
}
},
/**
* 打开模态框
*/
openCreateStockShemaModal(data, source) {
this.tempContainer = ''
this.source = source || ''
this.visible = true
this.stockFrameInfo = data
this.form.frameName = this.stockFrameInfo.name
this.queryStockFrameFields({ id: this.stockFrameInfo.id })
},
/**
* 改变预选容器
*/
handleChangeContainer(id, target) {
if (id) {
const findContainer = this.ContainerOptions.find(v => v.id === id)
const { id: containerId, name: containerName } = findContainer
target[0] = { containerId, containerName }
}
// else {
// target[0] = {containerId: null, containerName: ""}
// // target = []
// }
}
},
watch: {
form: {
handler() {
// Object.keys()
const targetId = this.stockFrameAttribute.find(item => item.paramName === '位置容器数')?.id
// console.log(targetId, this.form[targetId]?.length > 0 && this.form[targetId][0] !== '')
if (this.form[targetId]?.length > 0 && this.form[targetId][0] !== '') {
this.isShowContainerType = true
} else {
this.form[targetId]?.length > 0 && this.form[targetId][0] === '' && this.form[targetId].splice(0)
this.isShowContainerType = false
}
},
deep: true,
},
isShowContainerType: {
handler() {
if(!this.isShowContainerType) {
const containerId = this.stockFrameAttribute.find(item => item.paramName === '预设容器')?.id
this.form[containerId] = []
}
}
}
},
}
</script>
<style lang="scss" scoped></style>