scorpio 2 år sedan
förälder
incheckning
5cee48fb35

+ 0 - 1
src/App.vue

@@ -49,7 +49,6 @@ export default {
   },
   mounted() {
     window.addEventListener('scroll', this.menu)
-    console.log(this.$route.meta.show)
   },
   methods: {
     router,

+ 49 - 41
src/api/axios.js

@@ -26,49 +26,57 @@ NProgress.configure({
   showSpinner: false
 })
 // http request拦截
-axios.interceptors.request.use(config => {
-  // 开启 progress bar
-  NProgress.start()
-  const meta = (config.meta || {})
-  const isToken = meta.isToken === false
-  config.headers.Authorization = `Basic ${Base64.encode(`${website.clientId}:${website.clientSecret}`)}`
-  // 让每个请求携带token
-  if (getToken() && !isToken) {
-    config.headers['Blade-Auth'] = 'bearer ' + getToken()
+axios.interceptors.request.use(
+  config => {
+    // 开启 progress bar
+    NProgress.start()
+    const meta = config.meta || {}
+    const isToken = meta.isToken === false
+    config.headers.Authorization = `Basic ${Base64.encode(
+      `${website.clientId}:${website.clientSecret}`
+    )}`
+    // 让每个请求携带token
+    if (getToken() && !isToken) {
+      config.headers['Blade-Auth'] = 'bearer ' + getToken()
+    }
+    // headers中配置text请求
+    if (config.text === true) {
+      config.headers['Content-Type'] = 'text/plain'
+    }
+    // headers中配置serialize为true开启序列化
+    // if (config.method === 'post' && meta.isSerialize === true) {
+    //   config.data = serialize(config.data)
+    // }
+    return config
+  },
+  error => {
+    return Promise.reject(error)
   }
-  // headers中配置text请求
-  if (config.text === true) {
-    config.headers['Content-Type'] = 'text/plain'
-  }
-  // headers中配置serialize为true开启序列化
-  // if (config.method === 'post' && meta.isSerialize === true) {
-  //   config.data = serialize(config.data)
-  // }
-  return config
-}, error => {
-  return Promise.reject(error)
-})
+)
 // http response 拦截
-axios.interceptors.response.use(res => {
-  // 关闭 progress bar
-  NProgress.done()
-  // 获取状态码
-  const status = res.data.code || res.status
-  const statusWhiteList = website.statusWhiteList || []
-  // 如果在白名单里则自行catch逻辑处理
-  if (statusWhiteList.includes(status)) return Promise.reject(res)
-  // 如果是401则跳转到登录页面
-  if (status === 401) {
-    router.push('/login')
+axios.interceptors.response.use(
+  res => {
+    // 关闭 progress bar
+    NProgress.done()
+    // 获取状态码
+    const status = res.data.code || res.status
+    const statusWhiteList = website.statusWhiteList || []
+    // 如果在白名单里则自行catch逻辑处理
+    if (statusWhiteList.includes(status)) return Promise.reject(res)
+    // 如果是401则跳转到登录页面
+    if (status === 401) {
+      router.push('/login')
+    }
+    // 如果请求为非200否者默认统一处理
+    if (status !== 200) {
+      return Promise.reject(res)
+    }
+    return res
+  },
+  error => {
+    NProgress.done()
+    return Promise.reject(error)
   }
-  // 如果请求为非200否者默认统一处理
-  if (status !== 200) {
-    return Promise.reject(res)
-  }
-  return res
-}, error => {
-  NProgress.done()
-  return Promise.reject(error)
-})
+)
 
 export default axios

+ 6 - 3
src/api/fetch.js

@@ -73,7 +73,6 @@ function fetch(
       if (status >= 200 && status <= 401) {
         if (data.code === 401 || data.code === 400) {
           // 未登录
-          console.log(data)
           removeToken()
           router.push(`/?redirect=${encodeURIComponent(window.location.href)}`)
           reject(new Error('需要登录'))
@@ -106,8 +105,12 @@ function fetch(
           }
           ElMessage.error(msg)
         } else {
-          resolve(err.data)
-          // ElMessage.error(err.data.error_description ? err.data.error_description : '网络异常,请点击重试')
+          // resolve(err.data)
+          ElMessage.error(
+            err.data.error_description
+              ? err.data.error_description
+              : '网络异常,请点击重试'
+          )
         }
       })
   })

+ 2 - 2
src/assets/style/color.scss

@@ -1,6 +1,6 @@
 //$primary: #7C9CFF;
-$primary: #ECAB56;
+$primary: #A3773D;
 $red: #ef0b0b;
 $blue: #409eff;
 $green: #5dc800;
-$border: #e7e7e7;
+$border: #f7f9fc;

+ 1 - 0
src/layout/index.vue

@@ -100,6 +100,7 @@ export default {
   methods: {
     getPermission() {
       this.$api.login.getPermission().then(res => {
+        console.log(res)
         if (res.code === 200) {
           this.permission.cleanPermission()
           this.permission.addPermission(res.data)

+ 0 - 1
src/layout/top.vue

@@ -161,7 +161,6 @@ export default {
       this.dataType = tmp
     }
     this.$bus.on('navChange', res => {
-      console.log(res)
       this.dataType = res
     })
     this.$bus.on('sizeChange', res => {

+ 0 - 129
src/views/home/component/task.vue

@@ -1,129 +0,0 @@
-<template>
-  <div>
-    <el-form :rules="rules" :model="form">
-      <el-form-item label="任务名称" prop="title">
-        <el-input v-model="form.title" placeholder="请填写任务名称"></el-input>
-      </el-form-item>
-      <el-form-item label="任务说明" prop="remark">
-        <el-input
-          v-model="form.remark"
-          type="textarea"
-          :rows="6"
-          placeholder="请填写任务说明"
-        ></el-input>
-      </el-form-item>
-      <el-form-item label="任务期限">
-        <el-date-picker
-          v-model="form.date"
-          type="daterange"
-          unlink-panels
-          range-separator="至"
-          start-placeholder="开始日期"
-          end-placeholder="截止日期"
-          format="YYYY-MM-DD"
-          value-format="YYYY-MM-DD"
-        />
-      </el-form-item>
-      <div class="full-width flex flex-align-center mt-10">
-        <span class="font-14 bold">生成二维码</span>
-        <el-button
-          circle
-          class="ml-20"
-          icon="Picture"
-          type="danger"
-          @click="initCode()"
-        />
-      </div>
-      <div
-        class="full-width mt-20 border-top padding-top flex flex-justify-end"
-      >
-        <el-button @click="close">取消</el-button>
-        <el-button type="primary" @click="close">关闭</el-button>
-      </div>
-    </el-form>
-    <el-dialog v-model="qrCodeShow" width="400px">
-      <div
-        class="flex flex-col flex-center"
-        style="height: 400rpx; width: 400rpx"
-      >
-        <vue-qr
-          :currentLevel="3"
-          :logoCornerRadius="4"
-          :logoScale="0.25"
-          :text="qrCodeText"
-          size="340"
-        />
-        <span>右键复制二维码,通过微信进行分享</span>
-        <span>{{ qrCodeText }}</span>
-      </div>
-    </el-dialog>
-  </div>
-</template>
-
-<script>
-import VueQr from 'vue-qr/src/packages/vue-qr.vue'
-import { objectToParams } from '@/utils/tools.js'
-export default {
-  name: 'task',
-  components: { VueQr },
-  props: {
-    projectId: {
-      type: String,
-      default: ''
-    },
-    folders: {
-      type: Array,
-      default: []
-    }
-  },
-  data() {
-    return {
-      qrCodeText: '',
-      qrCodeShow: false,
-      rules: {
-        title: [{ required: true, message: '请输入任务名称', trigger: 'blur' }],
-        remark: [{ required: true, message: '请输入任务说明', trigger: 'blur' }]
-      },
-      form: {
-        title: '',
-        remark: '',
-        date: '',
-        taskStartTime: '',
-        taskEndTime: ''
-      }
-    }
-  },
-  methods: {
-    initCode() {
-      // this.qrCodeShow = true
-      if (this.form.date.length !== 2) {
-        this.$message.error('请按要求选择时间段')
-        return
-      }
-      this.form.folderIds = this.folders.map(sub => sub.id)
-      this.form.taskStartTime = this.form.date[0]
-      this.form.taskEndTime = this.form.date[1]
-      this.form.projectId = this.projectId
-      this.$api.task.add(this.form).then(res => {
-        if (res.code === 200) {
-          this.$message.success(res.msg)
-          this.qrCodeShow = true
-          const data = res.data
-          this.qrCodeText =
-            'https://prod.wutongshucloud.com/apply?id=' +
-            data.qrcodeId +
-            '&' +
-            objectToParams(res.data)
-        } else {
-          this.$message.error(res.msg)
-        }
-      })
-    },
-    close() {
-      this.$emit('close')
-    }
-  }
-}
-</script>
-
-<style scoped></style>

+ 16 - 9
src/views/task/component/task-table.vue

@@ -62,21 +62,28 @@
             class="flex-child-average full-height full-width flex flex-center"
           >
             <div>
-              <div>08-14 截止</div>
+              <div>{{ row.startTime }} 至 {{ row.endTime }}</div>
             </div>
           </div>
           <div
             v-else
             class="flex-child-average full-height full-width flex flex-center"
           >
-            <el-avatar
-              src="https://cube.elemecdn.com/0/88/03b0d39583f48206768a7534e55bcpng.png"
-            />
-            <el-avatar
-              src="https://cube.elemecdn.com/0/88/03b0d39583f48206768a7534e55bcpng.png"
-            /><el-avatar
-              src="https://cube.elemecdn.com/0/88/03b0d39583f48206768a7534e55bcpng.png"
-            />
+            <div v-if="row.users !== undefined" class="flex flex-center">
+              <div v-for="i in row.users" :key="i.id" class="flex flex-center">
+                <el-tooltip :content="i.name">
+                  <el-avatar
+                    class="ml-10 mr-10"
+                    :size="25"
+                    :src="
+                      i.avatar.length === 0
+                        ? 'https://cube.elemecdn.com/3/7c/3ea6beec64369c2642b92c6726f1epng.png'
+                        : i.avatar
+                    "
+                  ></el-avatar>
+                </el-tooltip>
+              </div>
+            </div>
           </div>
         </div>
       </div>

+ 22 - 6
src/views/task/component/task.vue

@@ -41,10 +41,14 @@
           </div>
         </div>
 
+        <div class="mt-10 flex lex-align-start flex-justify-start">
+          <span class="mr-10 title flex flex-justify-start">标签:</span>
+          <div><wt-label @submit="handleTags" /></div>
+        </div>
         <div class="mt-10 flex lex-align-start flex-justify-start">
           <span class="mr-10 title flex flex-justify-start">执行者:</span>
           <div>
-            <tasker />
+            <tasker :data="task.users" @success="selected" />
           </div>
         </div>
         <div class="mt-10 flex flex-align-start flex-justify-start">
@@ -86,7 +90,9 @@
         </div>
       </div>
       <div class="flex flex-justify-end full-width">
-        <el-button type="primary" plain>取 消</el-button>
+        <el-button type="primary" plain @click="showDialog = false"
+          >取 消</el-button
+        >
         <el-button type="primary" @click="submit">确 定</el-button>
       </div>
     </div>
@@ -97,9 +103,10 @@
 import WtTag from '@/views/task/component/wt-tag.vue'
 import Tasker from '@/views/task/component/tasker.vue'
 import filepicker from '@/components/filepicker/index.vue'
+import WtLabel from '@/views/task/component/wt-label.vue'
 
 export default {
-  components: { Tasker, WtTag, filepicker },
+  components: { WtLabel, Tasker, WtTag, filepicker },
   props: {
     projectId: {
       type: String,
@@ -119,7 +126,7 @@ export default {
           this.form = val
           this.data = this.fetchIndex(this.data, this.form.taskStatus)
           this.data1 = this.fetchIndex(this.data1, this.form.level)
-          if (val.files && val.files.length > 0) {
+          if (val.files !== undefined && val.files.length > 0) {
             this.fileList = val.files.map(ele => {
               return {
                 fileId: ele.id,
@@ -225,8 +232,8 @@ export default {
       this.form.projectId = this.projectId
       this.form.relatedIds = this.fileList.map(ele => ele.fileId).join(',')
       this.$api.task.addTask(this.form).then(res => {
+        this.showDialog = false
         if (res.code === 200) {
-          this.showDialog = false
           this.$message.success(res.msg)
         } else {
           this.$message.error(res.msg)
@@ -240,7 +247,16 @@ export default {
           title: ele.title
         }
       })
-      console.log(this.fileList)
+    },
+    selected(list) {
+      this.form.executeUser = list.map(ele => ele.id).join(',')
+    },
+    handleTags(tags) {
+      this.form.tags = tags
+    },
+    close() {
+      this.form = {}
+      this.showDialog = false
     }
   }
 }

+ 126 - 6
src/views/task/component/tasker.vue

@@ -1,23 +1,143 @@
 <template>
   <div class="flex flex-align-center flex-justify-start flex-wrap">
-    <div class="flex flex-center" v-for="i in 20">
-      <el-avatar
-        src="https://cube.elemecdn.com/0/88/03b0d39583f48206768a7534e55bcpng.png"
-      ></el-avatar>
-      <div class="ml-5">张三</div>
+    <div class="flex flex-align-center">
+      <div
+        class="flex flex-center ml-10 mr-10 padding-bottom tag"
+        v-for="i in selectedList"
+        :key="i.id"
+      >
+        <el-avatar :size="15" :src="i.avatar"></el-avatar>
+        <div class="ml-5">{{ i.name }}</div>
+        <el-icon class="ml-10" @click="remove(i)">
+          <CircleCloseFilled />
+        </el-icon>
+      </div>
     </div>
+    <el-icon
+      size="30"
+      class="padding-left padding-right"
+      color="#A3773D"
+      @click="show = true"
+    >
+      <CirclePlusFilled />
+    </el-icon>
+
+    <el-dialog v-model="show" width="500">
+      <div>
+        <el-input placeholder="搜索"></el-input>
+        <div
+          class="mt-20 padding-left padding-right"
+          style="height: 300px; overflow-y: scroll"
+        >
+          <div
+            v-for="i in list"
+            :key="i.id"
+            class="full-width flex flex-justify-between flex-center border-bottom padding-bottom padding-top"
+            @click="change(i)"
+          >
+            <div class="flex flex-center flex-justify-start">
+              <el-icon v-if="i.checked" color="#ab7630" size="18px">
+                <CircleCheckFilled />
+              </el-icon>
+              <el-icon v-else color="grey" size="18px">
+                <CircleCheck />
+              </el-icon>
+              <el-avatar
+                class="ml-10 mr-10"
+                :size="25"
+                :src="i.avatar"
+              ></el-avatar>
+              <div class="ml-5">{{ i.name }}</div>
+            </div>
+            <el-tag>出差中</el-tag>
+          </div>
+        </div>
+        <div class="full-width flex flex-center flex-justify-end mt-20">
+          <el-button plain type="primary" size="small" @click="show = false"
+            >取 消</el-button
+          >
+          <el-button type="primary" size="small" @click="submit"
+            >确 定</el-button
+          >
+        </div>
+      </div>
+    </el-dialog>
   </div>
 </template>
 
 <script>
+import { useStore } from '@/store/user.js'
+
 export default {
   props: {
     data: {
       type: Array,
       default: []
     }
+  },
+  setup() {
+    const user = useStore()
+    return { user }
+  },
+  watch: {
+    data: {
+      handler(val) {
+        if (val && val.length > 0) {
+          this.selectedList = val
+        }
+      },
+      immediate: true
+    }
+  },
+  data() {
+    return {
+      show: false,
+      list: [],
+      keyword: '',
+      selectedList: []
+    }
+  },
+  created() {
+    this.getUser()
+  },
+  methods: {
+    getUser() {
+      const data = { key: this.keyword, deptId: this.user.info.deptId }
+      this.$api.role.roleList(data).then(res => {
+        if (res.code === 200) {
+          this.list = res.data.records.map(ele => {
+            ele.avatar = ele.avatar
+              ? ele.avatar
+              : 'https://cube.elemecdn.com/3/7c/3ea6beec64369c2642b92c6726f1epng.png'
+            ele.checked = false
+            return ele
+          })
+        }
+      })
+    },
+    change(res) {
+      res.checked = !res.checked
+    },
+    submit() {
+      this.selectedList = this.list.filter(ele => ele.checked)
+      this.$emit('success', this.selectedList)
+      this.show = false
+    },
+    remove(res) {
+      this.selectedList = this.selectedList.filter(ele => ele.id !== res.id)
+    }
   }
 }
 </script>
 
-<style lang="scss" scoped></style>
+<style lang="scss" scoped>
+.tag {
+  min-width: 60px;
+  height: 20px;
+  border-radius: 20px;
+  background-color: #a3773d;
+  padding: 2px 10px;
+  margin: 0 5px;
+  color: white;
+}
+</style>

+ 101 - 0
src/views/task/component/wt-label.vue

@@ -0,0 +1,101 @@
+<template>
+  <div class="flex flex-wrap flex-center">
+    <div class="tag flex flex-center" v-for="i in tags" :key="i.label">
+      {{ i.label }}
+      <el-icon class="ml-10" @click="remove(i)">
+        <CircleCloseFilled />
+      </el-icon>
+    </div>
+    <el-icon
+      size="30"
+      class="padding-left padding-right"
+      color="#A3773D"
+      @click="show = true"
+    >
+      <CirclePlusFilled />
+    </el-icon>
+
+    <el-dialog v-model="show" width="500" title="选择标签">
+      <div class="flex flex-center">
+        <el-select v-model="form.tag1" class="mr-10" placeholder="请选择">
+          <el-option
+            v-for="item in options"
+            :key="item.value"
+            :label="item.label"
+            :value="item"
+          />
+        </el-select>
+        <el-select v-model="form.tag2" placeholder="请选择">
+          <el-option
+            v-for="item in options1"
+            :key="item.value"
+            :label="item.label"
+            :value="item"
+          />
+        </el-select>
+      </div>
+      <div class="full-width flex flex-center flex-justify-end mt-20">
+        <el-button type="primary" plain @click="show = false">取 消</el-button>
+        <el-button type="primary" @click="submit">确 定</el-button>
+      </div>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+export default {
+  data() {
+    return {
+      show: false,
+      tags: [],
+      form: {
+        tag1: '',
+        tag2: ''
+      },
+      options: [
+        {
+          label: '新编',
+          value: 1
+        },
+        {
+          label: '修改',
+          value: 2
+        }
+      ],
+      options1: [
+        {
+          label: '项目建议书',
+          value: 1
+        },
+        {
+          label: '可研报告',
+          value: 2
+        }
+      ]
+    }
+  },
+  methods: {
+    submit() {
+      this.tags = [this.form.tag1, this.form.tag2]
+      this.show = false
+      this.form = {}
+      this.$emit('submit', { tags: this.tags })
+    },
+    remove(res) {
+      this.tags = this.tags.filter(ele => ele.label !== res.label)
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.tag {
+  min-width: 60px;
+  height: 20px;
+  border-radius: 20px;
+  background-color: #a3773d;
+  padding: 2px 10px;
+  margin: 0 5px;
+  color: white;
+}
+</style>

+ 1 - 7
src/views/task/index.vue

@@ -30,8 +30,7 @@
 <route>
 {
 path: '/task',
-name: '任务列表',
-meta: {keepAlive: true,show: false}
+name: '任务列表'
 }
 </route>
 
@@ -40,7 +39,6 @@ import TaskTable from '@/views/task/component/task-table.vue'
 import Task from '@/views/task/component/task.vue'
 
 export default {
-  name: 'index',
   components: { Task, TaskTable },
   data() {
     return {
@@ -89,10 +87,6 @@ export default {
           this.data = res.data.records
         }
       })
-    },
-    rowClick(item) {
-      this.task = item
-      this.$refs.task.show()
     }
   }
 }

+ 0 - 1
src/views/user/manage.vue

@@ -337,7 +337,6 @@ export default {
       this.page.current = this.page.currentPage
       this.page.size = this.page.pageSize
       const data = { deptId: this.user.info.deptId }
-      console.log(this.page)
       this.$api.role
         .roleList(Object.assign(this.page, data))
         .then(res => {