Mr.Jiu 4 anni fa
parent
commit
2fae01907a

+ 13 - 2
.eslintrc.js

@@ -14,6 +14,15 @@ module.exports = {
   // add your custom rules here
   //it is base on https://github.com/vuejs/eslint-config-vue
   rules: {
+    "vue/html-self-closing": ["error", {
+      "html": {
+        "void": "never",
+        "normal": "always",
+        "component": "always"
+      },
+      "svg": "always",
+      "math": "always"
+    }],
     "vue/max-attributes-per-line": [2, {
       "singleline": 10,
       "multiline": {
@@ -22,7 +31,7 @@ module.exports = {
       }
     }],
     "vue/singleline-html-element-content-newline": "off",
-    "vue/multiline-html-element-content-newline":"off",
+    "vue/multiline-html-element-content-newline": "off",
     "vue/name-property-casing": ["error", "PascalCase"],
     "vue/no-v-html": "off",
     'accessor-pairs': 2,
@@ -47,7 +56,9 @@ module.exports = {
     'curly': [2, 'multi-line'],
     'dot-location': [2, 'property'],
     'eol-last': 2,
-    'eqeqeq': ["error", "always", {"null": "ignore"}],
+    'eqeqeq': ["error", "always", {
+      "null": "ignore"
+    }],
     'generator-star-spacing': [2, {
       'before': true,
       'after': true

+ 1 - 0
package.json

@@ -11,6 +11,7 @@
     "preview": "node build/index.js --preview",
     "svgo": "svgo -f src/icons/svg --config=src/icons/svgo.yml",
     "lint": "eslint --ext .js,.vue src",
+    "lintFix": "eslint --ext .js,.vue src --fix",
     "test:unit": "jest --clearCache && vue-cli-service test:unit",
     "test:ci": "npm run lint && npm run test:unit"
   },

+ 2 - 1
src/App.vue

@@ -6,6 +6,7 @@
 
 <script>
 export default {
-  name: 'App'
+  name: 'App',
+  meaths: {}
 }
 </script>

+ 186 - 185
src/components/Dropzone/index.vue

@@ -5,215 +5,216 @@
 </template>
 
 <script>
-  import Dropzone from 'dropzone'
-  import 'dropzone/dist/dropzone.css'
-  // import { getToken } from 'api/qiniu';
+import Dropzone from 'dropzone'
+import 'dropzone/dist/dropzone.css'
+// import { getToken } from 'api/qiniu';
 
-  Dropzone.autoDiscover = false
+Dropzone.autoDiscover = false
 
-  export default {
-    props: {
-      id: {
-        type: String,
-        required: true
-      },
-      url: {
-        type: String,
-        required: false
-      },
-      clickable: {
-        type: Boolean,
-        default: true
-      },
-      defaultMsg: {
-        type: String,
-        default: '上传图片'
-      },
-      acceptedFiles: {
-        type: String,
-        default: 'image/*'
-      },
-      thumbnailHeight: {
-        type: Number,
-        default: 200
-      },
-      thumbnailWidth: {
-        type: Number,
-        default: 200
-      },
-      showRemoveLink: {
-        type: Boolean,
-        default: true
-      },
-      maxFilesize: {
-        type: Number,
-        default: 100
-      },
-      maxFiles: {
-        type: Number,
-        default: 100
-      },
-      autoProcessQueue: {
-        type: Boolean,
-        default: true
-      },
-      useCustomDropzoneOptions: {
-        type: Boolean,
-        default: false
-      },
-      defaultImg: {
-        default: '',
-        type: [String, Array]
-      },
-      couldPaste: {
-        type: Boolean,
-        default: false
-      }
+export default {
+  props: {
+    id: {
+      type: String,
+      required: true
     },
-    created() {
-      this.uploadUrl = this.url ? this.url : `${process.env.VUE_APP_BASE_API}/api/files/upload`
+    url: {
+      type: String,
+      required: false,
+      default: ''
     },
-    data() {
-      return {
-        dropzone: '',
-        uploadUrl: '',
-        initOnce: true,
-      }
+    clickable: {
+      type: Boolean,
+      default: true
     },
-    watch: {
-      defaultImg(val) {
-        if (val.length === 0) {
-          this.initOnce = false
-          return
-        }
-        if (!this.initOnce) return
-        this.initImages(val)
+    defaultMsg: {
+      type: String,
+      default: '上传图片'
+    },
+    acceptedFiles: {
+      type: String,
+      default: 'image/*'
+    },
+    thumbnailHeight: {
+      type: Number,
+      default: 200
+    },
+    thumbnailWidth: {
+      type: Number,
+      default: 200
+    },
+    showRemoveLink: {
+      type: Boolean,
+      default: true
+    },
+    maxFilesize: {
+      type: Number,
+      default: 100
+    },
+    maxFiles: {
+      type: Number,
+      default: 100
+    },
+    autoProcessQueue: {
+      type: Boolean,
+      default: true
+    },
+    useCustomDropzoneOptions: {
+      type: Boolean,
+      default: false
+    },
+    defaultImg: {
+      default: '',
+      type: [String, Array]
+    },
+    couldPaste: {
+      type: Boolean,
+      default: false
+    }
+  },
+  data() {
+    return {
+      dropzone: '',
+      uploadUrl: '',
+      initOnce: true
+    }
+  },
+  watch: {
+    defaultImg(val) {
+      if (val.length === 0) {
         this.initOnce = false
+        return
       }
-    },
-    mounted() {
-      const element = document.getElementById(this.id)
-      const vm = this
-      this.dropzone = new Dropzone(element, {
-        headers: { Authorization: this.$store.getters.token },
-        clickable: this.clickable,
-        thumbnailWidth: this.thumbnailWidth,
-        thumbnailHeight: this.thumbnailHeight,
-        maxFiles: this.maxFiles,
-        maxFilesize: this.maxFilesize,
-        dictRemoveFile: 'Remove',
-        addRemoveLinks: this.showRemoveLink,
-        acceptedFiles: this.acceptedFiles,
-        autoProcessQueue: this.autoProcessQueue,
-        dictDefaultMessage: '<i style="margin-top: 3em;display: inline-block" class="material-icons">' + this.defaultMsg + '</i><br>Drop files here to upload',
-        dictMaxFilesExceeded: '只能一个图',
-        previewTemplate: '<div class="dz-preview dz-file-preview">  <div class="dz-image" style="width:' + this.thumbnailWidth + 'px;height:' + this.thumbnailHeight + 'px" ><img style="width:' + this.thumbnailWidth + 'px;height:' + this.thumbnailHeight + 'px" data-dz-thumbnail /></div>  <div class="dz-details"> <div class="dz-progress"><span class="dz-upload" data-dz-uploadprogress></span></div>  <div class="dz-error-message"><span data-dz-errormessage></span></div>  <div class="dz-success-mark"> <i class="material-icons">done</i> </div>  <div class="dz-error-mark"><i class="material-icons">error</i></div></div>',
-        init() {
-          const val = vm.defaultImg
-          if (!val) return
-          if (Array.isArray(val)) {
-            if (val.length === 0) return
-            val.map((v, i) => {
-              const mockFile = { name: 'name' + i, size: 12345, url: v }
-              this.options.addedfile.call(this, mockFile)
-              this.options.thumbnail.call(this, mockFile, v)
-              mockFile.previewElement.classList.add('dz-success')
-              mockFile.previewElement.classList.add('dz-complete')
-              vm.initOnce = false
-              return true
-            })
-          } else {
-            const mockFile = { name: 'name', size: 12345, url: val }
+      if (!this.initOnce) return
+      this.initImages(val)
+      this.initOnce = false
+    }
+  },
+  created() {
+    this.uploadUrl = this.url ? this.url : `${process.env.VUE_APP_BASE_API}/api/files/upload`
+  },
+  mounted() {
+    const element = document.getElementById(this.id)
+    const vm = this
+    this.dropzone = new Dropzone(element, {
+      headers: { Authorization: this.$store.getters.token },
+      clickable: this.clickable,
+      thumbnailWidth: this.thumbnailWidth,
+      thumbnailHeight: this.thumbnailHeight,
+      maxFiles: this.maxFiles,
+      maxFilesize: this.maxFilesize,
+      dictRemoveFile: 'Remove',
+      addRemoveLinks: this.showRemoveLink,
+      acceptedFiles: this.acceptedFiles,
+      autoProcessQueue: this.autoProcessQueue,
+      dictDefaultMessage: '<i style="margin-top: 3em;display: inline-block" class="material-icons">' + this.defaultMsg + '</i><br>Drop files here to upload',
+      dictMaxFilesExceeded: '只能一个图',
+      previewTemplate: '<div class="dz-preview dz-file-preview">  <div class="dz-image" style="width:' + this.thumbnailWidth + 'px;height:' + this.thumbnailHeight + 'px" ><img style="width:' + this.thumbnailWidth + 'px;height:' + this.thumbnailHeight + 'px" data-dz-thumbnail /></div>  <div class="dz-details"> <div class="dz-progress"><span class="dz-upload" data-dz-uploadprogress></span></div>  <div class="dz-error-message"><span data-dz-errormessage></span></div>  <div class="dz-success-mark"> <i class="material-icons">done</i> </div>  <div class="dz-error-mark"><i class="material-icons">error</i></div></div>',
+      init() {
+        const val = vm.defaultImg
+        if (!val) return
+        if (Array.isArray(val)) {
+          if (val.length === 0) return
+          val.map((v, i) => {
+            const mockFile = { name: 'name' + i, size: 12345, url: v }
             this.options.addedfile.call(this, mockFile)
-            this.options.thumbnail.call(this, mockFile, val)
+            this.options.thumbnail.call(this, mockFile, v)
             mockFile.previewElement.classList.add('dz-success')
             mockFile.previewElement.classList.add('dz-complete')
             vm.initOnce = false
-          }
-        },
-        accept: (file, done) => {
-          /* 七牛*/
-          // const token = this.$store.getters.token;
-          // getToken(token).then(response => {
-          //   file.token = response.data.qiniu_token;
-          //   file.key = response.data.qiniu_key;
-          //   file.url = response.data.qiniu_url;
-          //   done();
-          // })
-          done()
-        },
-        sending: (file, xhr, formData) => {
-          // formData.append('token', file.token);
-          // formData.append('key', file.key);
+            return true
+          })
+        } else {
+          const mockFile = { name: 'name', size: 12345, url: val }
+          this.options.addedfile.call(this, mockFile)
+          this.options.thumbnail.call(this, mockFile, val)
+          mockFile.previewElement.classList.add('dz-success')
+          mockFile.previewElement.classList.add('dz-complete')
           vm.initOnce = false
         }
-      })
-
-      if (this.couldPaste) {
-        document.addEventListener('paste', this.pasteImg)
+      },
+      accept: (file, done) => {
+        /* 七牛*/
+        // const token = this.$store.getters.token;
+        // getToken(token).then(response => {
+        //   file.token = response.data.qiniu_token;
+        //   file.key = response.data.qiniu_key;
+        //   file.url = response.data.qiniu_url;
+        //   done();
+        // })
+        done()
+      },
+      sending: (file, xhr, formData) => {
+        // formData.append('token', file.token);
+        // formData.append('key', file.key);
+        vm.initOnce = false
       }
+    })
 
-      this.dropzone.on('success', (file, response) => {
-        file.fileUrl = response.url
-        file.dropzoneId = vm.dropzone.element.id
-        vm.$emit('dropzone-success', file, vm.dropzone.element)
-      })
-      this.dropzone.on('addedfile', file => {
-        vm.$emit('dropzone-fileAdded', file)
-      })
-      this.dropzone.on('removedfile', file => {
-        vm.$emit('dropzone-removedFile', file, )
-      })
-      this.dropzone.on('error', (file, error, xhr) => {
-        vm.$emit('dropzone-error', file, error, xhr)
-      })
-      this.dropzone.on('successmultiple', (file, error, xhr) => {
-        vm.$emit('dropzone-successmultiple', file, error, xhr)
-      })
+    if (this.couldPaste) {
+      document.addEventListener('paste', this.pasteImg)
+    }
+
+    this.dropzone.on('success', (file, response) => {
+      file.fileUrl = response.url
+      file.dropzoneId = vm.dropzone.element.id
+      vm.$emit('dropzone-success', file, vm.dropzone.element)
+    })
+    this.dropzone.on('addedfile', file => {
+      vm.$emit('dropzone-fileAdded', file)
+    })
+    this.dropzone.on('removedfile', file => {
+      vm.$emit('dropzone-removedFile', file)
+    })
+    this.dropzone.on('error', (file, error, xhr) => {
+      vm.$emit('dropzone-error', file, error, xhr)
+    })
+    this.dropzone.on('successmultiple', (file, error, xhr) => {
+      vm.$emit('dropzone-successmultiple', file, error, xhr)
+    })
+  },
+  destroyed() {
+    document.removeEventListener('paste', this.pasteImg)
+    this.dropzone.destroy()
+  },
+  methods: {
+    removeAllFiles() {
+      this.dropzone.removeAllFiles(true)
     },
-    destroyed() {
-      document.removeEventListener('paste', this.pasteImg)
-      this.dropzone.destroy()
+    processQueue() {
+      this.dropzone.processQueue()
     },
-    methods: {
-      removeAllFiles() {
-        this.dropzone.removeAllFiles(true)
-      },
-      processQueue() {
-        this.dropzone.processQueue()
-      },
-      pasteImg(event) {
-        const items = (event.clipboardData || event.originalEvent.clipboardData).items
-        if (items[0].kind === 'file') {
-          this.dropzone.addFile(items[0].getAsFile())
-        }
-      },
-      initImages(val) {
-        if (!val) return
-        if (Array.isArray(val)) {
-          val.map((v, i) => {
-            // const fileUrl = `${process.env.VUE_APP_BASE_API}/api/files/view-file?path=${v}`
-            // const mockFile = { url: fileUrl }
-            const mockFile = { url: v }
-            this.dropzone.options.addedfile.call(this.dropzone, mockFile)
-            this.dropzone.options.thumbnail.call(this.dropzone, mockFile, v)
-            mockFile.previewElement.classList.add('dz-success')
-            mockFile.previewElement.classList.add('dz-complete')
-            return true
-          })
-        } else {
-          // const fileUrl = `${process.env.VUE_APP_BASE_API}/api/files/view-file?path=${val}`
+    pasteImg(event) {
+      const items = (event.clipboardData || event.originalEvent.clipboardData).items
+      if (items[0].kind === 'file') {
+        this.dropzone.addFile(items[0].getAsFile())
+      }
+    },
+    initImages(val) {
+      if (!val) return
+      if (Array.isArray(val)) {
+        val.map((v, i) => {
+          // const fileUrl = `${process.env.VUE_APP_BASE_API}/api/files/view-file?path=${v}`
           // const mockFile = { url: fileUrl }
-          const mockFile = { url: val }
+          const mockFile = { url: v }
           this.dropzone.options.addedfile.call(this.dropzone, mockFile)
-          this.dropzone.options.thumbnail.call(this.dropzone, mockFile, val)
+          this.dropzone.options.thumbnail.call(this.dropzone, mockFile, v)
           mockFile.previewElement.classList.add('dz-success')
           mockFile.previewElement.classList.add('dz-complete')
-        }
+          return true
+        })
+      } else {
+        // const fileUrl = `${process.env.VUE_APP_BASE_API}/api/files/view-file?path=${val}`
+        // const mockFile = { url: fileUrl }
+        const mockFile = { url: val }
+        this.dropzone.options.addedfile.call(this.dropzone, mockFile)
+        this.dropzone.options.thumbnail.call(this.dropzone, mockFile, val)
+        mockFile.previewElement.classList.add('dz-success')
+        mockFile.previewElement.classList.add('dz-complete')
       }
-
     }
+
   }
+}
 </script>
 
 <style scoped>

+ 48 - 48
src/components/FloatingWindow/index.vue

@@ -9,20 +9,20 @@
       @mouseenter="enter"
       @mouseleave="leave"
     >
-      <slot></slot>
+      <slot />
     </div>
   </div>
 </template>
 
 <script>
 export default {
-  props:{
-    ableMove: {type: Boolean, default: true},  //是否可移动
-    ableHide: {type: Boolean, default: true},  //是否靠边隐藏
-    hoverShow: {type: Boolean, default: true},  //图标隐藏时 鼠标悬浮即展示,否则点击展示
-    distance: {type: Number, default: 5},  //距离边界多少px就隐藏
-    defaultX: {type: Number, default: 1},  //初始横坐标百分比
-    defaultY: {type: Number, default: 0.1}  //初始纵坐标百分比
+  props: {
+    ableMove: { type: Boolean, default: true }, // 是否可移动
+    ableHide: { type: Boolean, default: true }, // 是否靠边隐藏
+    hoverShow: { type: Boolean, default: true }, // 图标隐藏时 鼠标悬浮即展示,否则点击展示
+    distance: { type: Number, default: 5 }, // 距离边界多少px就隐藏
+    defaultX: { type: Number, default: 1 }, // 初始横坐标百分比
+    defaultY: { type: Number, default: 0.1 } // 初始纵坐标百分比
   },
   data() {
     return {
@@ -32,88 +32,88 @@ export default {
       y0: 0,
       top: null,
       left: null
-    };
+    }
   },
   mounted() {
-    let img = document.querySelector(".suspendBox");
-    let box = document.querySelector(".outBox");
-    this.left = (box.offsetWidth - img.offsetWidth) * this.defaultX;
-    this.top = (box.offsetHeight - img.offsetHeight) * this.defaultY;
-    setTimeout(()=>{
+    const img = document.querySelector('.suspendBox')
+    const box = document.querySelector('.outBox')
+    this.left = (box.offsetWidth - img.offsetWidth) * this.defaultX
+    this.top = (box.offsetHeight - img.offsetHeight) * this.defaultY
+    setTimeout(() => {
       this.hide()
     }, 1000)
   },
   methods: {
     start(e) {
-      e.preventDefault();   //阻止默认的拖拽
-      if (e.button == 0) {
-        this.canDrag = this.ableMove;
-        this.isClick = true;
-        this.x0 = e.clientX;
-        this.y0 = e.clientY;
+      e.preventDefault() // 阻止默认的拖拽
+      if (e.button === 0) {
+        this.canDrag = this.ableMove
+        this.isClick = true
+        this.x0 = e.clientX
+        this.y0 = e.clientY
       }
     },
     move(e) {
-      if (this.canDrag == true) {
-        this.isClick = false;
-        let x = e.clientX - this.x0;
-        let y = e.clientY - this.y0;
-        let img = document.querySelector(".suspendBox");
-        let box = document.querySelector(".outBox");
+      if (this.canDrag === true) {
+        this.isClick = false
+        const x = e.clientX - this.x0
+        const y = e.clientY - this.y0
+        const img = document.querySelector('.suspendBox')
+        const box = document.querySelector('.outBox')
         if (
           img.offsetLeft + x < 0 ||
           img.offsetTop + y < 0 ||
           img.offsetLeft + x > box.offsetWidth - img.offsetWidth ||
           img.offsetTop + y > box.offsetHeight - img.offsetHeight
         ) {
-          return false;
+          return false
         }
-        this.left = img.offsetLeft + x;
-        this.top = img.offsetTop + y;
-        this.x0 = e.clientX;
-        this.y0 = e.clientY;
+        this.left = img.offsetLeft + x
+        this.top = img.offsetTop + y
+        this.x0 = e.clientX
+        this.y0 = e.clientY
       }
     },
     stop() {
-      this.canDrag = false;
-      this.show();
+      this.canDrag = false
+      this.show()
     },
     enter() {
       if (this.hoverShow) {
-        this.show();
+        this.show()
       }
     },
     leave() {
-      this.canDrag = false;
-      this.hide();
+      this.canDrag = false
+      this.hide()
     },
     show() {
-      let img = document.querySelector(".suspendBox");
-      let box = document.querySelector(".outBox");
+      const img = document.querySelector('.suspendBox')
+      const box = document.querySelector('.outBox')
       if (img.offsetLeft < 0) {
-        this.left = 0;
+        this.left = 0
       } else if (img.offsetLeft > box.offsetWidth - img.offsetWidth) {
         this.left = box.offsetWidth - img.offsetWidth
-      } else if(this.isClick){
+      } else if (this.isClick) {
         this.clickEvent()
       }
     },
     hide() {
       if (this.ableHide) {
-        let img = document.querySelector(".suspendBox");
-        let box = document.querySelector(".outBox");
+        const img = document.querySelector('.suspendBox')
+        const box = document.querySelector('.outBox')
         if (!this.canDrag && img.offsetLeft < this.distance) {
-          this.left = -img.offsetWidth * 2 / 3;
+          this.left = -img.offsetWidth * 2 / 3
         } else if (!this.canDrag && img.offsetLeft > box.offsetWidth - img.offsetWidth - this.distance) {
           this.left = box.offsetWidth - img.offsetWidth / 3
         }
       }
     },
-    clickEvent() {      //悬浮窗的点击事件
-      this.$emit("clickHandle")
-    },
-  },
-};
+    clickEvent() { // 悬浮窗的点击事件
+      this.$emit('clickHandle')
+    }
+  }
+}
 </script>
 <style scoped>
 .outBox {

+ 45 - 45
src/components/Upload/SingleImage.vue

@@ -1,6 +1,7 @@
 <template>
   <div class="upload-container">
     <el-upload
+      v-if="imageUrl.length <= 0"
       :data="dataObj"
       :multiple="false"
       :show-file-list="false"
@@ -10,7 +11,6 @@
       drag
       :action="uploadHost"
       :style="{ width: uploaderWidth}"
-      v-if="imageUrl.length <= 0"
     >
       <i class="el-icon-upload" />
       <div class="el-upload__text">
@@ -29,58 +29,58 @@
 </template>
 
 <script>
-  import store from '@/store'
+import store from '@/store'
 
-  export default {
-    name: 'SingleImageUpload',
-    props: {
-      value: {
-        type: String,
-        default: ''
-      },
-      showPreview: {
-        type: Boolean,
-        default: true
-      },
-      uploaderWidth: {
-        type: String,
-        default: '100%'
-      },
-      imageType: {
-        type: String,
-        default: ''
-      }
+export default {
+  name: 'SingleImageUpload',
+  props: {
+    value: {
+      type: String,
+      default: ''
+    },
+    showPreview: {
+      type: Boolean,
+      default: true
+    },
+    uploaderWidth: {
+      type: String,
+      default: '100%'
+    },
+    imageType: {
+      type: String,
+      default: ''
+    }
+  },
+  data() {
+    return {
+      uploadHost: process.env.VUE_APP_BASE_API + '/api/files/upload',
+      dataObj: { token: '', key: '' }
+    }
+  },
+  computed: {
+    imageUrl() {
+      return this.value
     },
-    data() {
+    uploadHeaders() {
       return {
-        uploadHost: process.env.VUE_APP_BASE_API + '/api/files/upload',
-        dataObj: { token: '', key: '' }
+        'Authorization': store.getters.token
       }
+    }
+  },
+  methods: {
+    rmImage() {
+      this.emitInput('')
+      this.$emit('success', { fileUrl: '', imageType: this.imageType })
     },
-    computed: {
-      imageUrl() {
-        return this.value
-      },
-      uploadHeaders() {
-        return {
-          'Authorization': store.getters.token
-        }
-      }
+    emitInput(val) {
+      this.$emit('input', val)
     },
-    methods: {
-      rmImage() {
-        this.emitInput('')
-        this.$emit("success", { fileUrl: '', imageType: this.imageType })
-      },
-      emitInput(val) {
-        this.$emit('input', val)
-      },
-      handleImageSuccess(response) {
-        this.emitInput(response.url)
-        this.$emit("success", { fileUrl: response.url, imageType: this.imageType })
-      }
+    handleImageSuccess(response) {
+      this.emitInput(response.url)
+      this.$emit('success', { fileUrl: response.url, imageType: this.imageType })
     }
   }
+}
 </script>
 
 <style lang="scss" scoped>

+ 1 - 1
src/layout/components/AppMain.vue

@@ -25,7 +25,7 @@ export default {
   position: relative;
   overflow: hidden;
 }
-.fixed-header+.app-main {
+.fixed-header + .app-main {
   padding-top: 50px;
 }
 </style>

+ 142 - 122
src/layout/components/Navbar.vue

@@ -1,20 +1,22 @@
 <template>
   <div class="navbar">
-    <hamburger :is-active="sidebar.opened" class="hamburger-container" @toggleClick="toggleSideBar" />
+    <hamburger
+      :is-active="sidebar.opened"
+      class="hamburger-container"
+      @toggleClick="toggleSideBar"
+    />
 
     <breadcrumb class="breadcrumb-container" />
 
     <div class="right-menu">
       <el-dropdown class="avatar-container" trigger="click">
         <div class="avatar-wrapper">
-          <img :src="avatar" class="user-avatar">
+          <img class="user-avatar" :src="avatar">
           <i class="el-icon-caret-bottom" />
         </div>
         <el-dropdown-menu slot="dropdown" class="user-dropdown">
           <router-link to="/">
-            <el-dropdown-item>
-              首页
-            </el-dropdown-item>
+            <el-dropdown-item>首页</el-dropdown-item>
           </router-link>
           <el-dropdown-item divided @click.native="changePassword">
             <span style="display:block;">修改密码</span>
@@ -46,156 +48,174 @@
         </el-form-item>
       </el-form>
       <div slot="footer" class="dialog-footer">
-        <el-button @click="dialogFormVisible = false">
-          取消
-        </el-button>
-        <el-button type="primary" @click="submit()">
-          提交
-        </el-button>
+        <el-button @click="dialogFormVisible = false">取消</el-button>
+        <el-button type="primary" @click="submit()">提交</el-button>
       </div>
     </el-dialog>
   </div>
 </template>
 
 <script>
-  import { mapGetters } from 'vuex'
-  import Breadcrumb from '@/components/Breadcrumb'
-  import Hamburger from '@/components/Hamburger'
-  import { changePassword } from '@/api/user'
-
-  export default {
-    components: {
-      Breadcrumb,
-      Hamburger
+import { mapGetters } from 'vuex'
+import Breadcrumb from '@/components/Breadcrumb'
+import Hamburger from '@/components/Hamburger'
+import { changePassword } from '@/api/user'
+
+export default {
+  components: {
+    Breadcrumb,
+    Hamburger
+  },
+  data() {
+    return {
+      dialogFormVisible: false,
+      params: {},
+      rules: {
+        password: [{ required: true, message: '不允许为空', trigger: 'blur' }],
+        newPassword: [
+          { required: true, message: '不允许为空', trigger: 'blur' }
+        ],
+        newPasswordConfirm: [
+          { required: true, message: '不允许为空', trigger: 'blur' }
+        ]
+      }
+    }
+  },
+  computed: {
+    ...mapGetters(['sidebar', 'avatar', 'userId'])
+  },
+  methods: {
+    toggleSideBar() {
+      this.$store.dispatch('app/toggleSideBar')
     },
-    computed: {
-      ...mapGetters([
-        'sidebar',
-        'avatar',
-        'userId'
-      ])
+    async logout() {
+      await this.$store.dispatch('user/logout')
+      this.$router.push(`/login?redirect=${this.$route.fullPath}`)
     },
-    data() {
-      return {
-        dialogFormVisible: false,
-        params: {},
-        rules: {
-          password: [{ required: true, message: '不允许为空', trigger: 'blur' }],
-          newPassword: [{ required: true, message: '不允许为空', trigger: 'blur' }],
-          newPasswordConfirm: [{ required: true, message: '不允许为空', trigger: 'blur' }]
-        }
-      }
+    changePassword() {
+      this.dialogFormVisible = true
+      this.params = {}
     },
-    methods: {
-      toggleSideBar() {
-        this.$store.dispatch('app/toggleSideBar')
-      },
-      async logout() {
-        await this.$store.dispatch('user/logout')
-        this.$router.push(`/login?redirect=${this.$route.fullPath}`)
-      },
-      changePassword() {
-        this.dialogFormVisible = true
-        this.params = {}
-      },
-      submit() {
-        this.$refs['dataForm'].validate((valid) => {
-          if (valid) {
-            if (this.params.newPassword !== this.params.newPasswordConfirm) {
-              this.$notify({ title: '失败', message: '两次输入密码不一致', type: 'error', duration: 2000 })
-            } else {
-              changePassword(this.userId, this.params).then(res => {
-                this.$notify({ title: '成功', message: '修改密码成功', type: 'success', duration: 2000 })
+    submit() {
+      this.$refs['dataForm'].validate(valid => {
+        if (valid) {
+          if (this.params.newPassword !== this.params.newPasswordConfirm) {
+            this.$notify({
+              title: '失败',
+              message: '两次输入密码不一致',
+              type: 'error',
+              duration: 2000
+            })
+          } else {
+            changePassword(this.userId, this.params)
+              .then(res => {
+                this.$notify({
+                  title: '成功',
+                  message: '修改密码成功',
+                  type: 'success',
+                  duration: 2000
+                })
                 this.dialogFormVisible = false
-              }).catch(error => {
-                this.$notify({ title: '失败', message: error.response.message, type: 'error', duration: 2000 })
+              })
+              .catch(error => {
+                this.$notify({
+                  title: '失败',
+                  message: error.response.message,
+                  type: 'error',
+                  duration: 2000
+                })
                 this.dialogFormVisible = false
               })
-            }
-          } else {
-            this.$notify({ title: '失败', message: '有必填字段为空', type: 'error', duration: 2000 })
           }
-        })
-      }
+        } else {
+          this.$notify({
+            title: '失败',
+            message: '有必填字段为空',
+            type: 'error',
+            duration: 2000
+          })
+        }
+      })
     }
   }
+}
 </script>
 
 <style lang="scss" scoped>
-  .navbar {
-    height: 50px;
-    overflow: hidden;
-    position: relative;
-    background: #fff;
-    box-shadow: 0 1px 4px rgba(0,21,41,.08);
-
-    .hamburger-container {
-      line-height: 46px;
-      height: 100%;
-      float: left;
-      cursor: pointer;
-      transition: background .3s;
-      -webkit-tap-highlight-color:transparent;
-
-      &:hover {
-        background: rgba(0, 0, 0, .025)
-      }
+.navbar {
+  height: 50px;
+  overflow: hidden;
+  position: relative;
+  background: #fff;
+  box-shadow: 0 1px 4px rgba(0, 21, 41, 0.08);
+
+  .hamburger-container {
+    line-height: 46px;
+    height: 100%;
+    float: left;
+    cursor: pointer;
+    transition: background 0.3s;
+    -webkit-tap-highlight-color: transparent;
+
+    &:hover {
+      background: rgba(0, 0, 0, 0.025);
     }
+  }
 
-    .breadcrumb-container {
-      float: left;
-    }
+  .breadcrumb-container {
+    float: left;
+  }
 
-    .right-menu {
-      float: right;
-      height: 100%;
-      line-height: 50px;
+  .right-menu {
+    float: right;
+    height: 100%;
+    line-height: 50px;
 
-      &:focus {
-        outline: none;
-      }
+    &:focus {
+      outline: none;
+    }
 
-      .right-menu-item {
-        display: inline-block;
-        padding: 0 8px;
-        height: 100%;
-        font-size: 18px;
-        color: #5a5e66;
-        vertical-align: text-bottom;
+    .right-menu-item {
+      display: inline-block;
+      padding: 0 8px;
+      height: 100%;
+      font-size: 18px;
+      color: #5a5e66;
+      vertical-align: text-bottom;
 
-        &.hover-effect {
-          cursor: pointer;
-          transition: background .3s;
+      &.hover-effect {
+        cursor: pointer;
+        transition: background 0.3s;
 
-          &:hover {
-            background: rgba(0, 0, 0, .025)
-          }
+        &:hover {
+          background: rgba(0, 0, 0, 0.025);
         }
       }
+    }
 
-      .avatar-container {
-        margin-right: 30px;
+    .avatar-container {
+      margin-right: 30px;
 
-        .avatar-wrapper {
-          margin-top: 5px;
-          position: relative;
+      .avatar-wrapper {
+        margin-top: 5px;
+        position: relative;
 
-          .user-avatar {
-            cursor: pointer;
-            width: 40px;
-            height: 40px;
-            border-radius: 10px;
-          }
+        .user-avatar {
+          cursor: pointer;
+          width: 40px;
+          height: 40px;
+          border-radius: 10px;
+        }
 
-          .el-icon-caret-bottom {
-            cursor: pointer;
-            position: absolute;
-            right: -20px;
-            top: 25px;
-            font-size: 12px;
-          }
+        .el-icon-caret-bottom {
+          cursor: pointer;
+          position: absolute;
+          right: -20px;
+          top: 25px;
+          font-size: 12px;
         }
       }
     }
   }
+}
 </style>

+ 33 - 33
src/layout/index.vue

@@ -51,43 +51,43 @@ export default {
 </script>
 
 <style lang="scss" scoped>
-  @import "~@/styles/mixin.scss";
-  @import "~@/styles/variables.scss";
+@import '~@/styles/mixin.scss';
+@import '~@/styles/variables.scss';
 
-  .app-wrapper {
-    @include clearfix;
-    position: relative;
-    height: 100%;
-    width: 100%;
-    &.mobile.openSidebar{
-      position: fixed;
-      top: 0;
-    }
-  }
-  .drawer-bg {
-    background: #000;
-    opacity: 0.3;
-    width: 100%;
-    top: 0;
-    height: 100%;
-    position: absolute;
-    z-index: 999;
-  }
-
-  .fixed-header {
+.app-wrapper {
+  @include clearfix;
+  position: relative;
+  height: 100%;
+  width: 100%;
+  &.mobile.openSidebar {
     position: fixed;
     top: 0;
-    right: 0;
-    z-index: 9;
-    width: calc(100% - #{$sideBarWidth});
-    transition: width 0.28s;
   }
+}
+.drawer-bg {
+  background: #000;
+  opacity: 0.3;
+  width: 100%;
+  top: 0;
+  height: 100%;
+  position: absolute;
+  z-index: 999;
+}
 
-  .hideSidebar .fixed-header {
-    width: calc(100% - 54px)
-  }
+.fixed-header {
+  position: fixed;
+  top: 0;
+  right: 0;
+  z-index: 9;
+  width: calc(100% - #{$sideBarWidth});
+  transition: width 0.28s;
+}
 
-  .mobile .fixed-header {
-    width: 100%;
-  }
+.hideSidebar .fixed-header {
+  width: calc(100% - 54px);
+}
+
+.mobile .fixed-header {
+  width: 100%;
+}
 </style>

+ 16 - 6
src/permission.js

@@ -1,12 +1,15 @@
 import router from './router'
 import store from './store'
-import { Message } from 'element-ui'
 import NProgress from 'nprogress' // progress bar
 import 'nprogress/nprogress.css' // progress bar style
-import { getToken } from '@/utils/auth' // get token from cookie
+import {
+  getToken
+} from '@/utils/auth' // get token from cookie
 import getPageTitle from '@/utils/get-page-title'
 
-NProgress.configure({ showSpinner: false }) // NProgress Configuration
+NProgress.configure({
+  showSpinner: false
+}) // NProgress Configuration
 
 const whiteList = ['/login'] // no redirect whitelist
 
@@ -23,7 +26,9 @@ router.beforeEach(async(to, from, next) => {
   if (hasToken) {
     if (to.path === '/login') {
       // if is logged in, redirect to the home page
-      next({ path: '/' })
+      next({
+        path: '/'
+      })
       NProgress.done()
     } else {
       const hasGetUserInfo = store.getters.name
@@ -41,10 +46,15 @@ router.beforeEach(async(to, from, next) => {
               const redirect = decodeURIComponent(from.query.redirect || to.path)
               if (to.path === redirect) {
                 // hack方法 确保addRoutes已完成 ,设置replace:true,以便导航不会留下历史记录
-                next({ ...to, replace: true })
+                next({
+                  ...to,
+                  replace: true
+                })
               } else {
                 // 跳转到目的路由
-                next({ path: redirect })
+                next({
+                  path: redirect
+                })
               }
             })
           })

+ 7 - 7
src/router/config.js

@@ -51,7 +51,7 @@ export const asyncRouterMap = [
         path: '',
         name: '全部',
         component: () => import('@/views/food/index'),
-        meta: { title: '全部', admin: true  }
+        meta: { title: '全部', admin: true }
       },
       {
         path: 'entry',
@@ -63,13 +63,13 @@ export const asyncRouterMap = [
         path: 'cfct',
         name: 'CFCT',
         component: () => import('@/views/food/index'),
-        meta: { title: 'CFCT', admin: true  }
+        meta: { title: 'CFCT', admin: true }
       },
       {
         path: 'usda',
         name: 'USDA',
         component: () => import('@/views/food/index'),
-        meta: { title: 'USDA', admin: true  }
+        meta: { title: 'USDA', admin: true }
       },
       {
         path: 'create',
@@ -131,7 +131,7 @@ export const asyncRouterMap = [
         path: '',
         name: '营养素列表',
         component: () => import('@/views/nutrient/index'),
-        meta: { title: '营养素列表', icon: 'nutrient', admin: true  }
+        meta: { title: '营养素列表', icon: 'nutrient', admin: true }
       }
     ]
   },
@@ -144,7 +144,7 @@ export const asyncRouterMap = [
         path: '',
         name: '单位列表',
         component: () => import('@/views/unit/index'),
-        meta: { title: '单位列表', icon: 'unit', admin: true  }
+        meta: { title: '单位列表', icon: 'unit', admin: true }
       }
     ]
   },
@@ -158,7 +158,7 @@ export const asyncRouterMap = [
         path: '',
         name: '用户列表',
         component: () => import('@/views/user/index'),
-        meta: { title: '用户列表', icon: 'user', admin: true  }
+        meta: { title: '用户列表', icon: 'user', admin: true }
       }
     ]
   },
@@ -191,7 +191,7 @@ export const asyncRouterMap = [
         path: '',
         name: '食物种类管理',
         component: () => import('@/views/foodCategory/index'),
-        meta: { title: '食物种类管理', icon: 'category', admin: true  }
+        meta: { title: '食物种类管理', icon: 'category', admin: true }
       }
     ]
   },

+ 42 - 13
src/store/modules/user.js

@@ -1,6 +1,16 @@
-import { login, logout, getInfo } from '@/api/user'
-import { getToken, setToken, removeToken } from '@/utils/auth'
-import { Message } from 'element-ui'
+import {
+  login,
+  logout,
+  getInfo
+} from '@/api/user'
+import {
+  getToken,
+  setToken,
+  removeToken
+} from '@/utils/auth'
+import {
+  Message
+} from 'element-ui'
 
 const getDefaultState = () => {
   return {
@@ -43,11 +53,14 @@ const mutations = {
 
 const actions = {
   // user login
-  login({ commit }, userInfo) {
-    const { username, password } = userInfo
+  login({
+    commit
+  }, userInfo) {
     return new Promise((resolve, reject) => {
       login(userInfo).then(response => {
-        const { data } = response
+        const {
+          data
+        } = response
         commit('SET_TOKEN', data.token)
         setToken(data.token)
         resolve()
@@ -59,23 +72,35 @@ const actions = {
   },
 
   // get user info
-  getInfo({ commit, state }) {
+  getInfo({
+    commit,
+    state
+  }) {
     return new Promise((resolve, reject) => {
       getInfo().then(response => {
-        const { data } = response
+        const {
+          data
+        } = response
 
         if (!data) {
           return reject('Token 无效,请重新登录。')
         }
 
-        const { id, name, nickName, profilePic, isAdmin, isFrozen } = data
+        const {
+          id,
+          name,
+          nickName,
+          profilePic,
+          isAdmin,
+          isFrozen
+        } = data
 
         if (isFrozen) {
           return reject('用户账号冻结,请与管理员联系')
         }
 
         commit('SET_USER_ID', id)
-        commit('SET_NAME', nickName ? nickName : name)
+        commit('SET_NAME', nickName || name)
         commit('SET_AVATAR', profilePic)
         commit('SET_IS_ADMIN', isAdmin)
         commit('SET_IS_FROZEN', isFrozen)
@@ -89,7 +114,10 @@ const actions = {
   },
 
   // user logout
-  logout({ commit, state }) {
+  logout({
+    commit,
+    state
+  }) {
     return new Promise((resolve, reject) => {
       logout(state.token).then(() => {
         removeToken() // must remove  token  first
@@ -103,7 +131,9 @@ const actions = {
   },
 
   // remove token
-  resetToken({ commit }) {
+  resetToken({
+    commit
+  }) {
     return new Promise(resolve => {
       removeToken() // must remove  token  first
       commit('RESET_STATE')
@@ -118,4 +148,3 @@ export default {
   mutations,
   actions
 }
-

+ 3 - 3
src/utils/food-utils.js

@@ -4,7 +4,7 @@
  * @param {string} dataSource
  * @returns {String}
  */
-export function getFoodUrl(dataSource='') {
+export function getFoodUrl(dataSource = '') {
   if (dataSource.indexOf('ENTRY') > -1) {
     return '/food/entry'
   } else if (dataSource.indexOf('CFCT') > -1) {
@@ -19,8 +19,8 @@ export function getFoodUrl(dataSource='') {
  * @param url
  * @returns {string}
  */
-export function getFoodSourceByUrl(url='') {
-  if (url.indexOf('entry') > -1){
+export function getFoodSourceByUrl(url = '') {
+  if (url.indexOf('entry') > -1) {
     return 'ENTRY'
   } else if (url.indexOf('cfct') > -1) {
     return 'CFCT'

+ 14 - 4
src/utils/request.js

@@ -1,8 +1,12 @@
 import axios from 'axios'
-import { MessageBox, Message } from 'element-ui'
+import {
+  Message
+} from 'element-ui' // MessageBox
 import router from '@/router'
 import store from '@/store'
-import { getToken } from '@/utils/auth'
+import {
+  getToken
+} from '@/utils/auth'
 
 // create an axios instance
 const service = axios.create({
@@ -50,9 +54,15 @@ service.interceptors.response.use(
   error => {
     // 如果为401则返回登录页
     if (error.response.status === 401) {
-      Message({ message: '请重新登录', type: 'error', duration: 5 * 1000 })
+      Message({
+        message: '请重新登录',
+        type: 'error',
+        duration: 5 * 1000
+      })
       store.dispatch('user/resetToken').then(() => {
-        router.replace({ path: '/login' })
+        router.replace({
+          path: '/login'
+        })
       })
     }
     // 自行处理400+ 服务端定义的异常

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

@@ -1,12 +1,11 @@
 <template>
-  <div class="dashboard-container">
-  </div>
+  <div class="dashboard-container" />
 </template>
 
 <script>
 
 export default {
-  name: 'Dashboard',
+  name: 'Dashboard'
 
 }
 </script>

+ 22 - 22
src/views/food/components/FoodDetail.vue

@@ -1,9 +1,9 @@
 <template>
   <div class="createPost-container">
 
-    <floating-window v-if="isEdit" :class="{'is_fixed': isFixed}" >
+    <floating-window v-if="isEdit" :class="{'is_fixed': isFixed}">
       <el-dropdown @command="handleCommand">
-        <img width="50px" height="50px" src="@/assets/navigation.png" alt="导航.png" />
+        <img width="50px" height="50px" src="@/assets/navigation.png" alt="导航.png">
         <el-dropdown-menu slot="dropdown">
           <el-dropdown-item command="nutrient">营养素关联</el-dropdown-item>
           <el-dropdown-item command="unit">单位管理</el-dropdown-item>
@@ -13,7 +13,7 @@
       </el-dropdown>
     </floating-window>
 
-    <el-form :disabled="!canEdit" ref="postForm" :model="postForm" :rules="rules" label-position="right" label-width="90px" class="form-container">
+    <el-form ref="postForm" :disabled="!canEdit" :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" />
@@ -25,8 +25,8 @@
           <el-input v-model="postForm.description" type="textarea" :rows="4" placeholder="请输入描述" />
         </el-form-item>
         <el-form-item label="食物类型:" prop="foodType" style="margin-bottom: 30px;width: 40%">
-          <el-radio :label="0" v-model="postForm.foodType">主材</el-radio>
-          <el-radio :label="1" v-model="postForm.foodType">辅材</el-radio>
+          <el-radio v-model="postForm.foodType" :label="0">主材</el-radio>
+          <el-radio v-model="postForm.foodType" :label="1">辅材</el-radio>
         </el-form-item>
         <el-form-item label="ep:" prop="ep" style="margin-bottom: 40px;width: 60%">
           <el-input v-model="postForm.ep" placeholder="请输入ep" style="width: 60%" />
@@ -42,8 +42,8 @@
             v-model="postForm.categoryId"
             :options="foodCategories"
             :props="categoriesProp"
-            @change="handleChange"
             style="width: 60%"
+            @change="handleChange"
           />
         </el-form-item>
         <el-form-item label="密度:" prop="density" style="margin-bottom: 40px;width: 60%">
@@ -54,8 +54,8 @@
             :value="postForm.mainImage"
             image-type="MAIN"
             :show-preview="true"
-            @success="updateFile"
             style="width: 60%"
+            @success="updateFile"
           />
         </el-form-item>
         <el-form-item label="营养素图片" prop="coverPic">
@@ -78,16 +78,16 @@
         <el-button v-loading="loading" style="margin-left: 10px;" type="success" @click="submitForm">
           保存
         </el-button>
-        <el-button v-loading="loading" style="margin-left: 10px;" type="success" v-if="!isEdit" @click="handleDialog">
+        <el-button v-if="!isEdit" v-loading="loading" style="margin-left: 10px;" type="success" @click="handleDialog">
           保存并导入营养素
         </el-button>
       </div>
     </el-form>
 
-    <el-dialog title="导入营养素" :visible.sync="dialogFormVisible" v-loading="importLoading">
+    <el-dialog v-loading="importLoading" title="导入营养素" :visible.sync="dialogFormVisible">
       <el-form ref="dialogForm" label-position="left" style="width: 80%; margin-left:50px;">
-        <el-radio :label="0" v-model="importType" @change="handleImportTypeChange" >从模板导入</el-radio>
-        <el-radio :label="1" v-model="importType" @change="handleImportTypeChange" style="margin-bottom: 10px">从食物导入</el-radio>
+        <el-radio v-model="importType" :label="0" @change="handleImportTypeChange">从模板导入</el-radio>
+        <el-radio v-model="importType" :label="1" style="margin-bottom: 10px" @change="handleImportTypeChange">从食物导入</el-radio>
         <el-form-item prop="importId">
           <el-select
             v-model="importId"
@@ -126,7 +126,7 @@ import { getFoodCategories } from '@/api/foodCategory'
 import store from '@/store'
 
 export default {
-  name: "FoodDetail",
+  name: 'FoodDetail',
   components: { Dropzone, SingleImage, FloatingWindow },
   props: {
     isEdit: {
@@ -158,9 +158,9 @@ export default {
     }
   },
   mounted() {
-    window.addEventListener('scroll', this.initHeight);
+    window.addEventListener('scroll', this.initHeight)
   },
-  //回调中移除监听
+  // 回调中移除监听
   destroyed() {
     window.removeEventListener('scroll', this.handleScroll)
   },
@@ -176,7 +176,7 @@ export default {
     fetchData(id) {
       getDetail(id).then(res => {
         this.postForm = res.data
-        if (!store.getters.isAdmin && this.postForm.userId !== store.getters.userId){
+        if (!store.getters.isAdmin && this.postForm.userId !== store.getters.userId) {
           this.canEdit = false
         }
       })
@@ -207,7 +207,7 @@ export default {
       })
     },
     removeFile(file) {
-      let imgs = this.postForm.otherImages
+      const imgs = this.postForm.otherImages
       let imgIndex = -1
       for (let i = 0; i < imgs.length; i++) {
         if (imgs[i] === file.url) {
@@ -229,10 +229,10 @@ export default {
       this.importItems = []
       this.queryImportItems()
     },
-    queryImportItems(query=''){
+    queryImportItems(query = '') {
       this.importType === 0 ? this.queryTemplates(query) : this.queryFoods(query)
     },
-    queryTemplates(query='') {
+    queryTemplates(query = '') {
       this.importLoading = true
       getNutrientTemplates({ query }).then(res => {
         this.importItems = res.data.list
@@ -245,7 +245,7 @@ export default {
         this.importLoading = false
       })
     },
-    queryFoods(query='') {
+    queryFoods(query = '') {
       this.importLoading = true
       getFoodList({ query: query, orderBy: 0, pageNum: 1, pageSize: 20 }).then(res => {
         this.importItems = res.data.list
@@ -276,15 +276,15 @@ export default {
     updateFile(data) {
       if (data.imageType === 'MAIN') {
         this.$set(this.postForm, 'mainImage', data.fileUrl)
-      } else if (data.imageType === "NUTRIENT") {
+      } else if (data.imageType === 'NUTRIENT') {
         this.$set(this.postForm, 'nutrientImage', data.fileUrl)
       }
     },
     initHeight() {
       // 设置或获取位于对象最顶端和窗口中可见内容的最顶端之间的距离 (被卷曲的高度)
       const scrollTop = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop
-      //如果被卷曲的高度大于吸顶元素到顶端位置 的距离
-      this.isFixed = scrollTop > this.offsetTop;
+      // 如果被卷曲的高度大于吸顶元素到顶端位置 的距离
+      this.isFixed = scrollTop > this.offsetTop
     },
     handleCommand(value) {
       let path = ''

+ 6 - 6
src/views/food/components/MultiEditNutrients.vue

@@ -44,14 +44,14 @@
         <template slot-scope="{row}">
           <el-autocomplete
             v-model="row.unit"
-            @input="handleRowUnitChanged(row)"
             :fetch-suggestions="(query, cb) => {queryNutrientUnits(query, row.nutrientId, cb)}"
             placeholder="单位关键词"
+            @input="handleRowUnitChanged(row)"
           />
           <el-select
-            clearable
             v-show="showRowNutrientSource"
             v-model="row.nutrientSource"
+            clearable
             placeholder="请选择营养素来源"
           >
             <el-option v-for="item in nutrientSources" :key="item" :label="item" :value="item" />
@@ -68,12 +68,12 @@ export default {
   props: {
     data: {
       type: Array,
-      default: []
+      default: () => []
     }
   },
   data() {
     return {
-      tableKey: 0,
+      tableKey: 0
 
     }
   },
@@ -87,8 +87,8 @@ export default {
       this.$set(row, 'quantity', '')
     },
     getInputFocus(event) {
-      event.currentTarget.select();
-    },
+      event.currentTarget.select()
+    }
   }
 }
 </script>

+ 17 - 20
src/views/food/components/NutrientQuantity.vue

@@ -5,14 +5,12 @@
     <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.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.quantity" @focus="getInputFocus" />±:
       <el-input v-model="data.stdError" @focus="getInputFocus" />
     </div>
     <el-input
@@ -31,15 +29,11 @@
 <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) {
+      } else if (data.quantityMin && data.quantityMax) {
         return `${data.quantityMin} ~ ${data.quantityMax}`
       } else if (data.quantityMin) {
         return `≥${data.quantityMin}`
@@ -50,16 +44,9 @@ export default {
       }
     }
   },
-  methods: {
-    radioChange(data) {
-      this.$set(data, 'stdError', '')
-      this.$set(data, 'quantityMin', '')
-      this.$set(data, 'quantityMax', '')
-      this.$set(data, 'quantity', '')
-    },
-    getInputFocus(event) {
-      event.currentTarget.select();
-    },
+  props: {
+    data: { type: Object, default: () => {} },
+    edit: { type: Boolean, default: false }
   },
   watch: {
     edit(value) {
@@ -73,10 +60,20 @@ export default {
         }
       }
     }
+  },
+  methods: {
+    radioChange(data) {
+      this.$set(data, 'stdError', '')
+      this.$set(data, 'quantityMin', '')
+      this.$set(data, 'quantityMax', '')
+      this.$set(data, 'quantity', '')
+    },
+    getInputFocus(event) {
+      event.currentTarget.select()
+    }
   }
 }
 </script>
 
 <style scoped>
-
 </style>

+ 12 - 14
src/views/food/components/NutrientUnit.vue

@@ -2,14 +2,14 @@
   <div v-if="edit">
     <el-autocomplete
       v-model="data.unit"
-      @input="handleRowUnitChanged(data)"
       :fetch-suggestions="(query, cb) => {queryNutrientUnits(query, data.nutrientId, cb)}"
       placeholder="单位关键词"
+      @input="handleRowUnitChanged(data)"
     />
     <el-select
-      clearable
       v-show="showRowNutrientSource"
       v-model="data.nutrientSource"
+      clearable
       :value-key="data.nutrientId"
       placeholder="请选择营养素来源"
     >
@@ -30,7 +30,7 @@ const SPECIAL_NUTRIENT_NAMES = ['维生素A', '维生素D', '维生素E', '烟
 export default {
   name: 'NutrientUnit',
   props: {
-    data: { type: Object, default: {} },
+    data: { type: Object, default: () => {} },
     edit: { type: Boolean, default: false }
   },
   data() {
@@ -39,12 +39,19 @@ export default {
       showRowNutrientSource: false
     }
   },
+  watch: {
+    edit(value) {
+      if (value) {
+        this.handleRowUnitChanged(this.data)
+      }
+    }
+  },
   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 (this.nutrientSources.length > 0) {
             if (!data.nutrientSource) {
               this.$set(data, 'nutrientSource', this.nutrientSources[0])
             }
@@ -60,7 +67,7 @@ export default {
       }
     },
     queryNutrientUnits(query, nutrientId, cb) {
-      let units = []
+      const units = []
       if (nutrientId) {
         getNutrientUnits(nutrientId, { query }).then(res => {
           res.data.forEach(item => units.push({ value: item }))
@@ -68,17 +75,8 @@ export default {
         })
       }
     }
-  },
-  watch: {
-    edit(value) {
-      if (value) {
-        this.handleRowUnitChanged(this.data)
-      }
-    }
   }
 }
 </script>
-
 <style scoped>
-
 </style>

+ 22 - 22
src/views/food/index.vue

@@ -1,5 +1,5 @@
 <template>
-  <div class="app-container" v-loading="uploadLoading">
+  <div v-loading="uploadLoading" class="app-container">
     <div class="filter-container">
       <el-row style="margin-bottom: 5px">
         <el-input
@@ -9,10 +9,10 @@
           class="filter-item"
           @keyup.enter.native="fetchData()"
         />
-        <el-select v-model="selectType" v-if="isUsda" style="width: 160px;margin-left: 10px;" class="filter-item">
+        <el-select v-if="isUsda" v-model="selectType" style="width: 160px;margin-left: 10px;" class="filter-item">
           <el-option v-for="item in usdaTypes" :key="item.value" :label="item.label" :value="item.value" />
         </el-select>
-        <el-select v-model="selectType" v-if="foodSourceIsAll" clearable style="width: 160px;margin-left: 10px;" class="filter-item">
+        <el-select v-if="foodSourceIsAll" v-model="selectType" clearable style="width: 160px;margin-left: 10px;" class="filter-item">
           <el-option v-for="item in allTypes" :key="item.value" :label="item.label" :value="item.value" />
         </el-select>
         <el-button class="filter-item" style="margin-left: 10px;" type="primary" icon="el-icon-search" @click="fetchData">
@@ -120,10 +120,10 @@
         </template>
       </el-table-column>
       <el-table-column label="操作" align="center" class-name="small-padding" fixed="right" width="90">
-        <template slot-scope="{row,$index}">
+        <template slot-scope="{row}">
           <el-dropdown @command="handleCommand">
-            <el-button size="small" @click.stop="{}" type="primary">
-              操作<i class="el-icon-arrow-down el-icon--right"></i>
+            <el-button size="small" type="primary" @click.stop="{}">
+              操作<i class="el-icon-arrow-down el-icon--right" />
             </el-button>
             <el-dropdown-menu slot="dropdown">
               <el-dropdown-item :command="{row: row, command: 'update'}">更新/查看</el-dropdown-item>
@@ -157,10 +157,10 @@
         :show-file-list="true"
         :on-change="fileChanged"
       >
-        <i class="el-icon-upload"></i>
+        <i class="el-icon-upload" />
         <div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
       </el-upload>
-      <div slot="footer" >
+      <div slot="footer">
         <el-button @click="dialogFormVisible = false">
           取消
         </el-button>
@@ -176,7 +176,7 @@
           <el-input v-model="params.foodName" placeholder="请输入新食物名称" />
         </el-form-item>
       </el-form>
-      <div slot="footer" >
+      <div slot="footer">
         <el-button @click="copyDialogVisible = false">
           取消
         </el-button>
@@ -189,14 +189,14 @@
     <el-dialog title="食物二维码" width="250" :visible.sync="foodQRDialogVisible">
       <vue-qr
         :text="foodQRParams.url"
-        :bgSrc="foodQRParams.bgImg"
-        :logoSrc="foodQRParams.logoImg"
+        :bg-src="foodQRParams.bgImg"
+        :logo-src="foodQRParams.logoImg"
         :size="200"
-        :correctLevel="3"
-        colorDark="#000"
-        colorLight="#fff"
-        :dotScale="1"
-      ></vue-qr>
+        :correct-level="3"
+        color-dark="#000"
+        color-light="#fff"
+        :dot-scale="1"
+      />
     </el-dialog>
   </div>
 </template>
@@ -245,8 +245,8 @@ export default {
       isUsda: false,
       foodSourceIsAll: false,
       usdaTypes: [{ 'label': 'Foundation', 'value': 'USDA_FOUNDATION' },
-                  { 'label': 'SR Legacy', 'value': 'USDA_SR_LEGACY' }, { 'label': 'Branded', 'value': 'USDA_BRANDED' },
-                  { 'label': 'FNDDS', 'value': 'USDA_FNDDS' }],
+        { 'label': 'SR Legacy', 'value': 'USDA_SR_LEGACY' }, { 'label': 'Branded', 'value': 'USDA_BRANDED' },
+        { 'label': 'FNDDS', 'value': 'USDA_FNDDS' }],
       allTypes: [{ 'label': '全部', 'value': 'ALL' }, { 'label': '录入', 'value': 'ENTRY' },
         { 'label': 'CFCT', 'value': 'CFCT' }, { 'label': 'Foundation', 'value': 'USDA_FOUNDATION' },
         { 'label': 'SR Legacy', 'value': 'USDA_SR_LEGACY' }, { 'label': 'Branded', 'value': 'USDA_BRANDED' },
@@ -275,7 +275,7 @@ export default {
       this.listLoading = true
       this.listQuery.foodSource = this.foodSource
       if (this.isUsda) {
-        if (!this.selectType || this.selectType === 'ALL'){
+        if (!this.selectType || this.selectType === 'ALL') {
           this.listQuery.foodSource = 'USDA'
         } else {
           this.listQuery.foodSource = this.selectType
@@ -325,7 +325,7 @@ export default {
       this.dialogFormVisible = true
     },
     importFoods() {
-      const reqConfig = { headers: { 'Authorization': getToken(), 'Content-Type':'multipart/form-data' },
+      const reqConfig = { headers: { 'Authorization': getToken(), 'Content-Type': 'multipart/form-data' },
         timeout: 1000 * 60 * 3 }
       const importUrl = process.env.VUE_APP_BASE_API + '/api/foods/import'
       this.uploadLoading = true
@@ -339,7 +339,7 @@ export default {
       })
     },
     fileChanged(file, fileList) {
-      let fromData = new FormData()
+      const fromData = new FormData()
       fromData.append('file', file.raw)
       this.uploadFile = fromData
     },
@@ -350,7 +350,7 @@ export default {
     copyFood() {
       copyFromSimilarFood(this.params).then(res => {
         this.$notify.success('提交成功')
-        this.$router.push({ path: `/food/edit/${res.data}`})
+        this.$router.push({ path: `/food/edit/${res.data}` })
       }).catch(res => {
         this.$message.error(res.data.message)
       })

+ 58 - 54
src/views/food/nutrient.vue

@@ -2,9 +2,9 @@
   <div class="app-container">
     <div class="filter-container" style="position: relative">
 
-      <floating-window :class="{'is_fixed': isFixed}" >
+      <floating-window :class="{'is_fixed': isFixed}">
         <el-dropdown @command="handleCommand">
-          <img width="50px" height="50px" src="@/assets/navigation.png" alt="导航.png" />
+          <img width="50px" height="50px" src="@/assets/navigation.png" alt="导航.png">
           <el-dropdown-menu slot="dropdown">
             <el-dropdown-item command="detail">食物更新</el-dropdown-item>
             <el-dropdown-item command="unit">单位管理</el-dropdown-item>
@@ -55,11 +55,11 @@
           @focus="getInputFocus"
         />
         <el-autocomplete
-          class="inline-input"
           v-model="params.unit"
+          class="inline-input"
           :fetch-suggestions="(query, cb) => {queryNutrientUnits(query, params.nutrientId, cb)}"
-          @input="handleUnitChanged"
           placeholder="单位关键词"
+          @input="handleUnitChanged"
         />
         <div v-show="showNutrientSource" style="display: inline-block">
           <el-select
@@ -88,8 +88,8 @@
             @focus="getInputFocus"
           />
           <el-autocomplete
-            class="inline-input"
             v-model="params.nvSpecUnit"
+            class="inline-input"
             :fetch-suggestions="queryUnits"
             placeholder="单位关键词"
           />
@@ -105,7 +105,8 @@
           style="margin-left: 10px;"
           type="primary"
           :disabled="!canEdit"
-          @click="addNutrient">
+          @click="addNutrient"
+        >
           添加
         </el-button>
         <el-button
@@ -113,25 +114,28 @@
           style="margin-left: 10px;"
           type="success"
           :disabled="!canEdit"
-          @click="handleImport">
+          @click="handleImport"
+        >
           导入营养素
         </el-button>
         <el-button
+          v-if="!editAll"
           class="filter-item"
           style="margin-left: 10px;"
           type="success"
           :disabled="!canEdit"
-          v-if="!editAll"
-          @click="handleMultiEdit">
+          @click="handleMultiEdit"
+        >
           批量编辑
         </el-button>
         <el-button
+          v-else
           class="filter-item"
           style="margin-left: 10px;"
           type="primary"
           :disabled="!canEdit"
-          v-else
-          @click="submitMulti">
+          @click="submitMulti"
+        >
           批量提交
         </el-button>
       </el-row>
@@ -166,13 +170,13 @@
       <el-table-column label="NRV%" align="center" width="80">
         <template slot-scope="{row}">
           <template v-if="row.edit || editAll">
-            <el-input v-show="!isPercentByVolumeUnit(row)" v-model="row.nrvPercent"/>
+            <el-input v-show="!isPercentByVolumeUnit(row)" v-model="row.nrvPercent" />
           </template>
           <span v-else>{{ row.nrvPercent }}</span>
         </template>
       </el-table-column>
       <el-table-column label="Nv_Spec" align="center" width="80">
-        <template slot-scope="{row}" v-if="!isPercentByVolumeUnit(row)">
+        <template v-if="!isPercentByVolumeUnit(row)" slot-scope="{row}">
           <template v-if="row.edit || editAll">
             <el-input v-model="row.nvSpec" class="filter-item" @focus="getInputFocus" />
           </template>
@@ -180,7 +184,7 @@
         </template>
       </el-table-column>
       <el-table-column label="计量单位" align="center" width="150">
-        <template slot-scope="{row}" v-if="!isPercentByVolumeUnit(row)">
+        <template v-if="!isPercentByVolumeUnit(row)" slot-scope="{row}">
           <template v-if="row.edit || editAll">
             <el-autocomplete v-model="row.nvSpecUnit" :fetch-suggestions="queryUnits" placeholder="单位关键词" />
           </template>
@@ -202,7 +206,7 @@
       <el-table-column label="信息来源备注" align="center" width="200">
         <template slot-scope="{row}">
           <template v-if="row.edit || editAll">
-            <el-input type="text" :rows="2" v-model="row.sourceNote" @focus="getInputFocus" />
+            <el-input v-model="row.sourceNote" type="text" :rows="2" @focus="getInputFocus" />
           </template>
           <span v-else>{{ row.sourceNote }}</span>
         </template>
@@ -237,10 +241,10 @@
       </el-table-column>
     </el-table>
 
-    <el-dialog title="导入营养素" :visible.sync="dialogFormVisible" v-loading="importLoading">
+    <el-dialog v-loading="importLoading" title="导入营养素" :visible.sync="dialogFormVisible">
       <el-form ref="dialogForm" label-position="left" style="width: 80%; margin-left:50px;">
-        <el-radio :label="0" v-model="importType" @change="handleImportTypeChange" >从模板导入</el-radio>
-        <el-radio :label="1" v-model="importType" @change="handleImportTypeChange" style="margin-bottom: 10px">从食物导入</el-radio>
+        <el-radio v-model="importType" :label="0" @change="handleImportTypeChange">从模板导入</el-radio>
+        <el-radio v-model="importType" :label="1" style="margin-bottom: 10px" @change="handleImportTypeChange">从食物导入</el-radio>
         <el-form-item prop="importId">
           <el-select
             v-model="importId"
@@ -287,23 +291,11 @@ const SPECIAL_NUTRIENT_NAMES = ['维生素A', '维生素D', '维生素E', '烟
 export default {
   name: 'AddNutrient',
   components: { FloatingWindow, NutrientQuantity, NutrientUnit },
-  mounted() {
-    window.addEventListener('scroll', this.initHeight);
-  },
-  //回调中移除监听
-  destroyed() {
-    window.removeEventListener('scroll', this.handleScroll)
-  },
-  created() {
-    this.foodId = this.$route.params && this.$route.params.id
-    this.fetchData()
-    this.queryNutrients()
-  },
   filters: {
     nutrientQuantityFilter(row) {
       if (row.stdError) {
         return `${row.quantity} ± ${row.stdError}`
-      }else if (row.quantityMin && row.quantityMax) {
+      } else if (row.quantityMin && row.quantityMax) {
         return `${row.quantityMin} ~ ${row.quantityMax}`
       } else if (row.quantityMin) {
         return `≥${row.quantityMin}`
@@ -325,7 +317,7 @@ export default {
       params: { source: '营养标签', radio: 0, nvSpec: 100, nvSpecUnit: '克' },
       loading: false,
       unitLoading: false,
-      sources: [{ value: "营养标签" }, { value: "食品官方资料" }, { value: "计算值" }],
+      sources: [{ value: '营养标签' }, { value: '食品官方资料' }, { value: '计算值' }],
       dialogFormVisible: false,
       importType: 0,
       importId: '',
@@ -341,6 +333,18 @@ export default {
       editAll: false
     }
   },
+  mounted() {
+    window.addEventListener('scroll', this.initHeight)
+  },
+  // 回调中移除监听
+  destroyed() {
+    window.removeEventListener('scroll', this.handleScroll)
+  },
+  created() {
+    this.foodId = this.$route.params && this.$route.params.id
+    this.fetchData()
+    this.queryNutrients()
+  },
   methods: {
     fetchData() {
       this.listLoading = true
@@ -352,8 +356,8 @@ export default {
       getNutrientList(this.foodId).then(res => {
         this.list = res.data
         if (this.list.length > 0) {
-          this.$set(this.params, "nvSpec", this.list[0].nvSpec)
-          this.$set(this.params, "nvSpecUnit", this.list[0].nvSpecUnit)
+          this.$set(this.params, 'nvSpec', this.list[0].nvSpec)
+          this.$set(this.params, 'nvSpecUnit', this.list[0].nvSpecUnit)
         } else {
           this.$set(this.params, 'nvSpec', 100)
           this.$set(this.params, 'nvSpecUnit', '克')
@@ -419,7 +423,7 @@ export default {
       })
     },
     queryNutrientUnits(query, nutrientId, cb) {
-      let units = []
+      const units = []
       if (nutrientId) {
         getNutrientUnits(nutrientId, { query }).then(res => {
           res.data.forEach(item => units.push({ value: item }))
@@ -428,7 +432,7 @@ export default {
       }
     },
     queryUnits(query, cb) {
-      let units = []
+      const units = []
       getUnits({ query }).then(res => {
         res.data.list.forEach(item => units.push({ value: item.name }))
         cb(units)
@@ -443,14 +447,14 @@ export default {
       })
     },
     querySources(query, cb) {
-      let sources = this.sources
-      let results = query ? sources.filter(this.sourcesFilter(query)) : sources;
+      const sources = this.sources
+      const results = query ? sources.filter(this.sourcesFilter(query)) : sources
       cb(results)
     },
     sourcesFilter(query) {
       return (restaurant) => {
-        return (restaurant.value.toLowerCase().indexOf(query.toLowerCase()) === 0);
-      };
+        return (restaurant.value.toLowerCase().indexOf(query.toLowerCase()) === 0)
+      }
     },
     handleEdit(row) {
       if (!this.canEdit) {
@@ -473,7 +477,7 @@ export default {
       this.$set(row, 'quantity', '')
     },
     nutrientChanged(value) {
-      for (let nutrient of this.nutrients) {
+      for (const nutrient of this.nutrients) {
         if (nutrient.id === value) {
           this.$set(this.params, 'unit', nutrient.baseUnit)
           if (nutrient.nrvUnit) {
@@ -486,7 +490,7 @@ export default {
       }
     },
     getInputFocus(event) {
-      event.currentTarget.select();
+      event.currentTarget.select()
     },
     handleImport() {
       this.query = ''
@@ -510,10 +514,10 @@ export default {
       this.importItems = []
       this.queryImportItems()
     },
-    queryImportItems(query=''){
+    queryImportItems(query = '') {
       this.importType === 0 ? this.queryTemplates(query) : this.queryFoods(query)
     },
-    queryTemplates(query='') {
+    queryTemplates(query = '') {
       this.importLoading = true
       getNutrientTemplates({ query }).then(res => {
         this.importItems = res.data.list
@@ -526,7 +530,7 @@ export default {
         this.importLoading = false
       })
     },
-    queryFoods(query='') {
+    queryFoods(query = '') {
       this.importLoading = true
       getFoodList({ query: query, orderBy: 0, pageNum: 1, pageSize: 20 }).then(res => {
         this.importItems = res.data.list
@@ -538,12 +542,12 @@ export default {
     },
     submitImport() {
       this.importLoading = true
-      const resPromise = this.importType === 0 ?
-        importNutrientsFromTemplate(this.foodId, { templateId: this.importId }) :
-        importNutrientFromSimilarFood(this.foodId, { foodId: this.importId })
+      const resPromise = this.importType === 0
+        ? importNutrientsFromTemplate(this.foodId, { templateId: this.importId })
+        : importNutrientFromSimilarFood(this.foodId, { foodId: this.importId })
       resPromise.then(res => {
         this.fetchData()
-        this.$notify.success("提交成功")
+        this.$notify.success('提交成功')
         this.dialogFormVisible = false
         this.importLoading = false
       }).catch(res => {
@@ -555,8 +559,8 @@ export default {
     initHeight() {
       // 设置或获取位于对象最顶端和窗口中可见内容的最顶端之间的距离 (被卷曲的高度)
       const scrollTop = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop
-      //如果被卷曲的高度大于吸顶元素到顶端位置 的距离
-      this.isFixed = scrollTop > this.offsetTop;
+      // 如果被卷曲的高度大于吸顶元素到顶端位置 的距离
+      this.isFixed = scrollTop > this.offsetTop
     },
     handleCommand(value) {
       let path = ''
@@ -594,8 +598,8 @@ export default {
       if (this.isSpecialNutrient(this.params.nutrientId)) {
         getNutrientSources(this.params.nutrientId, { unit: this.params.unit }).then(res => {
           this.nutrientSources = res.data
-          if (this.nutrientSources.length > 0){
-            this.$set(this.params, "nutrientSource", this.nutrientSources[0])
+          if (this.nutrientSources.length > 0) {
+            this.$set(this.params, 'nutrientSource', this.nutrientSources[0])
             this.showNutrientSource = true
           } else {
             this.showNutrientSource = false
@@ -611,7 +615,7 @@ export default {
       if (SPECIAL_NUTRIENT_NAMES.indexOf(row.nutrientName) > -1) {
         getNutrientSources(row.nutrientId, { unit: row.unit }).then(res => {
           this.nutrientSources = res.data
-          if (this.nutrientSources.length > 0){
+          if (this.nutrientSources.length > 0) {
             if (!row.nutrientSource) {
               this.$set(row, 'nutrientSource', this.nutrientSources[0])
             }

+ 9 - 9
src/views/food/unit.vue

@@ -2,9 +2,9 @@
   <div class="app-container">
     <div class="filter-container" style="position: relative">
 
-      <floating-window :class="{'is_fixed': isFixed}" >
+      <floating-window :class="{'is_fixed': isFixed}">
         <el-dropdown @command="handleCommand">
-          <img width="50px" height="50px" src="@/assets/navigation.png" alt="导航.png" />
+          <img width="50px" height="50px" src="@/assets/navigation.png" alt="导航.png">
           <el-dropdown-menu slot="dropdown">
             <el-dropdown-item command="detail">食物更新</el-dropdown-item>
             <el-dropdown-item command="nutrient">营养素关联</el-dropdown-item>
@@ -17,15 +17,15 @@
       From单位:
       <el-autocomplete
         ref="fromUnitSelect"
-        class="inline-input"
         v-model="params.fromUnit"
+        class="inline-input"
         :fetch-suggestions="queryUnits"
         placeholder="单位关键词"
       />
       To单位:
       <el-autocomplete
-        class="inline-input"
         v-model="params.toUnit"
+        class="inline-input"
         :fetch-suggestions="queryUnits"
         placeholder="单位关键词"
       />
@@ -118,9 +118,9 @@ export default {
     }
   },
   mounted() {
-    window.addEventListener('scroll', this.initHeight);
+    window.addEventListener('scroll', this.initHeight)
   },
-  //回调中移除监听
+  // 回调中移除监听
   destroyed() {
     window.removeEventListener('scroll', this.handleScroll)
   },
@@ -176,7 +176,7 @@ export default {
       })
     },
     queryUnits(query, cb) {
-      let units = []
+      const units = []
       getList({ query }).then(res => {
         res.data.list.forEach(item => units.push({ value: item.name }))
         cb(units)
@@ -185,8 +185,8 @@ export default {
     initHeight() {
       // 设置或获取位于对象最顶端和窗口中可见内容的最顶端之间的距离 (被卷曲的高度)
       const scrollTop = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop
-      //如果被卷曲的高度大于吸顶元素到顶端位置 的距离
-      this.isFixed = scrollTop > this.offsetTop;
+      // 如果被卷曲的高度大于吸顶元素到顶端位置 的距离
+      this.isFixed = scrollTop > this.offsetTop
     },
     handleCommand(value) {
       let path = ''

+ 9 - 9
src/views/foodCategory/index.vue

@@ -9,14 +9,14 @@
         :highlight-current="true"
         :default-expanded-keys="['root']"
       >
-        <span class="custom-tree-node" slot-scope="{ node, data }">
-        <span>{{ node.label }}</span>
-        <span>
-          <el-button v-if="data.id !== 'root'" type="text" size="mini" @click="appendOrEdit(data, 'edit')">更新</el-button>
-          <el-button type="text" size="mini" @click="appendOrEdit(data, 'create')">追加</el-button>
-          <el-button v-if="data.id !== 'root'" type="text" size="mini" @click="remove(data)">删除</el-button>
+        <span slot-scope="{ node, data }" class="custom-tree-node">
+          <span>{{ node.label }}</span>
+          <span>
+            <el-button v-if="data.id !== 'root'" type="text" size="mini" @click="appendOrEdit(data, 'edit')">更新</el-button>
+            <el-button type="text" size="mini" @click="appendOrEdit(data, 'create')">追加</el-button>
+            <el-button v-if="data.id !== 'root'" type="text" size="mini" @click="remove(data)">删除</el-button>
+          </span>
         </span>
-      </span>
       </el-tree>
     </div>
 
@@ -89,8 +89,8 @@ export default {
       if (this.params.parentId === 'root') {
         this.params.parentId = ''
       }
-      const resultPromise = this.dialogStatus === 'create' ? createFoodCategory(this.params) :
-        updateFoodCategory(this.params.id, this.params)
+      const resultPromise = this.dialogStatus === 'create' ? createFoodCategory(this.params)
+        : updateFoodCategory(this.params.id, this.params)
       resultPromise.then(res => {
         this.fetchData()
         this.$notify.success('提交成功')

+ 20 - 20
src/views/foodModifier/components/ModifierDetail.vue

@@ -1,9 +1,9 @@
 <template>
   <div class="createPost-container" style="position: relative">
 
-    <floating-window :class="{'is_fixed': isFixed}" >
+    <floating-window :class="{'is_fixed': isFixed}">
       <el-dropdown @command="handleCommand">
-        <img width="50px" height="50px" src="@/assets/navigation.png" alt="导航.png" />
+        <img width="50px" height="50px" src="@/assets/navigation.png" alt="导航.png">
         <el-dropdown-menu slot="dropdown">
           <el-dropdown-item command="detail">食物更新</el-dropdown-item>
           <el-dropdown-item command="nutrient">营养素关联</el-dropdown-item>
@@ -16,14 +16,14 @@
 
     <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-checkbox v-model="isDefaultModifier" :disabled="isEdit" style="margin: 0 0 10px 100px" @change="checkboxChange">默认规格</el-checkbox>
         <el-form-item label="包装名称:" style="margin-bottom: 40px;width: 60%" prop="name">
-          <el-input :disabled="isDefaultModifier" v-model="postForm.name" placeholder="请输入名称" @blur="updateUnit" />
+          <el-input v-model="postForm.name" :disabled="isDefaultModifier" 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"
+            style="width: 100%"
             :fetch-suggestions="queryUnits"
             placeholder="单位关键词"
           />
@@ -35,10 +35,10 @@
             </el-form-item>
           </el-col>
           <el-col :span="12">
-            <el-form-item v-show="!isDefaultModifier"  label="单位名称:" style="margin-bottom: 40px" prop="unit">
+            <el-form-item v-show="!isDefaultModifier" label="单位名称:" style="margin-bottom: 40px" prop="unit">
               <el-autocomplete
-                style="width: 100%"
                 v-model="postForm.unit"
+                style="width: 100%"
                 :fetch-suggestions="queryUnits"
                 placeholder="单位关键词"
               />
@@ -65,8 +65,8 @@
           </el-col>
         </el-row>
         <el-form-item label="状态:" prop="status" style="margin-bottom: 40px;width: 60%">
-          <el-radio :label="1" v-model="postForm.status">上架</el-radio>
-          <el-radio :label="0" v-model="postForm.status">下架</el-radio>
+          <el-radio v-model="postForm.status" :label="1">上架</el-radio>
+          <el-radio v-model="postForm.status" :label="0">下架</el-radio>
         </el-form-item>
         <el-form-item label="CF" style="margin-bottom: 40px;width: 60%" prop="cf">
           <el-input v-model="postForm.cf" :disabled="true" />
@@ -80,7 +80,7 @@
         <el-form-item label="卡尺每格刻度:" prop="stepScale" style="margin-bottom: 40px;width: 60%">
           <el-input v-model="postForm.stepScale" placeholder="请输入卡尺每格刻度" />
         </el-form-item>
-        <el-form-item v-show="!isDefaultModifier"  label="图片列表:" prop="images" style="margin-bottom: 30px;width: 60%">
+        <el-form-item v-show="!isDefaultModifier" label="图片列表:" prop="images" style="margin-bottom: 30px;width: 60%">
           <dropzone
             id="modifierImages"
             :default-img="postForm.images"
@@ -104,14 +104,14 @@ import { getList as getUnits } from '@/api/unit'
 import store from '@/store'
 
 export default {
-  name: "ModifierDetail",
+  name: 'ModifierDetail',
+  components: { Dropzone, FloatingWindow },
   props: {
     isEdit: {
       type: Boolean,
       default: false
     }
   },
-  components: { Dropzone, FloatingWindow },
   data() {
     return {
       defaultModifierName: '-',
@@ -126,9 +126,9 @@ export default {
     }
   },
   mounted() {
-    window.addEventListener('scroll', this.initHeight);
+    window.addEventListener('scroll', this.initHeight)
   },
-  //回调中移除监听
+  // 回调中移除监听
   destroyed() {
     window.removeEventListener('scroll', this.handleScroll)
   },
@@ -149,7 +149,7 @@ export default {
       })
     },
     removeFile(file) {
-      let imgs = this.postForm.images
+      const imgs = this.postForm.images
       let imgIndex = -1
       for (let i = 0; i < imgs.length; i++) {
         if (imgs[i] === file.url) {
@@ -179,8 +179,8 @@ export default {
       })
     },
     createOrUpdateData() {
-      const resultPromise = this.isEdit ? updateFoodModifier(this.foodId, this.postForm.id, this.postForm) :
-        addFoodModifier(this.foodId, this.postForm)
+      const resultPromise = this.isEdit ? updateFoodModifier(this.foodId, this.postForm.id, this.postForm)
+        : addFoodModifier(this.foodId, this.postForm)
       resultPromise.then(res => {
         this.$notify.success('创建成功')
         this.loading = false
@@ -191,7 +191,7 @@ export default {
       })
     },
     queryUnits(query, cb) {
-      let units = []
+      const units = []
       getUnits({ query }).then(res => {
         res.data.list.forEach(item => units.push({ value: item.name }))
         cb(units)
@@ -218,8 +218,8 @@ export default {
     initHeight() {
       // 设置或获取位于对象最顶端和窗口中可见内容的最顶端之间的距离 (被卷曲的高度)
       const scrollTop = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop
-      //如果被卷曲的高度大于吸顶元素到顶端位置 的距离
-      this.isFixed = scrollTop > this.offsetTop;
+      // 如果被卷曲的高度大于吸顶元素到顶端位置 的距离
+      this.isFixed = scrollTop > this.offsetTop
     },
     handleCommand(value) {
       let path = ''

+ 38 - 26
src/views/foodModifier/components/ModifierImport.vue

@@ -1,7 +1,12 @@
 <template>
   <div style="overflow: auto">
-    <el-form ref="dialogForm" label-position="left" label-width="60px" style="width: 80%; margin-left:50px;">
-      <el-form-item label="食物:" prop="importFoodId" >
+    <el-form
+      ref="dialogForm"
+      label-position="left"
+      label-width="60px"
+      style="width: 80%; margin-left:50px;"
+    >
+      <el-form-item label="食物:" prop="importFoodId">
         <el-select
           v-model="importFoodId"
           class="filter-item"
@@ -13,17 +18,18 @@
           :remote-method="queryFoods"
           style="width: 100%"
         >
-          <el-option v-for="item in foods" :key="`food${item.id}`" :label="item.name" :value="item.id" />
+          <el-option
+            v-for="item in foods"
+            :key="`food${item.id}`"
+            :label="item.name"
+            :value="item.id"
+          />
         </el-select>
       </el-form-item>
     </el-form>
     <div slot="footer" class="dialog-footer" style="float: right">
-      <el-button @click="closeDialog">
-        取消
-      </el-button>
-      <el-button type="primary" @click="submit">
-        提交
-      </el-button>
+      <el-button @click="closeDialog">取消</el-button>
+      <el-button type="primary" @click="submit">提交</el-button>
     </div>
   </div>
 </template>
@@ -34,7 +40,10 @@ import { getList, importModifiersFromSimilarFood } from '@/api/food'
 export default {
   name: 'ModifierImport',
   props: {
-    foodId: { type: String }
+    foodId: {
+      type: String,
+      default: ''
+    }
   },
   data() {
     return {
@@ -44,33 +53,36 @@ export default {
     }
   },
   methods: {
-    queryFoods(query='') {
+    queryFoods(query = '') {
       this.foodLoading = true
-      getList({ query: query, orderBy: 0, pageNum: 1, pageSize: 20 }).then(res => {
-        this.foods = res.data.list
-        this.foodLoading = false
-      }).catch(() => {
-        this.foods = []
-        this.foodLoading = false
-      })
+      getList({ query: query, orderBy: 0, pageNum: 1, pageSize: 20 })
+        .then(res => {
+          this.foods = res.data.list
+          this.foodLoading = false
+        })
+        .catch(() => {
+          this.foods = []
+          this.foodLoading = false
+        })
     },
     closeDialog() {
       this.foods = []
       this.importFoodId = ''
-      this.$emit("closeDialog")
+      this.$emit('closeDialog')
     },
     submit() {
-      importModifiersFromSimilarFood(this.foodId, { foodId: this.importFoodId }).then(res => {
-        this.$notify.success('提交成功')
-        this.closeDialog()
-      }).catch(res => {
-        this.$message.error(res.data.message)
-      })
+      importModifiersFromSimilarFood(this.foodId, { foodId: this.importFoodId })
+        .then(res => {
+          this.$notify.success('提交成功')
+          this.closeDialog()
+        })
+        .catch(res => {
+          this.$message.error(res.data.message)
+        })
     }
   }
 }
 </script>
 
 <style scoped>
-
 </style>

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

@@ -24,9 +24,9 @@
       </el-button>
     </div>
 
-    <floating-window :able-hide="false" :class="{'is_fixed': isFixed}" >
+    <floating-window :able-hide="false" :class="{'is_fixed': isFixed}">
       <el-dropdown @command="handleCommand">
-        <img width="50px" height="50px" src="@/assets/navigation.png" alt="导航.png" />
+        <img width="50px" height="50px" src="@/assets/navigation.png" alt="导航.png">
         <el-dropdown-menu slot="dropdown">
           <el-dropdown-item command="detail">食物更新</el-dropdown-item>
           <el-dropdown-item command="nutrient">营养素关联</el-dropdown-item>
@@ -118,13 +118,13 @@
           <el-button type="primary" size="mini" :disabled="!canEdit" @click.stop="handleUpdate(row)">
             更新/查看
           </el-button>
-          <el-button type="primary" size="mini" :disabled="!canEdit"  @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" :disabled="!canEdit"  @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" :disabled="!canEdit"  @click.stop="handleDelete(row)">
+          <el-button size="mini" type="danger" :disabled="!canEdit" @click.stop="handleDelete(row)">
             删除
           </el-button>
         </template>
@@ -154,7 +154,7 @@ export default {
   name: 'FoodModifierIndex',
   components: { FloatingWindow, ModifierImport },
   filters: {
-    statusFilter(value){
+    statusFilter(value) {
       return STATUS_MAP[value]
     }
   },
@@ -173,9 +173,9 @@ export default {
     }
   },
   mounted() {
-    window.addEventListener('scroll', this.initHeight);
+    window.addEventListener('scroll', this.initHeight)
   },
-  //回调中移除监听
+  // 回调中移除监听
   destroyed() {
     window.removeEventListener('scroll', this.handleScroll)
   },
@@ -237,8 +237,8 @@ export default {
     initHeight() {
       // 设置或获取位于对象最顶端和窗口中可见内容的最顶端之间的距离 (被卷曲的高度)
       const scrollTop = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop
-      //如果被卷曲的高度大于吸顶元素到顶端位置 的距离
-      this.isFixed = scrollTop > this.offsetTop;
+      // 如果被卷曲的高度大于吸顶元素到顶端位置 的距离
+      this.isFixed = scrollTop > this.offsetTop
     },
     handleCommand(value) {
       let path = ''

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

@@ -80,8 +80,8 @@
       <el-table-column label="操作" align="center" fixed="right" width="90">
         <template slot-scope="{row}">
           <el-dropdown @command="handleCommand">
-            <el-button size="small" @click.stop="{}" type="primary">
-              操作<i class="el-icon-arrow-down el-icon--right"></i>
+            <el-button size="small" type="primary" @click.stop="{}">
+              操作<i class="el-icon-arrow-down el-icon--right" />
             </el-button>
             <el-dropdown-menu slot="dropdown">
               <el-dropdown-item :command="{row: row, command: 'update'}">更新</el-dropdown-item>
@@ -120,8 +120,8 @@
         </el-form-item>
         <el-form-item label="基础单位" prop="baseUnit">
           <el-autocomplete
-            class="inline-input"
             v-model="params.baseUnit"
+            class="inline-input"
             :fetch-suggestions="queryUnits"
             placeholder="单位关键词"
           />
@@ -237,7 +237,7 @@ export default {
       })
     },
     queryUnits(query, cb) {
-      let units = []
+      const units = []
       getUnits({ query }).then(res => {
         res.data.list.forEach(item => units.push({ value: item.name }))
         cb(units)

+ 25 - 26
src/views/nutrientTemplate/detail.vue

@@ -20,11 +20,11 @@
         </el-select>
         营养素计量单位:
         <el-autocomplete
-          class="inline-input"
           v-model="params.unit"
+          class="inline-input"
           :fetch-suggestions="(query, cb) => {queryNutrientUnits(query, params.nutrientId, cb)}"
-          @input="handleUnitChanged"
           placeholder="单位关键词"
+          @input="handleUnitChanged"
         />
         <div v-show="showNutrientSource" style="display: inline-block">
           营养素来源:
@@ -46,8 +46,8 @@
           />
           Nv_Spec计量单位:
           <el-autocomplete
-            class="inline-input"
             v-model="params.nvSpecUnit"
+            class="inline-input"
             :fetch-suggestions="queryUnits"
             placeholder="单位关键词"
           />
@@ -69,7 +69,6 @@
         </el-button>
       </el-row>
 
-
       <el-table
         ref="detailTable"
         :key="tableKey"
@@ -90,16 +89,16 @@
           <template slot-scope="{row}">
             <template v-if="row.edit">
               <el-autocomplete
-                class="inline-input"
                 v-model="row.unit"
-                @input="handleRowUnitChanged(row)"
+                class="inline-input"
                 :fetch-suggestions="(query, cb) => {queryNutrientUnits(query, row.nutrientId, cb)}"
                 placeholder="单位关键词"
+                @input="handleRowUnitChanged(row)"
               />
               <el-select
-                clearable
                 v-show="showRowNutrientSource"
                 v-model="row.nutrientSource"
+                clearable
                 placeholder="请选择营养素来源"
               >
                 <el-option v-for="item in nutrientSources" :key="item" :label="item" :value="item" />
@@ -109,7 +108,7 @@
           </template>
         </el-table-column>
         <el-table-column label="Nv_Spec" align="center" width="100px">
-          <template slot-scope="{row}" v-if="!isPercentByVolumeUnit(row)">
+          <template v-if="!isPercentByVolumeUnit(row)" slot-scope="{row}">
             <template v-if="row.edit">
               <el-input
                 v-model="row.nvSpec"
@@ -120,11 +119,11 @@
           </template>
         </el-table-column>
         <el-table-column label="Nv_Spec单位" align="center" width="150px">
-          <template slot-scope="{row}" v-if="!isPercentByVolumeUnit(row)">
+          <template v-if="!isPercentByVolumeUnit(row)" slot-scope="{row}">
             <template v-if="row.edit">
               <el-autocomplete
-                class="inline-input"
                 v-model="row.nvSpecUnit"
+                class="inline-input"
                 :fetch-suggestions="queryUnits"
                 placeholder="单位关键词"
               />
@@ -147,7 +146,7 @@
         <el-table-column label="信息来源备注" align="center" width="200">
           <template slot-scope="{row}">
             <template v-if="row.edit">
-              <el-input type="text" :rows="2" v-model="row.sourceNote" />
+              <el-input v-model="row.sourceNote" type="text" :rows="2" />
             </template>
             <span v-else>{{ row.sourceNote }}</span>
           </template>
@@ -208,7 +207,7 @@ export default {
       params: { source: '营养标签', nutrientSource: null },
       loading: false,
       unitLoading: false,
-      sources: [{ value: "营养标签" }, { value: "食品官方资料" }, { value: "计算值" }],
+      sources: [{ value: '营养标签' }, { value: '食品官方资料' }, { value: '计算值' }],
       sortable: null,
       showNutrientSource: false,
       showRowNutrientSource: false,
@@ -279,7 +278,7 @@ export default {
       })
     },
     queryUnits(query, cb) {
-      let units = []
+      const units = []
       getUnits({ query }).then(res => {
         res.data.list.forEach(item => units.push({ value: item.name }))
         cb(units)
@@ -291,8 +290,8 @@ export default {
         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)
+          this.$set(this.params, 'nvSpec', this.list[0].nvSpec)
+          this.$set(this.params, 'nvSpecUnit', this.list[0].nvSpecUnit)
         } else {
           this.$set(this.params, 'nvSpec', null)
           this.$set(this.params, 'nvSpecUnit', null)
@@ -313,17 +312,17 @@ export default {
       })
     },
     querySources(query, cb) {
-      let sources = this.sources
-      let results = query ? sources.filter(this.sourcesFilter(query)) : sources;
+      const sources = this.sources
+      const results = query ? sources.filter(this.sourcesFilter(query)) : sources
       cb(results)
     },
     sourcesFilter(query) {
       return (restaurant) => {
-        return (restaurant.value.toLowerCase().indexOf(query.toLowerCase()) === 0);
-      };
+        return (restaurant.value.toLowerCase().indexOf(query.toLowerCase()) === 0)
+      }
     },
     queryNutrientUnits(query, nutrientId, cb) {
-      let units = []
+      const units = []
       if (nutrientId) {
         getNutrientUnits(nutrientId, { query }).then(res => {
           res.data.forEach(item => units.push({ value: item }))
@@ -341,11 +340,11 @@ export default {
           dataTransfer.setData('Text', '')
         },
         onEnd: evt => {
-          let sortOrders = []
-          let ids = []
+          const sortOrders = []
+          const ids = []
           this.list.forEach(item => sortOrders.push(item.sortOrder))
 
-          let list = this.list.slice()
+          const list = this.list.slice()
           const targetRow = list.splice(evt.oldIndex, 1)[0]
           list.splice(evt.newIndex, 0, targetRow)
 
@@ -378,7 +377,7 @@ export default {
       if (this.isSpecialNutrient(this.params.nutrientId)) {
         getNutrientSources(this.params.nutrientId, { unit: this.params.unit }).then(res => {
           this.nutrientSources = res.data
-          if (this.nutrientSources.length > 0){
+          if (this.nutrientSources.length > 0) {
             this.params.nutrientSource = this.nutrientSources[0]
             this.showNutrientSource = true
           } else {
@@ -395,7 +394,7 @@ export default {
       if (SPECIAL_NUTRIENT_NAMES.indexOf(row.nutrientName) > -1) {
         getNutrientSources(row.nutrientId, { unit: row.unit }).then(res => {
           this.nutrientSources = res.data
-          if (this.nutrientSources.length > 0){
+          if (this.nutrientSources.length > 0) {
             if (!row.nutrientSource) {
               row.nutrientSource = this.nutrientSources[0]
             }
@@ -418,7 +417,7 @@ export default {
       return row && row.unit === '%Vol'
     },
     nutrientChanged(value) {
-      for (let nutrient of this.nutrients) {
+      for (const nutrient of this.nutrients) {
         if (nutrient.id === value) {
           this.$set(this.params, 'unit', nutrient.baseUnit)
           if (nutrient.nrvUnit) {

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

@@ -60,8 +60,8 @@
       <el-table-column label="操作" align="center" fixed="right" width="90">
         <template slot-scope="{row}">
           <el-dropdown @command="handleCommand">
-            <el-button size="small" @click.stop="{}" type="primary">
-              操作<i class="el-icon-arrow-down el-icon--right"></i>
+            <el-button size="small" type="primary" @click.stop="{}">
+              操作<i class="el-icon-arrow-down el-icon--right" />
             </el-button>
             <el-dropdown-menu slot="dropdown">
               <el-dropdown-item :command="{row: row, command: 'update'}">更新/查看</el-dropdown-item>

+ 10 - 9
src/views/recipe/food.vue

@@ -3,6 +3,7 @@
     <div class="filter-container">
       食物:
       <el-select
+        ref="foodSelect"
         v-model="params.foodId"
         filterable
         remote
@@ -12,14 +13,13 @@
         :remote-method="queryFoods"
         :loading="loading"
         @change="changeUnits"
-        ref="foodSelect"
       >
         <el-option
           v-for="item in foods"
           :key="item.id"
           :label="item.name"
-          :value="item.id">
-        </el-option>
+          :value="item.id"
+        />
       </el-select>
       数量:
       <el-input
@@ -46,7 +46,8 @@
         class="filter-item"
         style="margin-left: 10px;"
         type="primary"
-        @click="addFood">
+        @click="addFood"
+      >
         添加
       </el-button>
     </div>
@@ -69,7 +70,7 @@
       <el-table-column label="用量" align="center">
         <template slot-scope="{row}">
           <template v-if="row.edit">
-            <el-input v-model="row.quantity" style="width: 80px;" class="filter-item"/>
+            <el-input v-model="row.quantity" style="width: 80px;" class="filter-item" />
           </template>
           <span v-else>{{ row.quantity }}</span>
         </template>
@@ -77,8 +78,8 @@
       <el-table-column label="单位" align="center">
         <template slot-scope="{row}">
           <template v-if="row.edit">
-            <el-select filterable v-model="row.unit">
-              <el-option v-for="item in units" :key="item" :label="item" :value="item"/>
+            <el-select v-model="row.unit" filterable>
+              <el-option v-for="item in units" :key="item" :label="item" :value="item" />
             </el-select>
           </template>
           <span v-else>{{ row.unit }}</span>
@@ -140,7 +141,7 @@ export default {
   name: 'RecipeFood',
   components: {},
   filters: {
-    foodTypeFilter(value){
+    foodTypeFilter(value) {
       return foodTypeMapping[value]
     }
   },
@@ -163,7 +164,7 @@ export default {
     this.$refs.foodSelect.focus()
   },
   methods: {
-    fetchData(){
+    fetchData() {
       this.listLoading = true
       getRecipeFoods(this.recipeId).then(res => {
         this.list = res.data.list

+ 100 - 63
src/views/recipe/index.vue

@@ -4,22 +4,24 @@
       <el-input
         v-model="listQuery.query"
         placeholder="请输入检索词"
-        style="width: 60%;"
+        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;"
+        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>
+      >新建</el-button>
     </div>
 
     <el-table
@@ -29,7 +31,7 @@
       border
       fit
       highlight-current-row
-      style="width: 100%;"
+      style="width: 100%"
       @row-click="showDialog"
     >
       <el-table-column type="index" label="序号" align="center" fixed width="60px" />
@@ -45,7 +47,7 @@
       </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" />
+          <el-image style="width: 180px height: 100px" :src="row.coverPic" fit="contain" />
         </template>
       </el-table-column>
       <el-table-column label="描述" align="center">
@@ -63,11 +65,18 @@
           <span>{{ row.updateTime }}</span>
         </template>
       </el-table-column>
-      <el-table-column label="操作" align="center" class-name="small-padding" fixed="right" width="90">
-        <template slot-scope="{row,$index}">
+      <el-table-column
+        label="操作"
+        align="center"
+        class-name="small-padding"
+        fixed="right"
+        width="90"
+      >
+        <template slot-scope="{row}">
           <el-dropdown @command="handleCommand">
-            <el-button size="small" @click.stop="{}" type="primary">
-              操作<i class="el-icon-arrow-down el-icon--right"></i>
+            <el-button size="small" type="primary" @click.stop="{}">
+              操作
+              <i class="el-icon-arrow-down el-icon--right" />
             </el-button>
             <el-dropdown-menu slot="dropdown">
               <el-dropdown-item :command="{row: row, command: 'update'}">更新</el-dropdown-item>
@@ -80,10 +89,23 @@
       </el-table-column>
     </el-table>
 
-    <pagination v-show="total>0" :total="total" :page.sync="listQuery.pageNum" :limit.sync="listQuery.pageSize" @pagination="fetchData" />
+    <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
+        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>
@@ -94,16 +116,17 @@
           <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%" />
+          <single-image
+            :value="params.coverPic"
+            :show-preview="true"
+            style="width: 100%"
+            @success="updateFile"
+          />
         </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>
+        <el-button @click="dialogFormVisible = false">取消</el-button>
+        <el-button type="primary" @click="dialogStatus==='create'?createData():updateData()">提交</el-button>
       </div>
     </el-dialog>
 
@@ -114,7 +137,13 @@
 </template>
 
 <script>
-import { getRecipes, createRecipe, updateRecipe, removeRecipe, getRecipeReport } from '@/api/recipe'
+import {
+  getRecipes,
+  createRecipe,
+  updateRecipe,
+  removeRecipe,
+  getRecipeReport
+} from '@/api/recipe'
 import Pagination from '@/components/Pagination'
 import SingleImage from '@/components/Upload/SingleImage'
 
@@ -132,7 +161,7 @@ export default {
       list: [],
       total: 0,
       dialogFormVisible: false,
-      textMap: { 'create': '新建', 'edit': '更新' },
+      textMap: { create: '新建', edit: '更新' },
       dialogStatus: '',
       rules: {},
       params: {},
@@ -146,19 +175,20 @@ export default {
   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
-      })
+      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` })
@@ -167,44 +197,52 @@ export default {
       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()
-      })
+      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()
-      })
+      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()
-      })
+      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(data) {
       this.$set(this.params, 'coverPic', data.fileUrl)
     },
     showDialog(row) {
-      getRecipeReport(row.id).then(res => {
-        this.contentDialogVisible = true
-        this.recipeContentHtml = res.data
-      }).catch(res => {
-        this.$message.error(res.data.message)
-      })
+      getRecipeReport(row.id)
+        .then(res => {
+          this.contentDialogVisible = true
+          this.recipeContentHtml = res.data
+        })
+        .catch(res => {
+          this.$message.error(res.data.message)
+        })
     },
     handleCommand(data) {
       switch (data.command) {
@@ -227,5 +265,4 @@ export default {
 </script>
 
 <style scoped>
-
 </style>

+ 3 - 2
src/views/recipe/step.vue

@@ -4,7 +4,8 @@
       class="filter-item"
       style="margin-left: 10px;"
       type="primary"
-      @click="handleCreateOrUpdate('create')">
+      @click="handleCreateOrUpdate('create')"
+    >
       添加
     </el-button>
 
@@ -52,7 +53,7 @@
           <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%" />
+          <single-image :value="params.stepPic" :show-preview="true" style="width: 100%" @success="updateFile" />
         </el-form-item>
       </el-form>
       <div slot="footer" class="dialog-footer">

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

@@ -80,8 +80,8 @@
       <el-table-column label="操作" align="center" class-name="small-padding fixed-width" fixed="right" width="90">
         <template slot-scope="{row}">
           <el-dropdown @command="handleCommand">
-            <el-button size="small" @click.stop="{}" type="primary">
-              操作<i class="el-icon-arrow-down el-icon--right"></i>
+            <el-button size="small" type="primary" @click.stop="{}">
+              操作<i class="el-icon-arrow-down el-icon--right" />
             </el-button>
             <el-dropdown-menu slot="dropdown">
               <el-dropdown-item :command="{row: row, command: 'update'}">更新</el-dropdown-item>

+ 126 - 125
src/views/user/index.vue

@@ -16,7 +16,8 @@
         style="margin: 0 10px 20px 0; float: right;"
         type="success"
         icon="el-icon-circle-plus-outline"
-        @click="handleCreate">
+        @click="handleCreate"
+      >
         新建
       </el-button>
     </div>
@@ -69,10 +70,10 @@
           <el-button type="danger" size="mini" @click="resetPassword(row)">
             重置密码
           </el-button>
-          <el-button size="mini" type="info" v-if="row.isFrozen" @click="handleFrozen(row)">
+          <el-button v-if="row.isFrozen" size="mini" type="info" @click="handleFrozen(row)">
             解除冻结
           </el-button>
-          <el-button size="mini" type="danger" v-else @click="handleFrozen(row)">
+          <el-button v-else size="mini" type="danger" @click="handleFrozen(row)">
             冻结
           </el-button>
         </template>
@@ -92,7 +93,7 @@
         <el-form-item label="工号" prop="name">
           <el-input v-model="params.name" placeholder="请输入工号" />
         </el-form-item>
-        <el-form-item label="密码" prop="password" v-if="dialogStatus==='CREATE'">
+        <el-form-item v-if="dialogStatus==='CREATE'" label="密码" prop="password">
           <el-input v-model="params.password" type="password" :show-password="true" placeholder="请输入密码" />
         </el-form-item>
         <el-form-item label="昵称" prop="nickName">
@@ -107,7 +108,7 @@
           </el-select>
         </el-form-item>
         <el-form-item label="头像" prop="profilePic">
-          <single-image :value="params.profilePic" :show-preview="true" @success="uploadFile" style="width: 100%" />
+          <single-image :value="params.profilePic" :show-preview="true" style="width: 100%" @success="uploadFile" />
         </el-form-item>
       </el-form>
       <div slot="footer" class="dialog-footer">
@@ -142,133 +143,133 @@
 </template>
 
 <script>
-  import Pagination from '@/components/Pagination'
-  import SingleImage from '@/components/Upload/SingleImage'
-  import { getUsers, changeUserFrozen, resetUserPassword, createUser, updateUser } from '@/api/user'
+import Pagination from '@/components/Pagination'
+import SingleImage from '@/components/Upload/SingleImage'
+import { getUsers, changeUserFrozen, resetUserPassword, createUser, updateUser } from '@/api/user'
 
-  const genderMapping = { 0: '未知', 1: '男', 2: '女' }
+const genderMapping = { 0: '未知', 1: '男', 2: '女' }
 
-  export default {
-    name: 'UserList',
-    components: { Pagination, SingleImage },
-    filters: {
-      genderFilter(value) {
-        return genderMapping[value]
-      }
-    },
-    created() {
-      this.fetchData()
-    },
-    data() {
-      return {
-        tableKey: 0,
-        listQuery: {
-          query: '',
-          pageNum: 1,
-          pageSize: 20
-        },
-        list: [],
-        rules: {
-          name: [{ required: true, message: '工号不能为空', trigger: 'blur' }],
-          password: [{ required: true, message: '密码不能为空', trigger: 'blur' }]
-        },
-        resetPasswordRules: {
-          newPassword: [{ required: true, message: '密码不能为空', trigger: 'blur' }],
-          newPasswordConfirm: [{ required: true, message: '密码不能为空', trigger: 'blur' }]
-        },
-        listLoading: true,
-        total: 0,
-        dialogStatus: '',
-        dialogFormVisible: false,
-        params: {},
-        profilePic: '',
-        resetPasswordParams: {},
-        resetPasswordDialog: false,
-        genders: [{ value: 0, name: '未知' }, { value: 1, name: '男' }, { value: 2, name: '女' }],
-        textMapping: { 'UPDATE': '更新', 'CREATE': '创建' }
-      }
-    },
-    methods: {
-      fetchData() {
-        this.listLoading = true
-        getUsers(this.listQuery).then(res => {
-          this.list = res.data.list
-          this.total = res.data.count
-          this.listLoading = false
-        }).catch(res => {
-          this.listLoading = false
-          this.$message.error(res.data.message)
-        })
-      },
-      handleCreate() {
-        this.dialogStatus = 'CREATE'
-        this.params = {}
-        this.$set(this.params, 'gender', 0)
-        this.dialogFormVisible = true
-      },
-      handleUpdate(row) {
-        this.dialogStatus = 'UPDATE'
-        this.params = row
-        this.dialogFormVisible = true
-      },
-      handleFrozen(row) {
-        this.listLoading = true
-        changeUserFrozen(row.id).then(res => {
-          this.fetchData()
-          this.$message.success("提交成功")
-        }).catch(res => {
-          this.fetchData()
-          this.$message.error(res.data.message)
-        })
-      },
-      createData() {
-        this.params.gender = this.gender
-        createUser(this.params).then(res => {
-          this.fetchData()
-          this.$message.success("提交成功")
-          this.dialogFormVisible = false
-        }).catch(res => {
-          this.fetchData()
-          this.$message.error(res.data.message)
-          this.dialogFormVisible = false
-        })
-      },
-      updateData() {
-        this.params.gender = this.gender
-        updateUser(this.params.id, this.params).then(res => {
-          this.fetchData()
-          this.$message.success("提交成功")
-          this.dialogFormVisible = false
-        }).catch(res => {
-          this.fetchData()
-          this.$message.error(res.data.message)
-          this.dialogFormVisible = false
-        })
+export default {
+  name: 'UserList',
+  components: { Pagination, SingleImage },
+  filters: {
+    genderFilter(value) {
+      return genderMapping[value]
+    }
+  },
+  data() {
+    return {
+      tableKey: 0,
+      listQuery: {
+        query: '',
+        pageNum: 1,
+        pageSize: 20
       },
-      uploadFile(data) {
-        this.$set(this.params, "profilePic", data.fileUrl)
+      list: [],
+      rules: {
+        name: [{ required: true, message: '工号不能为空', trigger: 'blur' }],
+        password: [{ required: true, message: '密码不能为空', trigger: 'blur' }]
       },
-      resetPassword(row) {
-        this.resetPasswordParams = { id: row.id }
-        this.resetPasswordDialog = true
+      resetPasswordRules: {
+        newPassword: [{ required: true, message: '密码不能为空', trigger: 'blur' }],
+        newPasswordConfirm: [{ required: true, message: '密码不能为空', trigger: 'blur' }]
       },
-      submitResetPassword() {
-        if (this.resetPasswordParams.newPassword !== this.resetPasswordParams.newPasswordConfirm) {
-          this.$message.error("两次输入的密码不一致")
-          return
-        }
-        resetUserPassword(this.resetPasswordParams.id, this.resetPasswordParams.newPassword).then(res => {
-          this.fetchData()
-          this.$message.success("提交成功")
-          this.resetPasswordDialog = false
-        }).catch(res => {
-          this.fetchData()
-          this.$message.error(res.data.message)
-          this.resetPasswordDialog = false
-        })
-      }
+      listLoading: true,
+      total: 0,
+      dialogStatus: '',
+      dialogFormVisible: false,
+      params: {},
+      profilePic: '',
+      resetPasswordParams: {},
+      resetPasswordDialog: false,
+      genders: [{ value: 0, name: '未知' }, { value: 1, name: '男' }, { value: 2, name: '女' }],
+      textMapping: { 'UPDATE': '更新', 'CREATE': '创建' }
+    }
+  },
+  created() {
+    this.fetchData()
+  },
+  methods: {
+    fetchData() {
+      this.listLoading = true
+      getUsers(this.listQuery).then(res => {
+        this.list = res.data.list
+        this.total = res.data.count
+        this.listLoading = false
+      }).catch(res => {
+        this.listLoading = false
+        this.$message.error(res.data.message)
+      })
+    },
+    handleCreate() {
+      this.dialogStatus = 'CREATE'
+      this.params = {}
+      this.$set(this.params, 'gender', 0)
+      this.dialogFormVisible = true
+    },
+    handleUpdate(row) {
+      this.dialogStatus = 'UPDATE'
+      this.params = row
+      this.dialogFormVisible = true
+    },
+    handleFrozen(row) {
+      this.listLoading = true
+      changeUserFrozen(row.id).then(res => {
+        this.fetchData()
+        this.$message.success('提交成功')
+      }).catch(res => {
+        this.fetchData()
+        this.$message.error(res.data.message)
+      })
+    },
+    createData() {
+      this.params.gender = this.gender
+      createUser(this.params).then(res => {
+        this.fetchData()
+        this.$message.success('提交成功')
+        this.dialogFormVisible = false
+      }).catch(res => {
+        this.fetchData()
+        this.$message.error(res.data.message)
+        this.dialogFormVisible = false
+      })
     },
+    updateData() {
+      this.params.gender = this.gender
+      updateUser(this.params.id, this.params).then(res => {
+        this.fetchData()
+        this.$message.success('提交成功')
+        this.dialogFormVisible = false
+      }).catch(res => {
+        this.fetchData()
+        this.$message.error(res.data.message)
+        this.dialogFormVisible = false
+      })
+    },
+    uploadFile(data) {
+      this.$set(this.params, 'profilePic', data.fileUrl)
+    },
+    resetPassword(row) {
+      this.resetPasswordParams = { id: row.id }
+      this.resetPasswordDialog = true
+    },
+    submitResetPassword() {
+      if (this.resetPasswordParams.newPassword !== this.resetPasswordParams.newPasswordConfirm) {
+        this.$message.error('两次输入的密码不一致')
+        return
+      }
+      resetUserPassword(this.resetPasswordParams.id, this.resetPasswordParams.newPassword).then(res => {
+        this.fetchData()
+        this.$message.success('提交成功')
+        this.resetPasswordDialog = false
+      }).catch(res => {
+        this.fetchData()
+        this.$message.error(res.data.message)
+        this.resetPasswordDialog = false
+      })
+    }
   }
+}
 </script>
 
 <style scoped>