美文网首页
离开页面给提示

离开页面给提示

作者: 糖醋里脊120625 | 来源:发表于2022-11-08 17:55 被阅读0次
    <template>
      <el-main>
        <el-form :model="form.model" :rules="form.rules" ref="form" style="margin-bottom: 56px" v-loading="form.loading"
                 label-width="120px">
          <span>基本信息</span>
          <el-divider></el-divider>
    
          <el-form-item label="采购类型" required>
            <el-radio-group v-model="form.model.purchaseType" @change="onPurchaseTypeChanged">
              <el-radio label="0">市场自采</el-radio>
              <el-radio label="1">供应商采购</el-radio>
            </el-radio-group>
          </el-form-item>
    
          <el-form-item v-show="isMarketPurchase" label="采购员" prop="purchaserName">
            <el-col :span="8">
              <el-input v-model="form.model.purchaserName"></el-input>
            </el-col>
          </el-form-item>
    
          <el-form-item v-show="isSupplierPurchase" label="供应商" prop="supplierName">
            <el-col :span="8">
              <SupplierSearcher @change="onSupplierChanged" style="width: 100%" ref="supplierSearcher"
              />
            </el-col>
          </el-form-item>
    
          <el-form-item label="交货日期" prop="planSupplyDate" required>
            <el-col :span="8">
              <el-date-picker
                style="width: 100%"
                v-model="form.model.planSupplyDate"
                type="date"
                value-format="yyyy-MM-dd"
                @change="onSupplyDateChanged">
              </el-date-picker>
            </el-col>
          </el-form-item>
    
          <el-form-item label="采购协议" v-if="purchaseAgreementSelect.options.length>0">
            <el-col :span="8">
              <el-select
                style="width: 100%"
                v-model="form.model.purchaseAgreementId" value-key="id"
                placeholder="请选择"
                @change="onPurchaseAgreementChanged"
                clearable>
                <el-option v-for="item in purchaseAgreementSelect.options" :key="item.id" :label="item.name"
                           :value="item.id"
                           style="height: 56px">
                  <span style="float: left;display: block;position: relative">{{ item.name }}</span>
                  <span
                    style="float:left;display: block;position: absolute;margin-top: 20px; color: #8492a6; font-size: 13px">
                    {{ item.beginDate | momentFormat('YYYY-MM-DD') }}至{{ item.endDate | momentFormat('YYYY-MM-DD') }}</span>
                </el-option>
              </el-select>
            </el-col>
          </el-form-item>
    
          <div class="block-margin"></div>
          <div>商品条目</div>
          <el-divider></el-divider>
          <el-form-item prop="itemList" label-width="0px">
            <el-card shadow="never">
              <div slot="header">
                <el-form :inline="true" :model="itemForm.model" ref="itemForm">
                  <el-form-item label="品种" prop="product">
                    <PurchaseAgreementProductSearcher v-if="isAgreement"
                                                      ref="productSearcher"
                                                      :onSelected="onProductSelected"
                                                      :agreementId="form.model.purchaseAgreementId"/>
                    <ProductSearcher v-else ref="productSearcher" :onSelected="onProductSelected"/>
                  </el-form-item>
    
                  <el-form-item label="数量" prop="num">
                    <el-input v-model="itemForm.model.num"
                              v-input-number.decimal="{decimal:2,min:0}"
                              ref="numInput"
                              @keyup.enter.native="onItemAddBtnClicked"/>
                  </el-form-item>
    
                  <el-form-item label="单价" prop="unitPrice">
                    <el-input v-model="itemForm.model.unitPrice"
                              v-input-number.decimal="{decimal:2,min:0}"
                              ref="unitPriceInput"
                              :disabled="isAgreement"
                              @keyup.enter.native="onItemAddBtnClicked"/>
                  </el-form-item>
    
                  <el-form-item>
                    <el-button type="primary" @click="onItemAddBtnClicked">添加
                    </el-button>
                  </el-form-item>
                </el-form>
              </div>
              <el-table :data="form.model.itemList"
                        show-summary :summary-method="getSummaries">
                <el-table-column type="index" width="50"></el-table-column>
    
                <el-table-column label="品种">
                  <template slot-scope="scope">
                    <GoodsItem :imageSrc="scope.row.product.piImageUrl"
                               :name="scope.row.product.piProductName"
                               :spec="scope.row.product.piSpec"
                               :netContent="scope.row.product.piNetContent"
                               :netContentUnit="scope.row.product.piNetContentUnit"
                               :level="scope.row.product.piLevel"/>
                  </template>
                </el-table-column>
    
                <el-table-column label="数量">
                  <template slot-scope="scope">
                    <el-input @mousewheel.native.prevent v-model="scope.row.num" size="small"
                              v-input-number.decimal="{decimal:2,min:0}"
                              @change="onItemNumPriceChanged(scope.row,'num')"/>
                  </template>
                </el-table-column>
    
                <el-table-column label="单价">
                  <template slot-scope="scope">
                    <el-input @mousewheel.native.prevent v-model="scope.row.unitPrice" size="small"
                              v-input-number.decimal="{decimal:2,min:0}"
                              :disabled="isAgreement"
                              @change="onItemNumPriceChanged(scope.row,'unitPrice')"/>
                  </template>
                </el-table-column>
    
                <el-table-column label="小计" prop="amount" align="right">
                  <!--              <template slot-scope="scope">-->
                  <!--                <el-input @mousewheel.native.prevent v-model="scope.row.amount" size="small"-->
                  <!--                          v-input-number.decimal="{decimal:2,min:0}"-->
                  <!--                          @change="onItemNumPriceChanged(scope.row,'amount')"/>-->
                  <!--              </template>-->
                </el-table-column>
    
                <el-table-column label="备注">
                  <template slot-scope="scope">
                    <el-input v-model="scope.row.remark" size="small"/>
                  </template>
                </el-table-column>
    
                <el-table-column label="操作" width="100" align="center">
                  <template slot-scope="scope">
                    <el-button size="small" type="danger" @click="onItemDeleteClicked(scope.$index)">删除</el-button>
                  </template>
                </el-table-column>
              </el-table>
            </el-card>
          </el-form-item>
    
          <el-form-item label-width="0px">
            <el-input type="textarea" v-model="form.model.remark" placeholder="备注"/>
          </el-form-item>
    
        </el-form>
        <div class="el-main_foot_fixed">
          <el-button @click="back">取消</el-button>
          <el-button type="primary" v-loading="submitLoading" @click="onSubmitBtnClicked">提交</el-button>
          <el-button type="primary" plain @click="onStagingBtnClicked" v-if="!isUpdateStatus">暂存</el-button>
        </div>
      </el-main>
    </template>
    
    <script>
    import ProductSearcher from "../../components/business/ProductSearcher";
    import PurchaseAgreementProductSearcher from "../../components/business/PurchaseAgreementProductSearcher";
    import GoodsItem from "../../components/common/GoodsItem";
    import SupplierSearcher from "../../components/business/SupplierSearcher";
    
    import purchaseAgreementApi from "../../service/api/purchase-agreement-api";
    import selfPurchaseOrderApi from "../../service/api/self-purchase-order-api";
    
    import {centToYuan, yuanToCent} from "../../utils/priceUtil";
    import {Decimal} from "decimal.js";
    
    const MODEL_CACHE_KEY = "self-purchase-order/form/model";
    
    export default {
      components: {
        SupplierSearcher,
        PurchaseAgreementProductSearcher,
        ProductSearcher, GoodsItem
      },
    
      data() {
        return {
          form: {
            model: {
              id: '',
              purchaserName: '',
              purchaseType: '0',
              supplierName: '',
              supplierId: '',
              purchaseAgreementId: '',
              planSupplyDate: '',
              itemList: [],
              remark: '',
            },
            modelBackup: '',
            rules: {
              purchaseType: [
                {required: true, message: "请选择采购类型", trigger: "change"}
              ],
              planSupplyDate: [
                {required: true, message: "请选择交货日期", trigger: "change"}
              ],
              itemList: [
                {required: true, message: "商品条目不可为空"}
              ],
            },
            modelInitialValue: '',
            loading: false
          },
          itemForm: {
            model: {
              product: '',
              unitPrice: '',
              num: '',
            }
          },
          purchaseAgreementSelect: {
            options: []
          },
          submitLoading: false,
          isUpdateStatus: false,
        }
      },
    
      computed: {
        isAgreement: function () {
          return this.form.model.purchaseAgreementId !== '';
        },
    
        isMarketPurchase: function () {
          return this.form.model.purchaseType === '0';
        },
    
        isSupplierPurchase: function () {
          return this.form.model.purchaseType === '1';
        },
    
        pageHasBeenEdited: function () {
          return this.form.modelInitialValue !== JSON.stringify(this.form.model);
        }
      },
    
      watch: {
        'form.model.purchaseType'(newValue, oldValue) {
          this.backupFormData('purchaseType', oldValue);
        },
    
        'form.model.planSupplyDate'(newValue, oldValue) {
          this.backupFormData('planSupplyDate', oldValue);
        },
    
        'form.model.purchaseAgreementId'(newValue, oldValue) {
          this.backupFormData('purchaseAgreementId', oldValue);
        },
      },
    
      created() {
        this.id = this.$route.query.id;
      },
    
      mounted() {
        let id = this.$route.query.id;
        if (id) {
          this.isUpdateStatus = true;
          this.loadDetail(id);
        } else {
          this.restoreTemporaryData();
        }
      },
    
      methods: {
        loadDetail(id) {
          this.form.loading = true;
          selfPurchaseOrderApi.get(id)
            .then(value => {
              this.setValueToView(value)
            }).finally(() => {
            this.form.loading = false;
          });
        },
    
        loadPurchaseAgreements(supplierName, supplyDate) {
          // 获取且协议,并判断是否协议的数据源改变了
          purchaseAgreementApi.search({keyword: supplierName, queryDate: supplyDate, pageIndex: 1, pageSize: 20})
            .then(value => {
    
              // 数据源不包含当前选择的协议的情况弹出确认窗口
              let noCurrentAgreement = this.purchaseAgreementSelect.options.length > 0
                && !value.list.some(item => item.id === this.form.model.purchaseAgreementId);
    
              if (noCurrentAgreement && this.form.model.itemList.length > 0) {
                this.alertClearConfirm(() => {
                  this.purchaseAgreementSelect.options = value.list;
                  this.form.model.purchaseAgreementId = '';
                })
              } else {
                this.purchaseAgreementSelect.options = value.list;
              }
            })
        },
    
        alertClearConfirm(confirm) {
          this.$confirm('协议发生改变,当前商品条目将被清空', '是否继续', {
            confirmButtonText: '确定',
            cancelButtonText: '取消',
            type: 'warning'
          }).then(() => {
            // 清空商品条目
            this.form.model.itemList = [];
            confirm();
          }).catch(() => {
            this.restoreBackupFormData();
          })
        },
    
        setValueToView(value) {
          this.form.model = this.$clone(value);
          this.form.model.purchaseType = this.form.model.purchaseType + "";
          this.form.model.itemList = value.itemList.map(el => {
            return {
              product: el.productInfo,
              unitPrice: centToYuan(el.unitPrice),
              num: el.actualPurchaseNum,
              amount: centToYuan(el.amount),
              remark: el.remark,
            };
          });
    
          if (this.isSupplierPurchase) {
            this.$refs['supplierSearcher'].setValue({
              id: this.form.model.supplierId,
              name: this.form.model.supplierName,
            });
    
            this.loadPurchaseAgreements(this.form.model.supplierName, this.form.model.planSupplyDate);
          }
    
          this.initModelInitialValue();
        },
    
        onSupplierChanged(value) {
          this.backupFormData();
          this.form.model.supplierName = value.name;
          this.form.model.supplierId = value.id;
          this.loadPurchaseAgreements(this.form.model.supplierName, this.form.model.planSupplyDate)
        },
    
        onPurchaseTypeChanged(val) {
          if (this.isMarketPurchase) {// 切换到市场采购
            let change = () => {
              this.purchaseAgreementSelect.options = [];
              this.form.model.purchaseAgreementId = '';
              this.form.model.supplierId = '';
              this.form.model.supplierName = '';
              this.$refs['supplierSearcher'].setValue({});
            }
            if (JSON.stringify(this.purchaseAgreementSelect.options) !== JSON.stringify([])
              && this.form.model.itemList.length > 0) {
              this.alertClearConfirm(change);
            } else {
              change();
            }
          } else {// 供应商采购
            this.form.model.purchaserName = '';
          }
        },
    
        onSupplyDateChanged(val) {
          if (this.isSupplierPurchase) {
            this.loadPurchaseAgreements(this.form.model.supplierName, this.form.model.planSupplyDate);
          }
        },
    
        onProductSelected(item) {
          this.itemForm.model.product = item.obj;
    
          if (this.isAgreement) {
            this.itemForm.model.unitPrice = item.obj.unitPrice;
          }
    
          this.$nextTick(() => {
            this.$refs['numInput'].focus();
          })
        },
    
        onPurchaseAgreementChanged(value) {
          if (this.form.model.itemList.length > 0) {
            this.alertClearConfirm(() => {
              // nothing to do
            });
          }
        },
    
        onItemAddBtnClicked() {
          let item = this.$clone(this.itemForm.model);
          if (!item.product) {
            this.$message.error("请选择品种");
            return;
          }
    
          if (!item.num || item.num < 0) {
            this.$message.error("请输入正确数量");
            return;
          }
    
          if (!item.unitPrice || item.unitPrice < 0) {
            this.$message.error("请输入正确价格");
            return;
          }
    
          if (this.checkItemExist(item)) {
            this.$message.error("已存在相同品种");
            return;
          }
    
          item.amount = Decimal.mul(item.num, item.unitPrice).toFixed(2, Decimal.ROUND_DOWN);
    
          this.form.model.itemList.push(item);
          this.$refs['itemForm'].resetFields();
          this.$refs['unitPriceInput'].blur();
          this.$refs['numInput'].blur();
          this.$refs.productSearcher.clearSelected();
        },
    
        onItemDeleteClicked(index) {
          this.form.model.itemList.splice(index, 1);
        },
    
        onItemNumPriceChanged(row, type) {
          switch (type) {
            case 'amount':
              row.unitPrice = Decimal.div(row.amount, row.num).toFixed(2, Decimal.ROUND_DOWN);
              break
            default:
              row.amount = Decimal.mul(row.num, row.unitPrice).toFixed(2, Decimal.ROUND_DOWN);
              break
          }
        },
    
        checkItemExist(item) {
          if (this.form.model.itemList <= 0) {
            return false;
          }
    
          return this.form.model.itemList.some(el => {
            return el.product.piId === item.product.piId
          })
        },
    
        getSummaries(param) {
          const {columns, data} = param;
          const sums = [];
          columns.forEach((column, index) => {
            if (index === 0) {
              sums[index] = "合计";
              return
            }
    
            if (index === 4) {
              const values = data.map(item => Number(item[column.property]));
              sums[index] = values.reduce((prev, curr) => {
                const value = Number(curr);
                if (!isNaN(value)) {
                  return prev + curr;
                } else {
                  return prev;
                }
              }, 0);
    
              sums[index] = sums[index].toFixed(2);
            }
          });
          return sums;
        },
    
        onStagingBtnClicked() {
          sessionStorage.setItem(MODEL_CACHE_KEY, JSON.stringify(this.form.model));
          this.initModelInitialValue();
          this.$message.success("暂存成功");
        },
    
        restoreTemporaryData() {
          let value = sessionStorage.getItem(MODEL_CACHE_KEY);
          if (value) {
            this.form.model = JSON.parse(value);
    
            if (this.isSupplierPurchase) {
              this.$refs['supplierSearcher'].setValue({
                id: this.form.model.supplierId,
                name: this.form.model.supplierName,
              });
    
              this.loadPurchaseAgreements(this.form.model.supplierName, this.form.model.planSupplyDate);
            }
          }
    
          this.initModelInitialValue()
        },
    
        clearTemporaryData() {
          sessionStorage.removeItem(MODEL_CACHE_KEY);
        },
    
        initModelInitialValue() {
          this.form.modelInitialValue = JSON.stringify(this.form.model);
        },
    
        back() {
          this.$router.back();
        },
    
        onSubmitBtnClicked() {
          this.$refs.form.validate((valid) => {
            if (!valid) {
              return false;
            }
    
            // 转换视图的明细为参数需要的明细
            let items = this.form.model.itemList.map(value => {
              return {
                productId: value.product.piId,
                unitPrice: yuanToCent(value.unitPrice),
                num: value.num,
                remark: value.remark,
              }
            })
    
            let model = this.$clone(this.form.model);
            model.itemList = items;
    
            this.submitLoading = true;
            let promise = model.id ? selfPurchaseOrderApi.update(model) : selfPurchaseOrderApi.add(model);
            promise.then(value => {
              this.$message.success("提交成功");
              // 为了跳过离开页面时的验证
              this.initModelInitialValue();
    
              // 新增成功的情况下清除缓存
              if (model.id === '') {
                this.clearTemporaryData();
              }
    
              this.back();
            }).finally(() => {
              this.submitLoading = false;
            })
          })
        },
    
        backupFormData(property, oldValue) {
          let modelClone = this.$clone(this.form.model);
          if (property) {
            modelClone[property] = oldValue;
          }
    
          this.form.modelBackup = JSON.stringify(modelClone);
        },
    
        restoreBackupFormData() {
          this.form.model = JSON.parse(this.form.modelBackup);
    
          let supplierSearcherValue = {
            id: this.form.model.supplierId,
            name: this.form.model.supplierName,
          }
    
          this.$refs['supplierSearcher'].setValue(supplierSearcherValue);
        },
    
        alertDataChangeConfirm(confirm, cancel) {
          if (this.pageHasBeenEdited) {
            this.$confirm('数据发生改变,是否离开?', {
              confirmButtonText: '考虑一下',
              cancelButtonText: '直接离开',
              type: 'warning'
            }).then(confirm).catch(cancel);
          } else {
            cancel();
          }
        }
      },
    
      beforeRouteLeave(to, from, next) {
        next(false);
        setTimeout(() => {
          this.alertDataChangeConfirm(() => {
          }, () => {
            next()
          });
        }, 200);
      }
    }
    </script>
    
    <style lang="less" scoped>
    .el-card {
      .el-form-item {
        margin-bottom: 0;
      }
    
      .el-card__header {
        background: #F5F7FA;
      }
    }
    
    .el-divider--horizontal {
      margin: 10px 0 20px;
    }
    
    .block-margin {
      height: 22px;
    }
    
    </style>
    
    

    相关文章

      网友评论

          本文标题:离开页面给提示

          本文链接:https://www.haomeiwen.com/subject/crawtdtx.html