【问题标题】:How can I get ID after creating mysql row in Vue - Express在 Vue 中创建 mysql 行后如何获取 ID - Express
【发布时间】:2026-01-01 22:40:01
【问题描述】:

我对从 Sequelize.create 获取 ID 有疑问。我有一个名为 Cases 的数据库,在那里我存储了用户创建的整个案例。然后,我有数据库 CasesImages,我在其中存储属于案例的图像。

案例模型:

module.exports = (sequelize, DataTypes) => {
const Case = sequelize.define('Case', {
    id: {
        type: DataTypes.INTEGER,
        primaryKey: true,
        autoIncrement: true
    },
    caseName: DataTypes.STRING,
    constructionSite: DataTypes.STRING,
    createdBy: DataTypes.STRING,
    dateOfDiscovery: { 
        type: DataTypes.DATEONLY,
        get: function() {
            return moment(this.getDataValue('dateOfDiscovery')).format('DD.MM.YYYY')
        }},
    dateOfRemoval: DataTypes.DATEONLY,
    responsible: DataTypes.STRING,
    howManyDiscoveries: DataTypes.INTEGER,
    placeOfDiscovery: DataTypes.STRING,
    text: DataTypes.TEXT,
    sanction: DataTypes.STRING,
    forCompany: DataTypes.STRING,
    priority: DataTypes.STRING,
})

Case.associate = (models) => {
    Case.hasMany(models.caseimages, {foreignKey: 'id', as: 'images'});
};

return Case }

案例图像模型:

module.exports = (sequelize, DataTypes) => {
const CaseImage = sequelize.define('CaseImage', {
    fileName: DataTypes.STRING,
    mimeType: DataTypes.STRING,
    caseId: {
        type: DataTypes.INTEGER,
        references: {
            model: 'Cases',
            key: 'id',
        }
    },
    path: DataTypes.STRING
})

CaseImage.associate = (models) => {
    CaseImage.belongsTo(models.cases, {foreignKey: 'id', as: 'case'});
  };

return CaseImage;}

我可以创建新案例,然后使用该 ID 添加图片。此外,在我的快速应用程序中,我有一个工作方法,首先创建案例,保存它,返回该案例的 id,然后将图像发送到第二个数据库。我使用邮递员对此进行了测试,并且可以正常工作。 您可以在此处查看该方法:

async postImageWithCase (req, res) {
    try {
        Case.create({
            caseName: req.body.caseName,
            constructionSite: req.body.constructionSite,
            createdBy: req.body.createdBy,
            dateOfDiscovery: req.body.dateOfDiscovery,
            dateOfRemoval: req.body.dateOfRemoval,
            responsible: req.body.responsible,
            howManyDiscoveries: req.body.howManyDiscoveries,
            placeOfDiscovery: req.body.placeOfDiscovery,
            text: req.body.text,
            sanction: req.body.sanction,
            forCompany: req.body.forCompany,
            priority: req.body.priority
        })
        .then((result) => {
            const newId = result.id;
            return newId;
        })
        .then((newId) => {
            const checkId = Case.findOne({ where: {id: newId }});

            if (checkId == null) {
                res.status(400).send({ message: 'Prípad so zadaným ID sa nenašiel.'});
                return;
            }

            CaseImage.create({
                fileName: req.file.originalname,
                mimeType: req.file.mimetype,
                caseId: newId,
                path: req.file.path,
            })
            
            res.status(201).send({ message: 'Zistenie bolo úspešne vytvorené aj s fotografiou.'});
        })
        .catch((error) => {
            console.log(error);
            res.status(400).send({ message: 'Nepodarilo sa pridať zistenie s fotografiou.'});
        })
     } 
    catch (err) {
        console.log(err)
        res.status(400).send({ message: 'Nepodarilo sa pridať fotografiu, skúste to neskôr.'})

    }
},

在这里你还可以看到我的 Express 路由设置:

app.post('/api/v1/cases/:id/images',
  upload.single('file'),
  CaseImagesController.postImageWithCase)

问题是,我不知道如何在我的 Vue 应用程序中获取该 ID。我有创建新案例的方法,然后它也尝试通过该新案例 ID 发送图像,但它对我不起作用。 Error that I'm getting

另外,在这里你可以看到我的 Vue.js 方法。

async submitCaseWithPhotos() {
  const bozpCase = new FormData();
    bozpCase.append('file', this.file);
    bozpCase.append('caseName', this.caseName);
    bozpCase.append('constructionSite', this.constructionSite);
    bozpCase.append('createdBy', this.logedUser);
    bozpCase.append('dateOfDiscovery', this.date);
    bozpCase.append('responsible', this.responsible);
    bozpCase.append('howManyDiscoveries', this.howManyDiscoveries);
    bozpCase.append('placeOfDiscovery', this.placeOfDiscovery);
    bozpCase.append('text', this.text);
    bozpCase.append('sanction', this.sanction);
    bozpCase.append('forCompany', this.forCompany);
    bozpCase.append('priority', this.priority);
    CaseImagesService.postImageWithCase(bozpCase)
    .then((response) => {
      this.$emit("close-card");
    })
  .catch((error) => {
    console.log(error)
    this.error = "Failed to submit data - please try again later.";
    });
},
  formatDate (date) {
      if (!date) return null

      const [year, month, day] = date.split('-')
      return `${day}/${month}/${year}`
    },
  async loadConstructions() {
  ConstructionsService.index()
  .then((response) => {
      if(!response.data){
        throw "Error";
      }
      const data = response.data;
      const constructionSites = [];
      for (const id in data) {
        if(data[id].isActive){
          constructionSites.push({
            id: data[id].id,
            constructionSite: data[id].constructionSite,
            isActive: data[id].isActive
          })};
      }
      this.constructionSites = constructionSites;
    })
    .catch((error) => {
      this.isLoading = false;
      this.error = "Failed to fetch data - please try again later.";
    });
},

},

这也是我的 Vue.js API 调用。

postImageWithCase(id, bozpCase) {
    return Api().post('cases/' + id + '/images', bozpCase);
},

也许我只是遗漏了一些小细节,或者整个功能有问题,但我已尽力而为,我无法移动。

【问题讨论】:

  • #1 我可以看到 3 个不同的工件:cases-api (express)、cases-image-api (express) 和 web (vue)。我对么? #2 是否需要caseId(创建case时获得)用于case-image创建(cases-image-api)?
  • 是的,你是绝对正确的。是的,因为当我创建新案例时,Sequelize 会为其创建 ID。我需要这个 ID 来为其分配图像。
  • 你的问题解决了吗?
  • 还没有,我仍然无法在 Vue 中接收 ID。

标签: node.js vue.js express sequelize.js


【解决方案1】:

sequelize api 中访问数据库的方法都是异步的,因此您需要对它们使用 Promise。换句话说,像

这样的行
const checkId = Case.findOne({ where: {id: newId }});

CaseImage.create({
          fileName: req.file.originalname,
          mimeType: req.file.mimetype,
          caseId: newId,
          path: req.file.path,
      })

return promises,所以你必须使用 .then 语法或 async/await 关键字。

另外,req.file 在您的控制器中为 null 或未定义。您可能打算输入req.body.file.originalname,而不是req.file.originalname

否则,您也可以尝试添加一行

console.log(JSON.stringify(req, null, 2));

尝试注销req 对象。如果您使用的是 express,您可能会在 req.body 下找到您要查找的内容。

您可以将postImageWithCase 中的代码更改为类似

async postImageWithCase (req, res) {
    try {
        Case.create({
            caseName: req.body.caseName,
            constructionSite: req.body.constructionSite,
            createdBy: req.body.createdBy,
            dateOfDiscovery: req.body.dateOfDiscovery,
            dateOfRemoval: req.body.dateOfRemoval,
            responsible: req.body.responsible,
            howManyDiscoveries: req.body.howManyDiscoveries,
            placeOfDiscovery: req.body.placeOfDiscovery,
            text: req.body.text,
            sanction: req.body.sanction,
            forCompany: req.body.forCompany,
            priority: req.body.priority
        })
        .then((case) => {
            return CaseImage.create({
                fileName: req.body.file.originalname,
                mimeType: req.body.file.mimetype,
                caseId: case.id,
                path: req.body.file.path,
            })
        .then(caseImage => {
            res.status(201).send({ message: 'Zistenie bolo úspešne vytvorené aj s fotografiou.',
                caseId: caseImage.caseId,
                caseImageId: caseImage.id
            });
        })
        .catch((error) => {
            console.log(error);
            res.status(400).send({ message: 'Nepodarilo sa pridať zistenie s fotografiou.'});
        })
     } 
    catch (err) {
        console.log(err)
        res.status(400).send({ message: 'Nepodarilo sa pridať fotografiu, skúste to neskôr.'})

    }
},

【讨论】:

  • 您好,感谢您的回复。我试过你的建议..第一个问题是案例。我不得不使用大写的情况,因为小写我有错误:SyntaxError: Unexpected token 'case'... 然后我尝试使用你编辑的方法,我得到同样的错误 req.body.file.originalname - 仍然 TypeError: 不能读取未定义的属性“原始名称”
  • 但是当我使用 postman 和我的原始方法时 - req.file.originalname.. 我得到状态 201 并且它有效.. 唯一的问题是我不知道如何在 Vue 中使用它。