Преглед на файлове

完成菜谱添加步骤相关功能

wangyang преди 5 години
родител
ревизия
e3320c9bbf
променени са 5 файла, в които са добавени 449 реда и са изтрити 2 реда
  1. 78 0
      src/api/recipe.js
  2. 26 0
      src/router/config.js
  3. 13 0
      src/views/recipe/food.vue
  4. 190 2
      src/views/recipe/index.vue
  5. 142 0
      src/views/recipe/step.vue

+ 78 - 0
src/api/recipe.js

@@ -0,0 +1,78 @@
+import request from '@/utils/request'
+
+// 获取食谱列表
+export function getRecipes(params) {
+  return request({
+    url: '/api/recipes',
+    method: 'get',
+    params
+  })
+}
+
+// 获取食谱列表
+export function getRecipe(id) {
+  return request({
+    url: `/api/recipes/${id}`,
+    method: 'get'
+  })
+}
+
+// 创建食谱
+export function createRecipe(data) {
+  return request({
+    url: '/api/recipes',
+    method: 'post',
+    data
+  })
+}
+
+// 更新食谱
+export function updateRecipe(id, data) {
+  return request({
+    url: `/api/recipes/${id}`,
+    method: 'post',
+    data
+  })
+}
+
+// 删除食谱
+export function removeRecipe(id) {
+  return request({
+    url: `/api/recipes/${id}`,
+    method: 'delete'
+  })
+}
+
+// 添加步骤
+export function addRecipeStep(recipeId, data) {
+  return request({
+    url: `/api/recipes/${recipeId}/steps`,
+    method: 'post',
+    data
+  })
+}
+
+// 更新步骤
+export function updateRecipeStep(recipeId, recipeStepId, data) {
+  return request({
+    url: `/api/recipes/${recipeId}/steps/${recipeStepId}`,
+    method: 'post',
+    data
+  })
+}
+
+// 删除步骤
+export function removeRecipeStep(recipeId, recipeStepId) {
+  return request({
+    url: `/api/recipes/${recipeId}/steps/${recipeStepId}`,
+    method: 'delete'
+  })
+}
+
+// 获取食谱步骤列表
+export function getRecipeSteps(id) {
+  return request({
+    url: `/api/recipes/${id}/steps`,
+    method: 'get'
+  })
+}

+ 26 - 0
src/router/config.js

@@ -15,6 +15,32 @@ export const asyncRouterMap = [
       }
     ]
   },
+  {
+    path: '/recipe',
+    component: Layout,
+    children: [
+      {
+        path: '',
+        name: '菜谱列表',
+        component: () => import('@/views/recipe/index'),
+        meta: { title: '菜谱列表', icon: 'dashboard' }
+      },
+      {
+        path: ':id/food',
+        name: '食物管理',
+        component: () => import('@/views/recipe/food'),
+        meta: { title: '食物管理' },
+        hidden: true
+      },
+      {
+        path: ':id/step',
+        name: '步骤管理',
+        component: () => import('@/views/recipe/step'),
+        meta: { title: '步骤管理' },
+        hidden: true
+      }
+    ]
+  },
   {
     path: '/food',
     component: Layout,

+ 13 - 0
src/views/recipe/food.vue

@@ -0,0 +1,13 @@
+<template>
+
+</template>
+
+<script>
+export default {
+  name: 'RecipeFood'
+}
+</script>
+
+<style scoped>
+
+</style>

+ 190 - 2
src/views/recipe/index.vue

@@ -1,11 +1,199 @@
 <template>
+  <div class="app-container">
+    <div class="filter-container">
+      <el-input
+        v-model="listQuery.query"
+        placeholder="请输入检索词"
+        style="width: 60%;"
+        class="filter-item"
+        @keyup.enter.native="fetchData()"
+      />
+      <el-button class="filter-item" style="margin-left: 10px;" type="primary" icon="el-icon-search" @click="fetchData">
+        检索
+      </el-button>
+      <el-button
+        class="filter-item"
+        style="margin: 0 10px 20px 0; float: right;"
+        type="success"
+        icon="el-icon-circle-plus-outline"
+        @click="handleCreateOrUpdate('create')"
+      >
+        新建
+      </el-button>
+    </div>
 
+    <el-table
+      key="0"
+      v-loading="listLoading"
+      :data="list"
+      border
+      fit
+      highlight-current-row
+      style="width: 100%;"
+    >
+      <el-table-column type="index" label="序号" align="center" width="60px" />
+      <el-table-column label="自定义ID" align="center" width="80px">
+        <template slot-scope="{row}">
+          <span>{{ row.id2 }}</span>
+        </template>
+      </el-table-column>
+      <el-table-column label="食谱封面图" align="center" width="200px">
+        <template slot-scope="{row}">
+          <el-image style="width: 180px; height: 100px" :src="row.coverPic" fit="contain" />
+        </template>
+      </el-table-column>
+      <el-table-column label="名称" align="center">
+        <template slot-scope="{row}">
+          <span>{{ row.name }}</span>
+        </template>
+      </el-table-column>
+      <el-table-column label="描述" align="center">
+        <template slot-scope="{row}">
+          <span>{{ row.description }}</span>
+        </template>
+      </el-table-column>
+      <el-table-column label="创建时间" width="180px" align="center">
+        <template slot-scope="{row}">
+          <span>{{ row.createTime }}</span>
+        </template>
+      </el-table-column>
+      <el-table-column label="更新时间" width="180px" align="center">
+        <template slot-scope="{row}">
+          <span>{{ row.updateTime }}</span>
+        </template>
+      </el-table-column>
+      <el-table-column label="操作" align="center" class-name="small-padding">
+        <template slot-scope="{row,$index}">
+          <el-button type="primary" size="mini" @click="handleCreateOrUpdate('edit', row)">
+            更新
+          </el-button>
+          <el-button type="primary" size="mini" @click="manageSteps(row)">
+            管理步骤
+          </el-button>
+          <el-button type="primary" size="mini" @click="manageFoods(row)">
+            管理食物
+          </el-button>
+          <el-button size="mini" type="danger" @click="handleDelete(row, $index)">
+            删除
+          </el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+
+    <pagination v-show="total>0" :total="total" :page.sync="listQuery.pageNum" :limit.sync="listQuery.pageSize" @pagination="fetchData" />
+
+    <el-dialog :title="textMap[dialogStatus]" :visible.sync="dialogFormVisible">
+      <el-form ref="dataForm" :rules="rules" :model="params" label-position="left" label-width="100px" style="width: 400px; margin-left:50px;">
+        <el-form-item label="ID" prop="id">
+          <el-input v-model="params.id2" placeholder="请输入自定义ID" />
+        </el-form-item>
+        <el-form-item label="名称" prop="name">
+          <el-input v-model="params.name" placeholder="请输入名称" />
+        </el-form-item>
+        <el-form-item label="描述" prop="description">
+          <el-input v-model="params.description" placeholder="请输入描述" type="textarea" :row="2" />
+        </el-form-item>
+        <el-form-item label="营养素图片" prop="coverPic">
+          <single-image :value="params.coverPic" :show-preview="true" @success="updateFile" style="width: 100%" />
+        </el-form-item>
+      </el-form>
+      <div slot="footer" class="dialog-footer">
+        <el-button @click="dialogFormVisible = false">
+          取消
+        </el-button>
+        <el-button type="primary" @click="dialogStatus==='create'?createData():updateData()">
+          提交
+        </el-button>
+      </div>
+    </el-dialog>
+  </div>
 </template>
 
 <script>
-  export default {
-    name: 'index'
+import { getRecipes, createRecipe, updateRecipe, removeRecipe } from '@/api/recipe'
+import Pagination from '@/components/Pagination'
+import SingleImage from '@/components/Upload/SingleImage'
+
+export default {
+  name: 'Index',
+  components: { Pagination, SingleImage },
+  data() {
+    return {
+      listQuery: {
+        query: '',
+        pageNum: 1,
+        pageSize: 20
+      },
+      listLoading: false,
+      list: [],
+      total: 0,
+      dialogFormVisible: false,
+      textMap: { 'create': '新建', 'edit': '更新' },
+      dialogStatus: '',
+      rules: {},
+      params: {}
+    }
+  },
+  created() {
+    this.fetchData()
+  },
+  methods: {
+    fetchData() {
+      this.listLoading = true
+      getRecipes(this.listQuery).then(res => {
+        this.list = res.data.list
+        this.listLoading = false
+      }).catch(res => {
+        this.$message.error('获取数据失败')
+        this.listLoading = false
+      })
+    },
+    handleCreateOrUpdate(dialogStatus, row) {
+      this.params = dialogStatus === 'create' ? {} : Object.assign({}, row)
+      this.dialogStatus = dialogStatus
+      this.dialogFormVisible = true
+
+    },
+    manageSteps(row) {
+      this.$router.push({ path: `recipe/${row.id}/step` })
+    },
+    manageFoods(row) {
+      this.$router.push({ path: `recipe/${row.id}/food` })
+    },
+    handleDelete(row) {
+      removeRecipe(row.id).then(res => {
+        this.$message.success('提交成功')
+        this.fetchData()
+      }).catch(res => {
+        this.$message.error(res.data.message)
+        this.fetchData()
+      })
+    },
+    createData() {
+      createRecipe(this.params).then(res => {
+        this.$message.success('提交成功')
+        this.dialogFormVisible = false
+        this.fetchData()
+      }).catch(res => {
+        this.$message.error(res.data.message)
+        this.fetchData()
+      })
+    },
+    updateData() {
+      updateRecipe(this.params.id, this.params).then(res => {
+        this.$message.success('提交成功')
+        this.dialogFormVisible = false
+        this.fetchData()
+      }).catch(res => {
+        this.$message.error(res.data.message)
+        this.fetchData()
+      })
+    },
+    updateFile(value) {
+      this.$set(this.params, 'coverPic', value)
+    }
   }
+}
 </script>
 
 <style scoped>

+ 142 - 0
src/views/recipe/step.vue

@@ -0,0 +1,142 @@
+<template>
+  <div class="app-container">
+    <el-button
+      class="filter-item"
+      style="margin-left: 10px;"
+      type="primary"
+      @click="handleCreateOrUpdate('create')">
+      添加
+    </el-button>
+
+    <el-table
+      :key="0"
+      v-loading="listLoading"
+      :data="list"
+      border
+      fit
+      highlight-current-row
+      style="width: 60%;margin-top: 10px"
+    >
+      <el-table-column type="index" label="序号" align="center" width="60px" />
+      <el-table-column label="内容" align="center">
+        <template slot-scope="{row}">
+          <span>{{ row.content }}</span>
+        </template>
+      </el-table-column>
+      <el-table-column label="图片" align="center">
+        <template slot-scope="{row}">
+          <el-image v-if="row.stepPic" style="width: 180px; height: 100px" :src="row.stepPic" fit="contain" />
+        </template>
+      </el-table-column>
+      <el-table-column label="操作" align="center" class-name="small-padding">
+        <template slot-scope="{row}">
+          <el-button size="mini" type="primary" @click="handleCreateOrUpdate('edit', row)">
+            更新
+          </el-button>
+          <el-button size="mini" type="danger" @click="handleDelete(row)">
+            删除
+          </el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+
+    <el-dialog :title="textMap[dialogStatus]" :visible.sync="dialogFormVisible">
+      <el-form ref="dataForm" :rules="rules" :model="params" label-position="left" label-width="100px" style="width: 400px; margin-left:50px;">
+        <el-form-item label="内容" prop="content">
+          <el-input v-model="params.content" placeholder="请输入步骤内容" type="textarea" :row="5" />
+        </el-form-item>
+        <el-form-item label="步骤图片" prop="stepPic">
+          <single-image :value="params.stepPic" :show-preview="true" @success="updateFile" style="width: 100%" />
+        </el-form-item>
+      </el-form>
+      <div slot="footer" class="dialog-footer">
+        <el-button @click="dialogFormVisible = false">
+          取消
+        </el-button>
+        <el-button type="primary" @click="dialogStatus==='create'?createData():updateData()">
+          提交
+        </el-button>
+      </div>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import SingleImage from '@/components/Upload/SingleImage'
+import { addRecipeStep, updateRecipeStep, removeRecipeStep, getRecipeSteps } from '@/api/recipe'
+
+export default {
+  name: 'RecipeStep',
+  components: { SingleImage },
+  data() {
+    return {
+      params: {},
+      listLoading: false,
+      list: [],
+      recipeId: '',
+      textMap: { 'create': '新建', 'edit': '更新' },
+      dialogStatus: '',
+      dialogFormVisible: false,
+      rules: {}
+    }
+  },
+  created() {
+    this.recipeId = this.$route.params && this.$route.params.id
+    this.fetchData()
+  },
+  methods: {
+    fetchData() {
+      this.listLoading = true
+      getRecipeSteps(this.recipeId).then(res => {
+        this.list = res.data.list
+        this.listLoading = false
+      }).catch(() => {
+        this.$message.error('获取数据失败')
+        this.list = []
+        this.listLoading = false
+      })
+    },
+    updateFile(value) {
+      this.$set(this.params, 'stepPic', value)
+    },
+    handleDelete(row) {
+      removeRecipeStep(this.recipeId, row.id).then(res => {
+        this.$message.success('提交成功')
+        this.fetchData()
+      }).catch(res => {
+        this.$message.error(res.data.message)
+        this.fetchData()
+      })
+    },
+    handleCreateOrUpdate(dialogStatus, row) {
+      this.params = dialogStatus === 'create' ? {} : Object.assign({}, row)
+      this.dialogStatus = dialogStatus
+      this.dialogFormVisible = true
+    },
+    createData() {
+      addRecipeStep(this.recipeId, this.params).then(res => {
+        this.fetchData()
+        this.dialogFormVisible = false
+        this.$message.success('提交成功')
+      }).catch(res => {
+        this.fetchData()
+        this.$message.error(res.data.message)
+      })
+    },
+    updateData() {
+      updateRecipeStep(this.recipeId, this.params.id, this.params).then(res => {
+        this.fetchData()
+        this.dialogFormVisible = false
+        this.$message.success('提交成功')
+      }).catch(res => {
+        this.fetchData()
+        this.$message.error(res.data.message)
+      })
+    }
+  }
+}
+</script>
+
+<style scoped>
+
+</style>