

子组件:
<template><div class="product-base-info-form"><a-form-modelref="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-itemprop="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-itemclass="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-itemclass="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-selectv-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-itemprop="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-itemclass="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-itemclass="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-itemv-for="item in productValues" // 动态字段:label="item.paramName":prop="item.id":key="item.id":label-col="labelColItem":wrapper-col="wrapperColItem"><divv-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-inputv-if="item.isMultipleValue === 2"v-model="form[item.id][0]"></a-input><a-selectv-elsev-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-inputv-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-pickerv-elsev-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"><liclass="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"><liclass="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"><spanv-if="item.paramValues[0].value && item.paramValues[0].cycleType">{{`${item.paramValues[0].value} ${CycleTypeInfo[item.paramValues[0].cycleType]}`}}</span></div><!-- 周期 --><CycleTypeComv-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-modalref="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,// 后端需要的paramTypeparamTypeObj: {},STOCK_FRAME_TYPE: Object.freeze(STOCK_FRAME_TYPE),unitOptions: [],ContainerOptions: [],// tmpContainerId: '',spinning: true,checkContainer: false}},methods: {moment,// 下拉菜单触发的回调dropdownVisibleChange(open) {// this.spinning = trueopen && _.isEmpty(this.unitOptions) && this.getFullUnitInfo()},/*** 获取数据库预选单位*/async getFullUnitInfo() {this.spinning = trueconst 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 = falsethis.$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} = targetObject.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.paramTypethis.$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.namethis.form.prefix = newProductSelfInfo.prefixthis.form.icon = newProductSelfInfo.iconthis.form.unitId = newProductSelfInfo.unitIdthis.form.capacity = newProductSelfInfo.capacitythis.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-buttonv-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-formref="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-buttontype="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-buttonv-if="operatorName[2] === 'edit'"@click="(e) => changeCradStatus(2, e)"size="small"icon="edit"/></div></div><a-descriptionsv-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-fieldsref="productCustomFieldsRef"@getData="getSchemaFieldsData":customFields="customFields"></product-custom-fields><div class="product-info-content-card-footer"><a-space><a-buttonsize="small"@click="(e) => backCradEditStatus(2, e)">取消</a-button><a-buttontype="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-locationref="storageLocationRef"@getData="getStorageLocationFieldsData":customFields="storageFields":showMode="showMode.productKey"></storage-location><div class="product-info-content-card-footer"><a-space><a-buttontype="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-buttonv-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-formref="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-buttontype="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-buttonv-if="operatorName[2] === 'edit'"@click="(e) => changeCradStatus(2, e)"size="small"icon="edit"/></div></div><a-descriptionsv-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-fieldsref="productCustomFieldsRef"@getData="getSchemaFieldsData":customFields="customFields"></product-custom-fields><div class="product-info-content-card-footer"><a-space><a-buttonsize="small"@click="(e) => backCradEditStatus(2, e)">取消</a-button><a-buttontype="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-locationref="storageLocationRef"@getData="getStorageLocationFieldsData":customFields="storageFields":showMode="showMode.productKey"></storage-location><div class="product-info-content-card-footer"><a-space><a-buttontype="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-cardclass="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-formref="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-cardclass="card product-fields":class="{ 'product-forbidden': operatorName[2] === 'edit' }":tab-list="tabListTitle":active-tab-key="titleKey"@tabChange="(key) => onTabChange(key, 'titleKey')"><aclass="link-button"slot="tabBarExtraContent"@click="(e) => changeCradStatus(2, e)">{{ operatorName[2] === "edit" ? "编辑" : "确认" }}</a><a-alertv-if="operatorName[2] === 'ok'"message="进入编辑状态,暂未保存更新"banner/><product-custom-fieldsv-show="titleKey === '1'"ref="productCustomFieldsRef"@getData="getSchemaFieldsData":customFields="customFields":class="{ forbidden: operatorName[2] === 'edit' }"></product-custom-fields><storage-locationv-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-modalv-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-modelref="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"><templatev-if="paramTypeColumn.text === item.paramType ||paramTypeColumn.integer === item.paramType ||paramTypeColumn.float === item.paramType"><a-inputv-if="item.isMultipleValue === 2"v-model="form[item.id][0]"></a-input><a-selectv-elsev-model="form[item.id]":dropdownStyle="{ display: 'none' }":dropdownMenuStyle="{ display: 'none' }"mode="tags"></a-select></template><templatev-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><templatev-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><templatev-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-pickerv-model="item.paramValues[0]":showTime="true"></a-date-picker></template><template v-else-if="paramTypeColumn.link === item.paramType"><spanclass="link-type":key="ele.referenceId"v-for="ele in item.paramValues"@click="showProductLinkDetail(ele)"><a-icon type="link" /> {{ ele.referenceName }}</span></template><!-- <templatev-else-if="paramTypeColumn.container === item.paramType && isShowContainerType"><a-selectallowClear@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-selectallowClear@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-fieldsref="storageFieldsRef"@getData="getStorageLocationFieldsData":showMode="showMode.productKey"></storage-fields></a-tab-pane><a-tab-panekey="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: [],// 后端需要的paramTypeparamTypeObj: {},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 = trueopen && _.isEmpty(this.unitOptions) && this.getFullUnitInfo()},/*** 获取数据库预选单位*/async getFullUnitInfo() {this.spinning = trueconst 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 = trueconst 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)breakcase 'storageSchemaListRight':this.schemaRightSuccess()breakdefault: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 = falsethis.$refs.createBatchInfoRef.resetFields()this.isShowContainerType = falsethis.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.datathis.stockFrameAttribute.forEach(element => {this.paramTypeObj[element.id] = element.paramTypethis.$set(this.form, element.id, element.paramValues || [])// 校验规则this.dynamicValidate(element)// console.log(this.form);})}},/*** 打开模态框*/openCreateStockShemaModal(data, source) {this.tempContainer = ''this.source = source || ''this.visible = truethis.stockFrameInfo = datathis.form.frameName = this.stockFrameInfo.namethis.queryStockFrameFields({ id: this.stockFrameInfo.id })},/*** 改变预选容器*/handleChangeContainer(id, target) { // 这里改回去if (id) {const findContainer = this.ContainerOptions.find(v => v.id === id)this.tempContainer = idconst { id: containerId, name: containerName } = findContainertarget[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>
