2
0

12 Commity b063924dc7 ... 5d8d8e83fa

Autor SHA1 Správa Dátum
  wangyang 5d8d8e83fa 修复营养物来源下拉框无反应的bug 4 rokov pred
  wangyang 83c18e2b5c update 4 rokov pred
  wangyang 47aaf31390 实现批量更新食物营养素 4 rokov pred
  wangyang f7fa77dea9 食物增加密密度 5 rokov pred
  wangyang 55c2a8e255 实现食物分享二维码 5 rokov pred
  wangyang 3373335fa8 update 5 rokov pred
  wangyang 93cc285565 完成录入员权限控制 5 rokov pred
  wangyang 7012e06733 食物如果是录入的默认按时间排序,如果是导入的默认按id排序 5 rokov pred
  wangyang c2e0be42a2 update 5 rokov pred
  wangyang 2d44e6eb81 修复单位基础单位保存不上,修复置顶->置底,修复营养素模板单位 5 rokov pred
  wangyang b5e059a335 食物菜单栏按来源分子菜单 5 rokov pred
  wangyang 285170c80d 食物规格的名称 拆分为包装名称和包装单位 5 rokov pred

+ 3 - 0
.env.development

@@ -4,3 +4,6 @@ PORT = '9531'
 
 # base api
 VUE_APP_BASE_API = '//localhost:8084'
+
+# h5 url
+VUE_APP_H5_URL = 'http://localhost/static-web/pages/feuc-test'

+ 3 - 0
.env.production

@@ -4,3 +4,6 @@ PORT = '9531'
 
 # base api
 VUE_APP_BASE_API = '//feuc.liveplus.online'
+
+# h5 url
+VUE_APP_H5_URL = 'https://h5.liveplus.online/static-web/feuc'

+ 3 - 0
.env.test

@@ -4,3 +4,6 @@ PORT = '9532'
 
 # base api
 VUE_APP_BASE_API = '//feuc-test.liveplus.online'
+
+# h5 url
+VUE_APP_H5_URL = 'http://h5.liveplus.online/static-web/feuc-test'

+ 3 - 2
package.json

@@ -23,10 +23,11 @@
     "normalize.css": "7.0.0",
     "nprogress": "0.2.0",
     "path-to-regexp": "2.4.0",
+    "sortablejs": "1.12.0",
     "vue": "2.6.10",
+    "vue-qr": "^2.3.0",
     "vue-router": "3.0.6",
-    "vuex": "3.1.0",
-    "sortablejs": "1.12.0"
+    "vuex": "3.1.0"
   },
   "devDependencies": {
     "@vue/cli-plugin-babel": "4.4.4",

+ 9 - 0
src/api/food.js

@@ -61,6 +61,15 @@ export function updateFoodNutrient(id, nutrientId, data) {
   })
 }
 
+// 批量更新食物关联的营养素
+export function multiUpdateNutrients(id, data) {
+  return request({
+    url: `/api/foods/${id}/nutrients/multi-update`,
+    method: 'post',
+    data
+  })
+}
+
 // 更新食物关联的营养素的排序
 export function updateFoodNutrientSort(id, nutrientId, data) {
   return request({

+ 21 - 7
src/router/config.js

@@ -23,7 +23,7 @@ export const asyncRouterMap = [
         path: '',
         name: '菜谱列表',
         component: () => import('@/views/recipe/index'),
-        meta: { title: '菜谱列表', icon: 'recipe' }
+        meta: { title: '菜谱列表', icon: 'recipe', admin: true }
       },
       {
         path: ':id/food',
@@ -44,12 +44,26 @@ export const asyncRouterMap = [
   {
     path: '/food',
     component: Layout,
+    name: '食物列表',
+    meta: { title: '食物列表', icon: 'food' },
     children: [
       {
         path: '',
-        name: '食物列表',
+        name: '全部',
         component: () => import('@/views/food/index'),
-        meta: { title: '食物列表', icon: 'food' }
+        meta: { title: '全部', admin: true  }
+      },
+      {
+        path: 'entry',
+        name: '录入',
+        component: () => import('@/views/food/index'),
+        meta: { title: '录入' }
+      },
+      {
+        path: 'cfct',
+        name: 'CFCT',
+        component: () => import('@/views/food/index'),
+        meta: { title: 'CFCT', admin: true  }
       },
       {
         path: 'create',
@@ -111,7 +125,7 @@ export const asyncRouterMap = [
         path: '',
         name: '营养素列表',
         component: () => import('@/views/nutrient/index'),
-        meta: { title: '营养素列表', icon: 'nutrient' }
+        meta: { title: '营养素列表', icon: 'nutrient', admin: true  }
       }
     ]
   },
@@ -124,7 +138,7 @@ export const asyncRouterMap = [
         path: '',
         name: '单位列表',
         component: () => import('@/views/unit/index'),
-        meta: { title: '单位列表', icon: 'unit' }
+        meta: { title: '单位列表', icon: 'unit', admin: true  }
       }
     ]
   },
@@ -138,7 +152,7 @@ export const asyncRouterMap = [
         path: '',
         name: '用户列表',
         component: () => import('@/views/user/index'),
-        meta: { title: '用户列表', icon: 'user' }
+        meta: { title: '用户列表', icon: 'user', admin: true  }
       }
     ]
   },
@@ -171,7 +185,7 @@ export const asyncRouterMap = [
         path: '',
         name: '食物种类管理',
         component: () => import('@/views/foodCategory/index'),
-        meta: { title: '食物种类管理', icon: 'category' }
+        meta: { title: '食物种类管理', icon: 'category', admin: true  }
       }
     ]
   },

+ 0 - 1
src/store/modules/user.js

@@ -1,6 +1,5 @@
 import { login, logout, getInfo } from '@/api/user'
 import { getToken, setToken, removeToken } from '@/utils/auth'
-import { resetRouter } from '@/router'
 import { Message } from 'element-ui'
 
 const getDefaultState = () => {

+ 30 - 0
src/utils/food-utils.js

@@ -0,0 +1,30 @@
+
+/**
+ * 计算食物来源对应的path
+ * @param {string} dataSource
+ * @returns {String}
+ */
+export function getFoodUrl(dataSource='') {
+  if (dataSource.indexOf('ENTRY') > -1) {
+    return '/food/entry'
+  } else if (dataSource.indexOf('CFCT') > -1) {
+    return '/food/cfct'
+  } else {
+    return '/food'
+  }
+}
+
+/**
+ * 根据url判断食物来源
+ * @param url
+ * @returns {string}
+ */
+export function getFoodSourceByUrl(url='') {
+  if (url.indexOf('entry') > -1){
+    return 'ENTRY'
+  } else if (url.indexOf('cfct') > -1) {
+    return 'CFCT'
+  } else {
+    return ''
+  }
+}

+ 8 - 27
src/utils/request.js

@@ -1,5 +1,6 @@
 import axios from 'axios'
 import { MessageBox, Message } from 'element-ui'
+import router from '@/router'
 import store from '@/store'
 import { getToken } from '@/utils/auth'
 
@@ -45,35 +46,15 @@ service.interceptors.response.use(
    */
   response => {
     return response
-    // const res = response.data
-    //
-    // // if the custom code is not 20000, it is judged as an error.
-    // if (res.code !== 20000) {
-    //   Message({
-    //     message: res.message || 'Error',
-    //     type: 'error',
-    //     duration: 5 * 1000
-    //   })
-    //
-    //   // 50008: Illegal token; 50012: Other clients logged in; 50014: Token expired;
-    //   if (res.code === 50008 || res.code === 50012 || res.code === 50014) {
-    //     // to re-login
-    //     MessageBox.confirm('You have been logged out, you can cancel to stay on this page, or log in again', 'Confirm logout', {
-    //       confirmButtonText: 'Re-Login',
-    //       cancelButtonText: 'Cancel',
-    //       type: 'warning'
-    //     }).then(() => {
-    //       store.dispatch('user/resetToken').then(() => {
-    //         location.reload()
-    //       })
-    //     })
-    //   }
-    //   return Promise.reject(new Error(res.message || 'Error'))
-    // } else {
-    //   return res
-    // }
   },
   error => {
+    // 如果为401则返回登录页
+    if (error.response.status === 401) {
+      Message({ message: '请重新登录', type: 'error', duration: 5 * 1000 })
+      store.dispatch('user/resetToken').then(() => {
+        router.replace({ path: '/login' })
+      })
+    }
     // 自行处理400+ 服务端定义的异常
     if (error.response.status < 400 || error.response.status >= 500) {
       Message({

+ 13 - 4
src/views/food/components/FoodDetail.vue

@@ -8,11 +8,12 @@
           <el-dropdown-item command="nutrient">营养素关联</el-dropdown-item>
           <el-dropdown-item command="unit">单位管理</el-dropdown-item>
           <el-dropdown-item command="modifier">规格管理</el-dropdown-item>
+          <el-dropdown-item command="list">食物列表</el-dropdown-item>
         </el-dropdown-menu>
       </el-dropdown>
     </floating-window>
 
-    <el-form ref="postForm" :model="postForm" :rules="rules" label-position="right" label-width="90px" class="form-container">
+    <el-form :disabled="!canEdit" ref="postForm" :model="postForm" :rules="rules" label-position="right" label-width="90px" class="form-container">
       <div class="createPost-main-container">
         <el-form-item label="自定义ID:" style="margin-bottom: 40px;width: 60%" prop="id2">
           <el-input v-model="postForm.id2" placeholder="请输入自定义ID" />
@@ -45,6 +46,9 @@
             style="width: 60%"
           />
         </el-form-item>
+        <el-form-item label="密度:" prop="density" style="margin-bottom: 40px;width: 60%">
+          <el-input v-model="postForm.density" placeholder="请输入密度" style="width: 60%" />
+        </el-form-item>
         <el-form-item label="食物主图" prop="coverPic">
           <single-image
             :value="postForm.mainImage"
@@ -119,6 +123,7 @@ import SingleImage from '@/components/Upload/SingleImage'
 import FloatingWindow from '@/components/FloatingWindow'
 import { getNutrientTemplates } from '@/api/nutrientTemplate'
 import { getFoodCategories } from '@/api/foodCategory'
+import store from '@/store'
 
 export default {
   name: "FoodDetail",
@@ -148,7 +153,8 @@ export default {
       importLoading: false,
       importType: 0,
       importId: '',
-      importItems: []
+      importItems: [],
+      canEdit: true
     }
   },
   mounted() {
@@ -170,6 +176,9 @@ export default {
     fetchData(id) {
       getDetail(id).then(res => {
         this.postForm = res.data
+        if (!store.getters.isAdmin && this.postForm.userId !== store.getters.userId){
+          this.canEdit = false
+        }
       })
     },
     fetchCategories() {
@@ -185,7 +194,7 @@ export default {
           resultPromise.then((res) => {
             this.$notify.success('提交成功')
             this.loading = false
-            const nextPath = this.isEdit ? '/food' : `/food/${res.data}/nutrient`
+            const nextPath = this.isEdit ? '/food/entry' : `/food/${res.data}/nutrient`
             this.$router.push({ path: nextPath })
           }).catch(res => {
             this.$message.error(res.data.message)
@@ -286,7 +295,7 @@ export default {
       } else if (value === 'modifier') {
         path = `/food/${this.foodId}/modifier`
       } else if (value === 'list') {
-        path = `/food`
+        path = store.getters.isAdmin ? '/food' : '/food/entry'
       }
       if (path) {
         this.$router.push({ path: path })

+ 98 - 0
src/views/food/components/MultiEditNutrients.vue

@@ -0,0 +1,98 @@
+<template>
+  <div>
+    <el-table
+      :key="tableKey"
+      :data="data"
+      border
+      fit
+      highlight-current-row
+      style="width: 100%;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.nutrientName }}</span>
+        </template>
+      </el-table-column>
+      <el-table-column label="营养素计量" align="center" :width="150">
+        <template slot-scope="{row}">
+          <el-radio v-model="row.radio" :label="0" @change="radioChange(row)">值</el-radio>
+          <el-radio v-model="row.radio" :label="1" @change="radioChange(row)">范围</el-radio>
+          <el-radio v-model="row.radio" :label="2" @change="radioChange(row)">误差</el-radio>
+          <div v-if="row.radio === 1" style="display: inline-block">
+            大于等于:
+            <el-input v-model="row.quantityMin" @focus="getInputFocus" />
+            小于等于:
+            <el-input v-model="row.quantityMax" @focus="getInputFocus" />
+          </div>
+          <div v-else-if="row.radio === 2" style="display: inline-block">
+            基准:
+            <el-input v-model="row.quantity" @focus="getInputFocus" />
+            ±:
+            <el-input v-model="row.stdError" @focus="getInputFocus" />
+          </div>
+          <el-input
+            v-else
+            v-model="row.quantity"
+            style="width: 80px;"
+            class="filter-item"
+            @focus="getInputFocus"
+          />
+        </template>
+      </el-table-column>
+      <el-table-column label="计量单位" align="center" width="150">
+        <template slot-scope="{row}">
+          <el-autocomplete
+            v-model="row.unit"
+            @input="handleRowUnitChanged(row)"
+            :fetch-suggestions="(query, cb) => {queryNutrientUnits(query, row.nutrientId, cb)}"
+            placeholder="单位关键词"
+          />
+          <el-select
+            clearable
+            v-show="showRowNutrientSource"
+            v-model="row.nutrientSource"
+            placeholder="请选择营养素来源"
+          >
+            <el-option v-for="item in nutrientSources" :key="item" :label="item" :value="item" />
+          </el-select>
+        </template>
+      </el-table-column>
+    </el-table>
+  </div>
+</template>
+
+<script>
+export default {
+  name: 'MultiEditNutrients',
+  props: {
+    data: {
+      type: Array,
+      default: []
+    }
+  },
+  data() {
+    return {
+      tableKey: 0,
+
+    }
+  },
+  created() {
+  },
+  methods: {
+    radioChange(row) {
+      this.$set(row, 'stdError', '')
+      this.$set(row, 'quantityMin', '')
+      this.$set(row, 'quantityMax', '')
+      this.$set(row, 'quantity', '')
+    },
+    getInputFocus(event) {
+      event.currentTarget.select();
+    },
+  }
+}
+</script>
+
+<style scoped>
+
+</style>

+ 82 - 0
src/views/food/components/NutrientQuantity.vue

@@ -0,0 +1,82 @@
+<template>
+  <div v-if="edit">
+    <el-radio v-model="data.radio" :label="0" @change="radioChange(data)">值</el-radio>
+    <el-radio v-model="data.radio" :label="1" @change="radioChange(data)">范围</el-radio>
+    <el-radio v-model="data.radio" :label="2" @change="radioChange(data)">误差</el-radio>
+    <div v-if="data.radio === 1" style="display: inline-block">
+      大于等于:
+      <el-input v-model="data.quantityMin" @focus="getInputFocus" />
+      小于等于:
+      <el-input v-model="data.quantityMax" @focus="getInputFocus" />
+    </div>
+    <div v-else-if="data.radio === 2" style="display: inline-block">
+      基准:
+      <el-input v-model="data.quantity" @focus="getInputFocus" />
+      ±:
+      <el-input v-model="data.stdError" @focus="getInputFocus" />
+    </div>
+    <el-input
+      v-else
+      v-model="data.quantity"
+      style="width: 80px;"
+      class="filter-item"
+      @focus="getInputFocus"
+    />
+  </div>
+  <div v-else>
+    <span>{{ data | nutrientQuantityFilter }}</span>
+  </div>
+</template>
+
+<script>
+export default {
+  name: 'NutrientQuantity',
+  props: {
+    data: { type: Object, default: {} },
+    edit: { type: Boolean, default: false }
+  },
+  filters: {
+    nutrientQuantityFilter(data) {
+      if (data.stdError) {
+        return `${data.quantity} ± ${data.stdError}`
+      }else if (data.quantityMin && data.quantityMax) {
+        return `${data.quantityMin} ~ ${data.quantityMax}`
+      } else if (data.quantityMin) {
+        return `≥${data.quantityMin}`
+      } else if (data.quantityMax) {
+        return `≤${data.quantityMax}`
+      } else {
+        return data.quantity
+      }
+    }
+  },
+  methods: {
+    radioChange(data) {
+      this.$set(data, 'stdError', '')
+      this.$set(data, 'quantityMin', '')
+      this.$set(data, 'quantityMax', '')
+      this.$set(data, 'quantity', '')
+    },
+    getInputFocus(event) {
+      event.currentTarget.select();
+    },
+  },
+  watch: {
+    edit(value) {
+      if (value) {
+        if (this.data.quantityMax || this.data.quantityMin) {
+          this.$set(this.data, 'radio', 1)
+        } else if (this.data.stdError) {
+          this.$set(this.data, 'radio', 2)
+        } else {
+          this.$set(this.data, 'radio', 0)
+        }
+      }
+    }
+  }
+}
+</script>
+
+<style scoped>
+
+</style>

+ 84 - 0
src/views/food/components/NutrientUnit.vue

@@ -0,0 +1,84 @@
+<template>
+  <div v-if="edit">
+    <el-autocomplete
+      v-model="data.unit"
+      @input="handleRowUnitChanged(data)"
+      :fetch-suggestions="(query, cb) => {queryNutrientUnits(query, data.nutrientId, cb)}"
+      placeholder="单位关键词"
+    />
+    <el-select
+      clearable
+      v-show="showRowNutrientSource"
+      v-model="data.nutrientSource"
+      :value-key="data.nutrientId"
+      placeholder="请选择营养素来源"
+    >
+      <el-option v-for="item in nutrientSources" :key="item" :label="item" :value="item" />
+    </el-select>
+  </div>
+  <div v-else>
+    <span>{{ data.nutrientSource ? `${data.unit}(${data.nutrientSource})` : data.unit }}</span>
+  </div>
+</template>
+
+<script>
+import { getNutrientSources, getNutrientUnits } from '@/api/nutrient'
+
+// 特殊营养素 若单位不为baseUnit,则需要填写来源
+const SPECIAL_NUTRIENT_NAMES = ['维生素A', '维生素D', '维生素E', '烟酸', '叶酸']
+
+export default {
+  name: 'NutrientUnit',
+  props: {
+    data: { type: Object, default: {} },
+    edit: { type: Boolean, default: false }
+  },
+  data() {
+    return {
+      nutrientSources: [],
+      showRowNutrientSource: false
+    }
+  },
+  methods: {
+    handleRowUnitChanged(data) {
+      if (SPECIAL_NUTRIENT_NAMES.indexOf(data.nutrientName) > -1) {
+        getNutrientSources(data.nutrientId, { unit: data.unit }).then(res => {
+          this.nutrientSources = res.data
+          if (this.nutrientSources.length > 0){
+            if (!data.nutrientSource) {
+              this.$set(data, 'nutrientSource', this.nutrientSources[0])
+            }
+            this.showRowNutrientSource = true
+          } else {
+            this.showRowNutrientSource = false
+            this.$set(data, 'nutrientSource', null)
+          }
+        })
+      } else {
+        this.showRowNutrientSource = false
+        this.$set(data, 'nutrientSource', null)
+      }
+    },
+    queryNutrientUnits(query, nutrientId, cb) {
+      let units = []
+      if (nutrientId) {
+        getNutrientUnits(nutrientId, { query }).then(res => {
+          res.data.forEach(item => units.push({ value: item }))
+          cb(units)
+        })
+      }
+    }
+  },
+  watch: {
+    edit(value) {
+      if (value) {
+        this.handleRowUnitChanged(this.data)
+      }
+    }
+  }
+}
+</script>
+
+<style scoped>
+
+</style>

+ 46 - 4
src/views/food/index.vue

@@ -45,6 +45,7 @@
       fit
       highlight-current-row
       style="width: 100%;"
+      @row-click="handleFoodClick"
     >
       <el-table-column type="index" label="序号" align="center" fixed width="60px" />
       <el-table-column label="名称" align="center" fixed width="200px">
@@ -97,6 +98,11 @@
           <span>{{ row.dataSource }}</span>
         </template>
       </el-table-column>
+      <el-table-column label="创建人" align="center" width="100px">
+        <template slot-scope="{row}">
+          <span>{{ row.userName }}</span>
+        </template>
+      </el-table-column>
       <el-table-column label="创建时间" width="180px" align="center">
         <template slot-scope="{row}">
           <span>{{ row.createTime }}</span>
@@ -114,12 +120,12 @@
               操作<i class="el-icon-arrow-down el-icon--right"></i>
             </el-button>
             <el-dropdown-menu slot="dropdown">
-              <el-dropdown-item :command="{row: row, command: 'update'}">更新</el-dropdown-item>
+              <el-dropdown-item :command="{row: row, command: 'update'}">更新/查看</el-dropdown-item>
               <el-dropdown-item :command="{row: row, command: 'copy'}">复制</el-dropdown-item>
               <el-dropdown-item :command="{row: row, command: 'manageNutrients'}">营养素关联</el-dropdown-item>
               <el-dropdown-item :command="{row: row, command: 'manageUnits'}">单位管理</el-dropdown-item>
               <el-dropdown-item :command="{row: row, command: 'manageModifiers'}">规格管理</el-dropdown-item>
-              <el-dropdown-item :command="{row: row, command: 'delete'}">删除</el-dropdown-item>
+              <el-dropdown-item :disabled="!canDelete(row)" :command="{row: row, command: 'delete'}">删除</el-dropdown-item>
             </el-dropdown-menu>
           </el-dropdown>
         </template>
@@ -173,6 +179,19 @@
         </el-button>
       </div>
     </el-dialog>
+
+    <el-dialog title="食物二维码" width="250" :visible.sync="foodQRDialogVisible">
+      <vue-qr
+        :text="foodQRParams.url"
+        :bgSrc="foodQRParams.bgImg"
+        :logoSrc="foodQRParams.logoImg"
+        :size="200"
+        :correctLevel="3"
+        colorDark="#000"
+        colorLight="#fff"
+        :dotScale="1"
+      ></vue-qr>
+    </el-dialog>
   </div>
 </template>
 
@@ -181,12 +200,15 @@ import Pagination from '@/components/Pagination'
 import { getList, remove, copyFromSimilarFood } from '@/api/food'
 import axios from 'axios'
 import { getToken } from '@/utils/auth'
+import { getFoodSourceByUrl } from '@/utils/food-utils'
+import store from '@/store'
+import VueQr from 'vue-qr'
 
 const foodTypes = { 0: '主材', 1: '辅材' }
 
 export default {
   name: 'FoodList',
-  components: { Pagination },
+  components: { Pagination, VueQr },
   filters: {
     foodTypeFilter(value) {
       return foodTypes[value]
@@ -210,15 +232,25 @@ export default {
       uploadFile: null,
       uploadLoading: false,
       copyDialogVisible: false,
-      params: {}
+      params: {},
+      foodSource: '',
+      foodQRDialogVisible: false,
+      foodQRParams: {}
     }
   },
   created() {
+    this.foodSource = getFoodSourceByUrl(this.$route.path)
+    if (this.foodSource === 'ENTRY' || this.foodSource === '') {
+      this.listQuery.orderBy = 0
+    } else {
+      this.listQuery.orderBy = 1
+    }
     this.fetchData()
   },
   methods: {
     fetchData() {
       this.listLoading = true
+      this.listQuery.foodSource = this.foodSource
       getList(this.listQuery).then(response => {
         this.list = response.data.list
         this.total = response.data.count
@@ -308,6 +340,16 @@ export default {
           this.handleDelete(data.row)
           break
       }
+    },
+    canDelete(data) {
+      return store.getters.isAdmin || data && data.userId === store.getters.userId
+    },
+    handleFoodClick(row) {
+      this.foodQRParams = { url: process.env.VUE_APP_H5_URL + `/food/index.html?id=${row.id}`,
+        bgImg: row.mainImage ? row.mainImage : '',
+        logoImg: row.mainImage ? row.mainImage : ''
+      }
+      this.foodQRDialogVisible = true
     }
   }
 }

+ 76 - 67
src/views/food/nutrient.vue

@@ -104,6 +104,7 @@
           class="filter-item"
           style="margin-left: 10px;"
           type="primary"
+          :disabled="!canEdit"
           @click="addNutrient">
           添加
         </el-button>
@@ -111,9 +112,28 @@
           class="filter-item"
           style="margin-left: 10px;"
           type="success"
+          :disabled="!canEdit"
           @click="handleImport">
           导入营养素
         </el-button>
+        <el-button
+          class="filter-item"
+          style="margin-left: 10px;"
+          type="success"
+          :disabled="!canEdit"
+          v-if="!editAll"
+          @click="handleMultiEdit">
+          批量编辑
+        </el-button>
+        <el-button
+          class="filter-item"
+          style="margin-left: 10px;"
+          type="primary"
+          :disabled="!canEdit"
+          v-else
+          @click="submitMulti">
+          批量提交
+        </el-button>
       </el-row>
     </div>
 
@@ -135,57 +155,17 @@
       </el-table-column>
       <el-table-column label="营养素计量" align="center" :width="150">
         <template slot-scope="{row}">
-          <template v-if="row.edit">
-            <el-radio v-model="row.radio" :label="0" @change="radioChange(row)">值</el-radio>
-            <el-radio v-model="row.radio" :label="1" @change="radioChange(row)">范围</el-radio>
-            <el-radio v-model="row.radio" :label="2" @change="radioChange(row)">误差</el-radio>
-            <div v-if="row.radio === 1" style="display: inline-block">
-              大于等于:
-              <el-input v-model="row.quantityMin" @focus="getInputFocus" />
-              小于等于:
-              <el-input v-model="row.quantityMax" @focus="getInputFocus" />
-            </div>
-            <div v-else-if="row.radio === 2" style="display: inline-block">
-              基准:
-              <el-input v-model="row.quantity" @focus="getInputFocus" />
-              ±:
-              <el-input v-model="row.stdError" @focus="getInputFocus" />
-            </div>
-            <el-input
-              v-else
-              v-model="row.quantity"
-              style="width: 80px;"
-              class="filter-item"
-              @focus="getInputFocus"
-            />
-          </template>
-          <span v-else>{{ row | nutrientQuantityFilter }}</span>
+          <nutrient-quantity :data="row" :edit="editAll || row.edit" />
         </template>
       </el-table-column>
       <el-table-column label="计量单位" align="center" width="150">
         <template slot-scope="{row}">
-          <template v-if="row.edit">
-            <el-autocomplete
-              v-model="row.unit"
-              @input="handleRowUnitChanged(row)"
-              :fetch-suggestions="(query, cb) => {queryNutrientUnits(query, row.nutrientId, cb)}"
-              placeholder="单位关键词"
-            />
-            <el-select
-              clearable
-              v-show="showRowNutrientSource"
-              v-model="row.nutrientSource"
-              placeholder="请选择营养素来源"
-            >
-              <el-option v-for="item in nutrientSources" :key="item" :label="item" :value="item" />
-            </el-select>
-          </template>
-          <span v-else>{{ row.nutrientSource ? `${row.unit}(${row.nutrientSource})` : row.unit }}</span>
+          <nutrient-unit :data="row" :edit="editAll || row.edit" />
         </template>
       </el-table-column>
       <el-table-column label="NRV%" align="center" width="80">
         <template slot-scope="{row}">
-          <template v-if="row.edit">
+          <template v-if="row.edit || editAll">
             <el-input v-show="!isPercentByVolumeUnit(row)" v-model="row.nrvPercent"/>
           </template>
           <span v-else>{{ row.nrvPercent }}</span>
@@ -193,7 +173,7 @@
       </el-table-column>
       <el-table-column label="Nv_Spec" align="center" width="80">
         <template slot-scope="{row}" v-if="!isPercentByVolumeUnit(row)">
-          <template v-if="row.edit">
+          <template v-if="row.edit || editAll">
             <el-input v-model="row.nvSpec" class="filter-item" @focus="getInputFocus" />
           </template>
           <span v-else>{{ row.nvSpec }}</span>
@@ -201,7 +181,7 @@
       </el-table-column>
       <el-table-column label="计量单位" align="center" width="150">
         <template slot-scope="{row}" v-if="!isPercentByVolumeUnit(row)">
-          <template v-if="row.edit">
+          <template v-if="row.edit || editAll">
             <el-autocomplete v-model="row.nvSpecUnit" :fetch-suggestions="queryUnits" placeholder="单位关键词" />
           </template>
           <span v-else>{{ row.nvSpecUnit }}</span>
@@ -209,7 +189,7 @@
       </el-table-column>
       <el-table-column label="信息来源" align="center" width="200">
         <template slot-scope="{row}">
-          <template v-if="row.edit">
+          <template v-if="row.edit || editAll">
             <el-autocomplete
               v-model="row.source"
               :fetch-suggestions="querySources"
@@ -221,13 +201,13 @@
       </el-table-column>
       <el-table-column label="信息来源备注" align="center" width="200">
         <template slot-scope="{row}">
-          <template v-if="row.edit">
+          <template v-if="row.edit || editAll">
             <el-input type="text" :rows="2" v-model="row.sourceNote" @focus="getInputFocus" />
           </template>
           <span v-else>{{ row.sourceNote }}</span>
         </template>
       </el-table-column>
-      <el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="320" fixed="right">
+      <el-table-column v-if="!editAll" label="操作" align="center" class-name="small-padding fixed-width" width="350" fixed="right">
         <template slot-scope="{row}">
           <template v-if="row.edit">
             <el-button
@@ -246,10 +226,10 @@
             </el-button>
           </template>
           <template v-else>
-            <el-button size="mini" type="primary" @click="handleEdit(row)">编辑</el-button>
-            <el-button size="mini" type="primary" @click="updateSort(row, 0)">上移</el-button>
-            <el-button size="mini" type="primary" @click="updateSort(row, 1)">下移</el-button>
-            <el-button size="mini" type="danger" @click="confirmRemoveNutrient(row)">
+            <el-button size="mini" type="primary" :disabled="!canEdit" @click="handleEdit(row)">编辑</el-button>
+            <el-button size="mini" type="primary" :disabled="!canEdit" @click="updateSort(row, 0)">上移</el-button>
+            <el-button size="mini" type="primary" :disabled="!canEdit" @click="updateSort(row, 1)">下移</el-button>
+            <el-button size="mini" type="danger" :disabled="!canEdit" @click="confirmRemoveNutrient(row)">
               删除
             </el-button>
           </template>
@@ -278,10 +258,10 @@
         </el-form-item>
       </el-form>
       <div slot="footer" class="dialog-footer">
-        <el-button @click="dialogFormVisible = false">
+        <el-button v-if="!editAll" @click="dialogFormVisible = false">
           取消
         </el-button>
-        <el-button type="primary" @click="submitImport">
+        <el-button v-if="!editAll" type="primary" @click="submitImport">
           提交
         </el-button>
       </div>
@@ -292,18 +272,21 @@
 <script>
 import { getNutrientList, addFoodNutrient, updateFoodNutrient, removeFoodNutrient,
   updateFoodNutrientSort, confirmDeleteFoodNutrient, importNutrientsFromTemplate,
-  getList as getFoodList, importNutrientFromSimilarFood } from '@/api/food'
+  getList as getFoodList, importNutrientFromSimilarFood, getDetail, multiUpdateNutrients } from '@/api/food'
 import FloatingWindow from '@/components/FloatingWindow'
 import { getList, getNutrientUnits, getNutrientSources } from '@/api/nutrient'
 import { getList as getUnits } from '@/api/unit'
 import { getNutrientTemplates } from '@/api/nutrientTemplate'
+import store from '@/store'
+import NutrientQuantity from '@/views/food/components/NutrientQuantity'
+import NutrientUnit from '@/views/food/components/NutrientUnit'
 
 // 特殊营养素 若单位不为baseUnit,则需要填写来源
 const SPECIAL_NUTRIENT_NAMES = ['维生素A', '维生素D', '维生素E', '烟酸', '叶酸']
 
 export default {
   name: 'AddNutrient',
-  components: { FloatingWindow },
+  components: { FloatingWindow, NutrientQuantity, NutrientUnit },
   mounted() {
     window.addEventListener('scroll', this.initHeight);
   },
@@ -353,15 +336,21 @@ export default {
       showNutrientSource: false,
       showRowNutrientSource: false,
       nutrientSources: [],
-      showNRV: false
+      showNRV: false,
+      canEdit: true,
+      editAll: false
     }
   },
   methods: {
     fetchData() {
       this.listLoading = true
+      getDetail(this.foodId).then(res => {
+        if (!store.getters.isAdmin && res.data.userId !== store.getters.userId) {
+          this.canEdit = false
+        }
+      })
       getNutrientList(this.foodId).then(res => {
         this.list = res.data
-        this.listLoading = false
         if (this.list.length > 0) {
           this.$set(this.params, "nvSpec", this.list[0].nvSpec)
           this.$set(this.params, "nvSpecUnit", this.list[0].nvSpecUnit)
@@ -369,8 +358,14 @@ export default {
           this.$set(this.params, 'nvSpec', 100)
           this.$set(this.params, 'nvSpecUnit', '克')
         }
+
+        this.resetParams()
       })
     },
+    resetParams() {
+      this.listLoading = false
+      this.editAll = false
+    },
     addNutrient() {
       this.params.foodId = this.foodId
       addFoodNutrient(this.foodId, this.params).then(res => {
@@ -425,10 +420,12 @@ export default {
     },
     queryNutrientUnits(query, nutrientId, cb) {
       let units = []
-      getNutrientUnits(nutrientId, { query }).then(res => {
-        res.data.forEach(item => units.push({ value: item }))
-        cb(units)
-      })
+      if (nutrientId) {
+        getNutrientUnits(nutrientId, { query }).then(res => {
+          res.data.forEach(item => units.push({ value: item }))
+          cb(units)
+        })
+      }
     },
     queryUnits(query, cb) {
       let units = []
@@ -456,6 +453,9 @@ export default {
       };
     },
     handleEdit(row) {
+      if (!this.canEdit) {
+        return
+      }
       this.$set(row, 'edit', true)
       if (row.quantityMax || row.quantityMin) {
         this.$set(row, 'radio', 1)
@@ -496,6 +496,15 @@ export default {
       this.queryImportItems()
       this.dialogFormVisible = true
     },
+    handleMultiEdit() {
+      this.editAll = !this.editAll
+    },
+    submitMulti() {
+      multiUpdateNutrients(this.foodId, this.list).then(res => {
+        this.fetchData()
+        this.$notify.success('提交成功')
+      })
+    },
     handleImportTypeChange() {
       this.importId = ''
       this.importItems = []
@@ -560,7 +569,7 @@ export default {
       } else if (value === 'modifier') {
         path = `/food/${this.foodId}/modifier`
       } else if (value === 'list') {
-        path = `/food`
+        path = store.getters.isAdmin ? '/food' : '/food/entry'
       }
       if (path) {
         this.$router.push({ path: path })
@@ -586,7 +595,7 @@ export default {
         getNutrientSources(this.params.nutrientId, { unit: this.params.unit }).then(res => {
           this.nutrientSources = res.data
           if (this.nutrientSources.length > 0){
-            this.params.nutrientSource = this.nutrientSources[0]
+            this.$set(this.params, "nutrientSource", this.nutrientSources[0])
             this.showNutrientSource = true
           } else {
             this.showNutrientSource = false
@@ -604,17 +613,17 @@ export default {
           this.nutrientSources = res.data
           if (this.nutrientSources.length > 0){
             if (!row.nutrientSource) {
-              row.nutrientSource = this.nutrientSources[0]
+              this.$set(row, 'nutrientSource', this.nutrientSources[0])
             }
             this.showRowNutrientSource = true
           } else {
             this.showRowNutrientSource = false
-            row.nutrientSource = null
+            this.$set(row, 'nutrientSource', null)
           }
         })
       } else {
         this.showRowNutrientSource = false
-        row.nutrientSource = null
+        this.$set(row, 'nutrientSource', null)
       }
     }
   }

+ 13 - 5
src/views/food/unit.vue

@@ -35,6 +35,7 @@
         class="filter-item"
         style="margin-left: 10px;"
         type="primary"
+        :disabled="!canEdit"
         @click="addFoodUnit"
       >
         添加
@@ -78,7 +79,7 @@
           >
             提交
           </el-button>
-          <el-button v-else size="mini" type="primary" @click="row.edit=true">编辑</el-button>
+          <el-button v-else size="mini" type="primary" :disabled="!canEdit" @click="row.edit=true">编辑</el-button>
           <el-button
             v-if="row.edit"
             type="danger"
@@ -87,7 +88,7 @@
           >
             取消
           </el-button>
-          <el-button v-else size="mini" type="danger" @click="removeFoodUnit(row)">
+          <el-button v-else size="mini" type="danger" :disabled="!canEdit" @click="removeFoodUnit(row)">
             删除
           </el-button>
         </template>
@@ -98,8 +99,9 @@
 
 <script>
 import { getBaseUnits, getList } from '@/api/unit'
-import { getFoodUnits, createOrUpdateFoodUnit, removeFoodUnit } from '@/api/food'
+import { getFoodUnits, createOrUpdateFoodUnit, removeFoodUnit, getDetail } from '@/api/food'
 import FloatingWindow from '@/components/FloatingWindow'
+import store from '@/store'
 
 export default {
   name: 'FoodUnit',
@@ -111,7 +113,8 @@ export default {
       listLoading: false,
       list: [],
       isFixed: false,
-      offsetTop: 0
+      offsetTop: 0,
+      canEdit: true
     }
   },
   mounted() {
@@ -136,6 +139,11 @@ export default {
       getFoodUnits(this.foodId).then(res => {
         this.list = res.data.list
       })
+      getDetail(this.foodId).then(res => {
+        if (!store.getters.isAdmin && res.data.userId !== store.getters.userId) {
+          this.canEdit = false
+        }
+      })
     },
     addFoodUnit() {
       this.params.foodId = this.foodId
@@ -191,7 +199,7 @@ export default {
       } else if (value === 'modifier') {
         path = `/food/${this.foodId}/modifier`
       } else if (value === 'list') {
-        path = `/food`
+        path = store.getters.isAdmin ? '/food' : '/food/entry'
       }
       if (path) {
         this.$router.push({ path: path })

+ 0 - 0
src/views/food/utils/index.js


+ 14 - 2
src/views/foodModifier/components/ModifierDetail.vue

@@ -17,9 +17,17 @@
     <el-form ref="postForm" :model="postForm" :rules="rules" label-position="right" label-width="130px" class="form-container">
       <div class="createPost-main-container">
         <el-checkbox @change="checkboxChange" :disabled="isEdit" v-model="isDefaultModifier" style="margin: 0 0 10px 100px">默认规格</el-checkbox>
-        <el-form-item label="规格名称:" style="margin-bottom: 40px;width: 60%" prop="name">
+        <el-form-item label="包装名称:" style="margin-bottom: 40px;width: 60%" prop="name">
           <el-input :disabled="isDefaultModifier" v-model="postForm.name" placeholder="请输入名称" @blur="updateUnit" />
         </el-form-item>
+        <el-form-item label="包装单位:" style="margin-bottom: 40px;width: 60%" prop="packageUnit">
+          <el-autocomplete
+            style="width: 100%"
+            v-model="postForm.packageUnit"
+            :fetch-suggestions="queryUnits"
+            placeholder="单位关键词"
+          />
+        </el-form-item>
         <el-row style="width: 60%">
           <el-col :span="12">
             <el-form-item v-show="!isDefaultModifier" label="数值:" style="margin-bottom: 40px" prop="quantity">
@@ -93,6 +101,7 @@ import Dropzone from '@/components/Dropzone'
 import FloatingWindow from '@/components/FloatingWindow'
 import { addFoodModifier, updateFoodModifier, getFoodModifier } from '@/api/food'
 import { getList as getUnits } from '@/api/unit'
+import store from '@/store'
 
 export default {
   name: "ModifierDetail",
@@ -193,6 +202,9 @@ export default {
       if (!this.postForm.inInitUnit && unitName) {
         this.$set(this.postForm, 'inInitUnit', unitName)
       }
+      if (!this.isEdit && !this.postForm.packageUnit && unitName) {
+        this.$set(this.postForm, 'packageUnit', unitName)
+      }
     },
     checkboxChange(value) {
       const name = value ? this.defaultModifierName : ''
@@ -220,7 +232,7 @@ export default {
       } else if (value === 'modifier') {
         path = `/food/${this.foodId}/modifier`
       } else if (value === 'list') {
-        path = `/food`
+        path = store.getters.isAdmin ? '/food' : '/food/entry'
       }
       if (path) {
         this.$router.push({ path: path })

+ 22 - 10
src/views/foodModifier/index.vue

@@ -7,6 +7,7 @@
         style="margin: 0 10px 20px 0; float: left;"
         type="success"
         icon="el-icon-circle-plus-outline"
+        :disabled="!canEdit"
         @click="handleCreate"
       >
         新建
@@ -16,6 +17,7 @@
         style="margin: 0 10px 20px 0; float: left;"
         type="success"
         icon="el-icon-circle-plus-outline"
+        :disabled="!canEdit"
         @click="importDialogVisible = true"
       >
         从近似食物导入
@@ -45,7 +47,7 @@
       @row-click="showDialog"
     >
       <el-table-column type="index" label="序号" align="center" fixed width="60px" />
-      <el-table-column label="规格名称" fixed align="center">
+      <el-table-column label="包装名称" fixed align="center">
         <template slot-scope="{row}">
           <span>{{ row.name }}</span>
         </template>
@@ -60,6 +62,11 @@
           />
         </template>
       </el-table-column>
+      <el-table-column label="包装单位" align="center">
+        <template slot-scope="{row}">
+          <span>{{ row.packageUnit }}</span>
+        </template>
+      </el-table-column>
       <el-table-column label="转换关系" align="center">
         <template slot-scope="{row}">
           <span v-if="row.quantity">{{ row.quantity + row.unit }}</span>
@@ -108,16 +115,16 @@
       </el-table-column>
       <el-table-column label="操作" align="center" class-name="small-padding" fixed="right" width="320">
         <template slot-scope="{row}">
-          <el-button type="primary" size="mini" @click.stop="handleUpdate(row)">
-            更新
+          <el-button type="primary" size="mini" :disabled="!canEdit" @click.stop="handleUpdate(row)">
+            更新/查看
           </el-button>
-          <el-button type="primary" size="mini" @click.stop="updateSort(row, 0)">
+          <el-button type="primary" size="mini" :disabled="!canEdit"  @click.stop="updateSort(row, 0)">
             上移
           </el-button>
-          <el-button type="primary" size="mini" @click.stop="updateSort(row, 1)">
+          <el-button type="primary" size="mini" :disabled="!canEdit"  @click.stop="updateSort(row, 1)">
             下移
           </el-button>
-          <el-button size="mini" type="danger" @click.stop="handleDelete(row)">
+          <el-button size="mini" type="danger" :disabled="!canEdit"  @click.stop="handleDelete(row)">
             删除
           </el-button>
         </template>
@@ -135,10 +142,11 @@
 </template>
 
 <script>
-import { getFoodModifiers, removeFoodModifier, updateFoodModifierSort, convertFoodUnit, getNutrientList,
-  getDetail, calculateNutrientsContent } from '@/api/food'
+import { getFoodModifiers, removeFoodModifier, updateFoodModifierSort, getDetail,
+  calculateNutrientsContent } from '@/api/food'
 import FloatingWindow from '@/components/FloatingWindow'
 import ModifierImport from './components/ModifierImport'
+import store from '@/store'
 
 const STATUS_MAP = { 0: '下架', 1: '上架' }
 
@@ -160,7 +168,8 @@ export default {
       dialogFormVisible: false,
       isFixed: false,
       offsetTop: 0,
-      importDialogVisible: false
+      importDialogVisible: false,
+      canEdit: true
     }
   },
   mounted() {
@@ -194,6 +203,9 @@ export default {
     fetchFood() {
       getDetail(this.foodId).then(res => {
         this.food = res.data
+        if (!store.getters.isAdmin && this.food.userId !== store.getters.userId) {
+          this.canEdit = false
+        }
       })
     },
     fetchData() {
@@ -239,7 +251,7 @@ export default {
       } else if (value === 'modifier') {
         path = `/food/${this.foodId}/modifier`
       } else if (value === 'list') {
-        path = `/food`
+        path = store.getters.isAdmin ? '/food' : '/food/entry'
       }
       if (path) {
         this.$router.push({ path: path })

+ 39 - 10
src/views/nutrientTemplate/detail.vue

@@ -7,12 +7,14 @@
           ref="nutrientSelect"
           v-model="params.nutrientId"
           filterable
+          clearable
           remote
           reserve-keyword
           style="width: 200px;margin-left: 10px;"
           placeholder="请输入营养素关键词"
           :remote-method="queryNutrients"
           :loading="loading"
+          @change="nutrientChanged"
         >
           <el-option v-for="item in nutrients" :key="item.id" :label="item.name" :value="item.id" />
         </el-select>
@@ -20,7 +22,7 @@
         <el-autocomplete
           class="inline-input"
           v-model="params.unit"
-          :fetch-suggestions="queryNutrientUnits(params.nutrientId)"
+          :fetch-suggestions="(query, cb) => {queryNutrientUnits(query, params.nutrientId, cb)}"
           @input="handleUnitChanged"
           placeholder="单位关键词"
         />
@@ -60,6 +62,7 @@
           class="filter-item"
           style="margin-left: 10px;"
           type="primary"
+          :disabled="!canEdit"
           @click="addNutrient"
         >
           添加
@@ -90,7 +93,7 @@
                 class="inline-input"
                 v-model="row.unit"
                 @input="handleRowUnitChanged(row)"
-                :fetch-suggestions="queryNutrientUnits(row.nutrientId)"
+                :fetch-suggestions="(query, cb) => {queryNutrientUnits(query, row.nutrientId, cb)}"
                 placeholder="单位关键词"
               />
               <el-select
@@ -168,8 +171,8 @@
               </el-button>
             </template>
             <template v-else>
-              <el-button size="mini" type="primary" @click="handleEdit(row)">编辑</el-button>
-              <el-button size="mini" type="danger" @click="removeNutrient(row)">
+              <el-button size="mini" type="primary" :disabled="!canEdit" @click="handleEdit(row)">编辑</el-button>
+              <el-button size="mini" type="danger" :disabled="!canEdit" @click="removeNutrient(row)">
                 删除
               </el-button>
             </template>
@@ -184,8 +187,9 @@
 import { getList, getNutrientUnits, getNutrientSources } from '@/api/nutrient'
 import { getList as getUnits } from '@/api/unit'
 import { getNutrients, addTemplateNutrient, updateTemplateNutrient, removeNutrient,
-  updateTemplateNutrientSort, updateBatchDetailSorts } from '@/api/nutrientTemplate'
+  updateTemplateNutrientSort, updateBatchDetailSorts, getNutrientTemplate } from '@/api/nutrientTemplate'
 import Sortable from 'sortablejs'
+import store from '@/store'
 
 // 特殊营养素 若单位不为baseUnit,则需要填写来源
 const SPECIAL_NUTRIENT_NAMES = ['维生素A', '维生素D', '维生素E', '烟酸', '叶酸']
@@ -208,7 +212,8 @@ export default {
       sortable: null,
       showNutrientSource: false,
       showRowNutrientSource: false,
-      nutrientSources: []
+      nutrientSources: [],
+      canEdit: true
     }
   },
   created() {
@@ -219,11 +224,20 @@ export default {
     }
     this.fetchNutrients()
     this.queryNutrients()
+    this.fetchData()
     this.$nextTick(() => {
       this.setSort()
     })
   },
   methods: {
+    fetchData() {
+      getNutrientTemplate(this.templateId).then(res => {
+        if (!store.getters.isAdmin && res.data.userId !== store.getters.userId) {
+          this.canEdit = false
+          this.sortable.option('disabled', true)
+        }
+      })
+    },
     addNutrient() {
       if (this.params.nutrientId) {
         addTemplateNutrient(this.templateId, this.params).then(res => {
@@ -310,10 +324,12 @@ export default {
     },
     queryNutrientUnits(query, nutrientId, cb) {
       let units = []
-      getNutrientUnits(nutrientId, { query }).then(res => {
-        res.data.forEach(item => units.push({ value: item }))
-        cb(units)
-      })
+      if (nutrientId) {
+        getNutrientUnits(nutrientId, { query }).then(res => {
+          res.data.forEach(item => units.push({ value: item }))
+          cb(units)
+        })
+      }
     },
     setSort() {
       const el = this.$refs.detailTable.$el.querySelectorAll('.el-table__body-wrapper > table > tbody')[0]
@@ -400,6 +416,19 @@ export default {
     },
     isPercentByVolumeUnit(row) {
       return row && row.unit === '%Vol'
+    },
+    nutrientChanged(value) {
+      for (let nutrient of this.nutrients) {
+        if (nutrient.id === value) {
+          this.$set(this.params, 'unit', nutrient.baseUnit)
+          if (nutrient.nrvUnit) {
+            this.showNRV = true
+          } else {
+            this.showNRV = false
+          }
+          break
+        }
+      }
     }
   }
 }

+ 4 - 4
src/views/nutrientTemplate/index.vue

@@ -64,12 +64,12 @@
               操作<i class="el-icon-arrow-down el-icon--right"></i>
             </el-button>
             <el-dropdown-menu slot="dropdown">
-              <el-dropdown-item :disabled="!canUpdate(row.userId)" :command="{row: row, command: 'update'}">更新</el-dropdown-item>
-              <el-dropdown-item :disabled="!canUpdate(row.userId)" :command="{row: row, command: 'manage'}">管理营养素</el-dropdown-item>
+              <el-dropdown-item :command="{row: row, command: 'update'}">更新/查看</el-dropdown-item>
+              <el-dropdown-item :command="{row: row, command: 'manage'}">管理营养素</el-dropdown-item>
               <el-dropdown-item :disabled="!canUpdate(row.userId)" :command="{row: row, command: 'moveUp'}">上移</el-dropdown-item>
               <el-dropdown-item :disabled="!canUpdate(row.userId)" :command="{row: row, command: 'moveDown'}">下移</el-dropdown-item>
               <el-dropdown-item :disabled="!canUpdate(row.userId)" :command="{row: row, command: 'moveTop'}">置顶</el-dropdown-item>
-              <el-dropdown-item :disabled="!canUpdate(row.userId)" :command="{row: row, command: 'moveBottom'}">置</el-dropdown-item>
+              <el-dropdown-item :disabled="!canUpdate(row.userId)" :command="{row: row, command: 'moveBottom'}">置</el-dropdown-item>
               <el-dropdown-item :disabled="!canUpdate(row.userId)" :command="{row: row, command: 'delete'}">删除</el-dropdown-item>
             </el-dropdown-menu>
           </el-dropdown>
@@ -98,7 +98,7 @@
         <el-button @click="dialogFormVisible = false">
           取消
         </el-button>
-        <el-button type="primary" @click="createOrUpdateData">
+        <el-button type="primary" :disabled="dialogStatus === 'update' && !canUpdate(params.userId)" @click="createOrUpdateData">
           提交
         </el-button>
       </div>

+ 2 - 3
src/views/unit/index.vue

@@ -88,8 +88,7 @@
               <el-dropdown-item :command="{row: row, command: 'moveUp'}">上移</el-dropdown-item>
               <el-dropdown-item :command="{row: row, command: 'moveDown'}">下移</el-dropdown-item>
               <el-dropdown-item :command="{row: row, command: 'moveTop'}">置顶</el-dropdown-item>
-              <el-dropdown-item :command="{row: row, command: 'moveBottom'}">置顶</el-dropdown-item>
-              <el-dropdown-item :command="{row: row, command: 'delete'}">删除</el-dropdown-item>
+              <el-dropdown-item :command="{row: row, command: 'moveBottom'}">置底</el-dropdown-item>
             </el-dropdown-menu>
           </el-dropdown>
         </template>
@@ -117,7 +116,7 @@
           <el-radio v-model="params.isBaseUnit" :label="false" :disabled="dialogStatus === 'UPDATE'">否</el-radio>
         </el-form-item>
         <el-form-item v-if="!params.isBaseUnit" label="基础单位" prop="code">
-          <el-select v-model="params.baseUnit" :disabled="dialogStatus === 'UPDATE'">
+          <el-select v-model="params.baseUnitId" :disabled="dialogStatus === 'UPDATE'">
             <el-option v-for="item in baseUnits" :key="item.id" :value="item.id" :label="item.name" />
           </el-select>
         </el-form-item>