walter 8 月之前
父節點
當前提交
f3f9ed35cd
共有 49 個文件被更改,包括 5088 次插入435 次删除
  1. 1 1
      build/webpack.prod.conf.js
  2. 727 0
      src/components/AppealInfo.vue
  3. 253 0
      src/components/AppealRewrite.vue
  4. 5 0
      src/components/CategorySelectorCell.vue
  5. 10 2
      src/components/DeptSelectorBtn.vue
  6. 1 1
      src/components/EmployeeSelector.vue
  7. 30 0
      src/components/IntegralEventSelector.vue
  8. 6 2
      src/components/Mtextarea.vue
  9. 7 3
      src/components/Mtextarea2.vue
  10. 1 1
      src/components/NumberInput.vue
  11. 79 3
      src/components/RuleCategorySelector.vue
  12. 44 5
      src/components/RuleCategorySelector1.vue
  13. 17 9
      src/components/RuleCategorySelectorCell1.vue
  14. 5 5
      src/components/TabsList.vue
  15. 1 1
      src/components/user_image.vue
  16. 2 2
      src/okr/view/task/taskDetail.vue
  17. 22 14
      src/point/view/audit/integralAudit.vue
  18. 365 0
      src/point/view/integral/appealList.vue
  19. 141 28
      src/point/view/integral/approval_detail.vue
  20. 42 17
      src/point/view/integral/approval_list.vue
  21. 66 11
      src/point/view/integral/approval_process.vue
  22. 4 4
      src/point/view/integral/batchList.vue
  23. 272 0
      src/point/view/integral/deptRank.vue
  24. 98 7
      src/point/view/integral/event_detail.vue
  25. 49 10
      src/point/view/integral/event_list.vue
  26. 1 1
      src/point/view/integral/integral_application.vue
  27. 2 2
      src/point/view/integral/integral_entry_n.vue
  28. 2 2
      src/point/view/integral/manager_reward_deduction.vue
  29. 336 0
      src/point/view/integral/reward_deduction_search.vue
  30. 5 1
      src/point/view/integral/rule_category_add.vue
  31. 6 2
      src/point/view/integral/rule_category_edit.vue
  32. 5 1
      src/point/view/integral/rule_item_add.vue
  33. 6 1
      src/point/view/integral/rule_item_edit.vue
  34. 101 12
      src/point/view/pointHome.vue
  35. 529 0
      src/point/view/task/TaskEdit.vue
  36. 520 0
      src/point/view/task/WorkEdit.vue
  37. 14 2
      src/point/view/task/my_publish.vue
  38. 4 3
      src/point/view/task/my_task.vue
  39. 297 66
      src/point/view/task/repetitive_tasks_detail.vue
  40. 209 16
      src/point/view/task/short_task.vue
  41. 341 122
      src/point/view/task/taskFile.vue
  42. 188 43
      src/point/view/task/task_detail_a.vue
  43. 225 30
      src/point/view/task/temp_task.vue
  44. 37 0
      src/router/pointRoute.js
  45. 1 1
      src/store/modules/user.js
  46. 3 0
      src/utils/helper.js
  47. 3 1
      src/utils/validator.js
  48. 4 2
      src/view/system/about.vue
  49. 1 1
      src/view/user/login.vue

+ 1 - 1
build/webpack.prod.conf.js

@@ -35,7 +35,7 @@ const webpackConfig = merge(baseWebpackConfig, {
     new BundleAnalyzerPlugin({
       analyzerMode: 'server',
       analyzerHost: '127.0.0.1',
-      analyzerPort: 8889,
+      analyzerPort: 8890,
       reportFilename: 'report.html',
       defaultSizes: 'parsed',
       openAnalyzer: true,

+ 727 - 0
src/components/AppealInfo.vue

@@ -0,0 +1,727 @@
+<template>
+  <van-popup
+    v-model="showAppealInfo"
+    :position="position"
+    duration="0.2"
+    :style="{ height: height, width: width, 'background-color': 'rgb(245, 245, 245)' }"
+    @open="onOpen"
+    @closed="onClosed"
+  >
+    <div style="height: 100%;width: 100%;" >
+      <van-nav-bar
+        title="申诉信息"
+        :left-arrow="true"
+        @click-left="showAppealInfo = false"
+        @click-right="showActions = true"
+        fixed
+      >
+        <template slot="right" v-if="canActions">
+          <van-icon name="bars"/>
+        </template>
+      </van-nav-bar>
+      <div class="container" v-if="appealInfo" >
+        <div class="card-box">
+          <van-row type="flex" justify="center" gutter="10" align="center">
+            <van-col span="6" style="text-align: right">
+              <userImage
+                :img_url="appealInfo.employee_img_url"
+                :user_name="appealInfo.employee_name"
+              />
+            </van-col>
+            <van-col span="10" style="text-align: left" class="font-flex-word">
+              <span style="line-height: 0.8rem;">{{appealInfo.employee_name}}</span>
+            </van-col>
+            <van-col span="8">
+              <van-tag :type="appealStatusType(appealInfo.status)" size="medium" >{{appealStatusMap[appealInfo.status] || '--'}}</van-tag>
+            </van-col>
+          </van-row>
+          <van-divider/>
+          <div class="card-content">
+            <p><van-tag type="primary" size="medium">{{appealInfo.create_time}}</van-tag>&nbsp;发起申诉申请</p>
+            <p>共<van-tag type="primary" size="medium">{{appealInfo.events.length}}</van-tag>&nbsp;条积分事件</p>
+            <p v-if="appealInfo.global_remark">申请原因&nbsp;:&nbsp;<van-tag type="primary" size="medium">{{appealInfo.global_remark}}</van-tag></p>
+            <template v-if="appealInfo.complete_time">
+              <p><van-tag type="primary" size="medium">{{appealInfo.complete_time}}</van-tag>&nbsp;审批结束</p>
+            </template>
+          </div>
+        </div>
+        <van-collapse v-model="activeNames" accordion @change="collapseChange">
+          <van-collapse-item name="process">
+            <template slot="title">
+              <span class="content-font">审批流程</span>
+            </template>
+            <van-steps direction="vertical" :active="appealInfo.process.length - 1" >
+              <van-step v-for="(item,index) in appealInfo.process" :key="index" >
+                <div class="card-box">
+                  <div class="card-content" style="text-align: left;line-height: 0.25rem;">
+                    <p>阶段{{item.step}}&nbsp;<van-tag :type="processStatusType(item.status)" size="medium">{{processStatusMap[item.status] || '--'}}</van-tag></p>
+                    <p>发起人&nbsp;:&nbsp;{{item.publisher_name}}</p>
+                    <p>发起时间&nbsp;:&nbsp;{{item.create_time}}</p>
+                    <p>审批人&nbsp;:&nbsp;{{item.reviewer_name}}</p>
+                    <p v-if="item.remark" class="font-flex-word">审批意见&nbsp;:&nbsp;{{item.remark}}</p>
+                    <p v-if="item.complete_time">完结时间&nbsp;:&nbsp;{{item.complete_time}}</p>
+                  </div>
+                </div>
+              </van-step>
+            </van-steps>
+          </van-collapse-item>
+          <van-collapse-item name="events">
+            <template slot="title">
+              <span class="content-font">{{appealInfo.events.length + '条积分事件'}}</span>
+            </template>
+            <div class="card-box" v-for="(item,index) in appealInfo.events" :key="index">
+              <div class="card-content1">
+                <p>积分&nbsp;:&nbsp;{{item.point + ' ' + ptName(item.pt_id)}} <van-tag :type="pointStatusType(item.status)" >{{pointStatusMap[item.status] || '--'}}</van-tag> </p>
+                <p style="line-height: 0.5rem">积分备注&nbsp;:&nbsp;{{item.event_remark}}</p>
+                <p>时间&nbsp;:&nbsp;{{item.event_time}}</p>
+                <p v-if="item.appeal_remark" >申诉原因&nbsp;:&nbsp;{{item.appeal_remark}}</p>
+                <p v-if="item.delete_time" >已删除&nbsp;:&nbsp;{{item.delete_time}}</p>
+              </div>
+            </div>
+          </van-collapse-item>
+          <van-collapse-item name="logs" :disabled="appealInfo.logs.length === 0">
+            <template slot="title">
+              <span class="content-font">{{appealInfo.logs.length + '条操作日志'}}</span>
+            </template>
+            <p v-for="(item,index) in logs" :key="index" class="content-font font-flex-word">
+              <van-notice-bar
+                left-icon="info-o"
+                color="#1989fa"
+                background="#ecf9ff"
+                :text="item.create_time + item.msg"
+              />
+            </p>
+          </van-collapse-item>
+        </van-collapse>
+      </div>
+    </div>
+
+    <van-action-sheet
+      v-model="showActions"
+      :actions="appealActions"
+      @select="actionSelect"
+      :closeable="false"
+      close-on-click-action
+    />
+
+<!--  审批拒绝  -->
+    <van-dialog
+      v-model="showReviewRefuse"
+      title="审批拒绝"
+      :show-cancel-button="false"
+      :show-confirm-button="false"
+    >
+      <van-form @submit="refuseReview">
+        <van-cell-group>
+          <van-cell><Mtextarea v-model="formData.remark" placeholder="原因说明(选填)"></Mtextarea></van-cell>
+        </van-cell-group>
+        <van-row type="flex" justify="center" gutter="10" style="margin: 0.1rem;">
+          <van-col span="12">
+            <van-button round block type="warning" native-type="button" @click="closeRefuseReview">
+              取消
+            </van-button>
+          </van-col>
+          <van-col span="12">
+            <van-button round block type="info" native-type="submit">
+              提交
+            </van-button>
+          </van-col>
+        </van-row>
+      </van-form>
+    </van-dialog>
+
+<!--  驳回重做  -->
+    <van-dialog
+      v-model="showReviewRejectRewrite"
+      title="驳回重做"
+      :show-cancel-button="false"
+      :show-confirm-button="false"
+    >
+      <van-form @submit="rejectRewrite">
+        <van-cell-group>
+          <van-cell><Mtextarea v-model="formData.remark" placeholder="原因说明(选填)"></Mtextarea></van-cell>
+        </van-cell-group>
+
+        <van-row type="flex" justify="center" gutter="10" style="margin: 0.1rem;">
+          <van-col span="12">
+            <van-button round block type="warning" native-type="button" @click="closeRejectRewrite">
+              取消
+            </van-button>
+          </van-col>
+          <van-col span="12">
+            <van-button round block type="info" native-type="submit">
+              提交
+            </van-button>
+          </van-col>
+        </van-row>
+      </van-form>
+    </van-dialog>
+
+
+<!--  递交审批  -->
+    <van-dialog
+      v-model="showReviewSubmit"
+      title="递交审批"
+      :show-cancel-button="false"
+      :show-confirm-button="false"
+    >
+      <van-form @submit="reviewSubmit">
+        <van-cell-group>
+          <EmployeeSelectorCell
+            title="递交审批"
+            v-model="formData.reviewer"
+            :multi="false"
+            icon-type="records"
+            :employee_list="userInfo.employee_detail.superior_list"
+            :is_employee_list="true"
+          />
+        </van-cell-group>
+
+        <van-cell-group>
+          <van-cell><Mtextarea v-model="formData.remark" placeholder="原因说明(选填)"></Mtextarea></van-cell>
+        </van-cell-group>
+
+        <van-row type="flex" justify="center" gutter="10" style="margin: 0.1rem;">
+          <van-col span="12">
+            <van-button round block type="warning" native-type="button" @click="closeReviewSubmit">
+              取消
+            </van-button>
+          </van-col>
+          <van-col span="12">
+            <van-button round block type="info" native-type="submit">
+              提交
+            </van-button>
+          </van-col>
+        </van-row>
+      </van-form>
+    </van-dialog>
+
+<!--  审批通过  -->
+    <van-dialog
+      v-model="showReviewApproval"
+      title="通过"
+      :show-cancel-button="false"
+      :show-confirm-button="false"
+    >
+      <van-form @submit="reviewApproval">
+        <van-cell-group>
+          <van-cell><Mtextarea v-model="formData.remark" placeholder="原因说明(选填)"></Mtextarea></van-cell>
+        </van-cell-group>
+        <van-row type="flex" justify="center" gutter="10" style="margin: 0.1rem;">
+          <van-col span="12">
+            <van-button round block type="warning" native-type="button" @click="closeReviewApproval">
+              取消
+            </van-button>
+          </van-col>
+          <van-col span="12">
+            <van-button round block type="info" native-type="submit">
+              提交
+            </van-button>
+          </van-col>
+        </van-row>
+      </van-form>
+    </van-dialog>
+
+<!--  重新填写  -->
+<!--    <van-dialog-->
+<!--      v-model="showRewrite"-->
+<!--      title="申诉记录"-->
+<!--      :show-cancel-button="false"-->
+<!--      :show-confirm-button="false"-->
+<!--    >-->
+
+<!--    </van-dialog>-->
+    <AppealRewrite
+      v-if="appealInfo"
+      :visible.sync="showRewrite"
+      :id="appealInfo.id"
+      @hasSubmit="handleRewriteSubmit"
+    />
+
+
+  </van-popup>
+</template>
+
+<script>
+import Vue from "vue";
+import {NavBar,Steps,Step,Collapse,CollapseItem,Dialog,NoticeBar} from "vant";
+import EmployeeSelectorCell from "./EmployeeSelectorCell.vue";
+import Mtextarea from "./Mtextarea2.vue";
+import AppealRewrite from "./AppealRewrite.vue";
+Vue.use(NavBar)
+  .use(Steps)
+  .use(Step)
+  .use(Collapse)
+  .use(CollapseItem)
+  .use(Dialog)
+  .use(NoticeBar)
+
+export default {
+  name: 'appealInfo',
+  components: {AppealRewrite, Mtextarea, EmployeeSelectorCell},
+  props: {
+    visible:{
+      type: Boolean,
+      default : false
+    },
+    position:{
+      type: String,
+      default: 'bottom'
+    },
+    id:{
+      type: Number,
+      default: 0
+    },
+    height:{
+      type: String,
+      default: '90%'
+    },
+    width:{
+      type: String,
+      default: '100vw'
+    }
+  },
+  data(){
+    return {
+      userInfo: this.$userInfo(),
+      showAppealInfo:this.visible,
+      hasOpen:false,
+      hasSubmit:false,
+      loading:false,
+      appealInfo:null,
+      appealStatusMap:{
+        0:'全部',
+        1:'审批中',
+        2:'审批通过',
+        3:'驳回重做',
+        4:'撤回重填',
+        5:'拒绝'
+      },
+      pointStatusMap:{
+        1:'正常',
+        2:'已删除',
+        3:'已通过申诉并删除'
+      },
+      processStatusMap:{
+        1:'待处理',
+        2:'审批通过',
+        3:'递交审批',
+        4:'拒绝',
+        5:'驳回重做',
+        6:'撤回上个节点重填',
+        7:'申诉撤回',
+      },
+      pts:this.$getTypes,
+      formData:{
+        remark:'',
+        reviewer:[]
+      },
+      rewriteData:{
+        events:[],
+        globalRemark:'',
+        reviewerId:'',
+        reviewerName:'',
+        employeeSelected: { dept: [], employee: [] },
+      },
+      showReviewRefuse:false,
+      showReviewRejectRewrite:false,
+      showReviewApproval:false,
+      showReviewerSelector:false,
+      showReviewSubmit:false,
+      submitting:false,
+      showEventSelector:false,
+      showRewrite:false,
+      activeNames:'process',
+      showActions:false,
+      actions:{
+        delete:{name:'删除申诉',subname:'删除申诉后将不可恢复',action:'delete',loading:false,disabled:false},
+        refuse:{name:'拒绝',subname:'拒绝申请直接结束申诉流程',action:'refuse',loading:false,disabled:false},
+        rejectRewrite:{name:'驳回重做',subname:'申请人重新填写申诉内容',action:'rejectRewrite',loading:false,disabled:false},
+        cancel:{name:'撤回审批',subname:'撤回重新填写审批信息',action:'cancel',loading:false,disabled:false},
+        cancelAppeal:{name:'撤回申诉',subname:'撤回重新填写申诉内容',action:'cancelAppeal',loading:false,disabled:false},
+        rewrite:{name:'重新填写',subname:'填写申诉内容重新提交',action:'rewrite',loading:false,disabled:false},
+        submit:{name:'递交审批',subname:'递交其他人审批',action:'submit',loading:false,disabled:false},
+        approval:{name:'通过',subname:'通过审批结束申诉流程',action:'approval',loading:false,disabled:false},
+      },
+      logs:[]
+    }
+  },
+  watch:{
+    showAppealInfo(v){
+      this.$emit('update:visible', v)
+    },
+    visible(v){
+      this.showAppealInfo = v
+    }
+  },
+  computed:{
+    appealActions(){
+      let actions = []
+      if (!this.appealInfo) return actions
+      if (this.appealInfo.can_delete) actions.push(this.actions.delete)
+      if (this.appealInfo.can_refuse) actions.push(this.actions.refuse)
+      if (this.appealInfo.can_reject_rewrite) actions.push(this.actions.rejectRewrite)
+      if (this.appealInfo.can_cancel) actions.push(this.actions.cancel)
+      if (this.appealInfo.can_cancel_appeal) actions.push(this.actions.cancelAppeal)
+      if (this.appealInfo.can_rewrite) actions.push(this.actions.rewrite)
+      if (this.appealInfo.can_submit) actions.push(this.actions.submit)
+      if (this.appealInfo.can_approval) actions.push(this.actions.approval)
+      return actions
+    },
+    canActions(){
+      return this.appealActions.length > 0
+    }
+  },
+  methods:{
+    initData(){
+      this.formData.remark = ''
+      this.formData.reviewer = []
+      this.hasSubmit = false
+      this.appealInfo = null
+      this.showReviewRefuse = false
+      this.showReviewRejectRewrite = false
+      this.showReviewApproval = false
+      this.showReviewerSelector = false
+      this.showReviewSubmit = false
+      this.showRewrite = false
+      this.showEventSelector = false
+      this.submitting = false
+    },
+    onOpen(){
+      this.hasOpen = true
+      this.initData()
+      this.getAppealInfo()
+    },
+    onClosed(){
+      this.hasOpen = false
+      this.activeNames = 'process'
+      if (this.hasSubmit) this.$emit('hasSubmit')
+      this.$emit('closeInfo')
+    },
+    getAppealInfo(){
+      if (!this.$props.id) return
+      let self = this
+      self.loading = true
+      self.$axiosUser('get','api/pro/integral/appeal/info',{appeal_id:this.$props.id})
+        .then(res => {
+          if (res.data.code === 1) self.appealInfo = res.data.data
+        })
+        .finally(() => {
+          self.loading = false
+        })
+    },
+    appealStatusType(status){
+      const map = {
+        1:'primary',
+        2:'success',
+        3:'warning',
+        4:'warning',
+        5:'danger'
+      }
+      return map[status] || 'info'
+    },
+    processStatusType(status){
+      const map = {
+        1:'primary',
+        2:'success',
+        3:'success',
+        4:'danger',
+        5:'warning',
+        6:'warning',
+        7:'primary',
+      }
+      return map[status] || 'info'
+    },
+    ptName(ptId){
+      let item = this.pts.find(item => item.id === ptId)
+      return item ? item.name : ''
+    },
+    pointStatusType(status){
+      switch (status){
+        case 2:
+        case 3:
+          return 'warning'
+        default:
+          return "success"
+      }
+    },
+    actionSelect(item){
+      switch (item.action){
+        case 'delete':
+          Dialog.confirm({
+            title:'删除申诉',
+            message:'删除申诉后将不可恢复,确认提交吗',
+            showCancelButton:true,
+            confirmButtonText:'提交',
+            cancelButtonText:'取消',
+          })
+            .then(() => {
+              this.removeAppeal()
+            })
+            .catch(() => {})
+          break;
+        case 'refuse':
+          this.showReviewRefuse = true
+          break;
+        case 'rejectRewrite':
+          this.showReviewRejectRewrite = true
+          break;
+        case 'cancel':
+          Dialog.confirm({
+            title:'撤回审批',
+            message:'审批撤回后可以重新编辑内容重新提交',
+            showCancelButton:true,
+            confirmButtonText:'提交',
+            cancelButtonText:'取消',
+          })
+            .then(() => {
+              this.reviewCancel()
+            })
+            .catch(() => {})
+          break;
+        case 'cancelAppeal':
+          Dialog.confirm({
+            title:'撤回申诉',
+            message:'申诉撤回后可以重新编辑内容重新提交',
+            showCancelButton:true,
+            confirmButtonText:'提交',
+            cancelButtonText:'取消',
+          })
+            .then(() => {
+              this.appealCancel()
+            })
+            .catch(() => {})
+          break;
+        case 'rewrite':
+          this.showRewrite = true
+          break;
+        case 'submit':
+          this.showReviewSubmit = true
+          break;
+        case 'approval':
+          this.showReviewApproval = true
+          break;
+      }
+    },
+    removeAppeal(){
+      if (!this.appealInfo) return
+      let self = this
+      self.submitting = true
+      let params = {
+        appeal_id:self.appealInfo.id
+      }
+      self.$axiosUser('post','api/pro/integral/appeal/remove',params)
+        .then(res => {
+          if (res.data.code === 1){
+            self.hasSubmit = true
+            self.showAppealInfo = false
+          }else {
+            self.$toast(res.data.msg)
+          }
+        })
+        .finally(() => {
+          self.submitting = false
+        })
+    },
+    refuseReview(){
+      if (!this.appealInfo) return
+      let self = this
+      self.submitting = true
+      let params = {
+        appeal_id:self.appealInfo.id,
+        remark:self.formData.remark
+      }
+      self.$axiosUser('post','api/pro/integral/appeal/review/refuse',params)
+        .then(res => {
+          if (res.data.code === 1){
+            self.hasSubmit = true
+            self.getAppealInfo()
+            self.showReviewRefuse = false
+          }else {
+            self.$toast(res.data.msg)
+          }
+        })
+        .finally(() => {
+          self.submitting = false
+        })
+    },
+    closeRefuseReview(){
+      this.showReviewRefuse = false
+    },
+    rejectRewrite(){
+      if (!this.appealInfo) return
+      let self = this
+      self.submitting = true
+      let params = {
+        appeal_id:self.appealInfo.id,
+        remark:self.formData.remark
+      }
+      self.$axiosUser('post','api/pro/integral/appeal/review/reject',params)
+        .then(res => {
+          if (res.data.code === 1){
+            self.hasSubmit = true
+            self.getAppealInfo()
+            self.showReviewRejectRewrite = false
+          }else {
+            self.$toast(res.data.msg)
+          }
+        })
+        .finally(() => {
+          self.submitting = false
+        })
+    },
+    closeRejectRewrite(){
+      this.showReviewRejectRewrite = false
+    },
+    reviewSubmit(){
+      if (!this.appealInfo) return
+      let self = this
+      self.submitting = true
+      let params = {
+        appeal_id:self.appealInfo.id,
+        reviewer_id:self.formData.reviewer[0].id,
+        remark:self.formData.remark
+      }
+      self.$axiosUser('post','api/pro/integral/appeal/review/submit',params)
+        .then(res => {
+          if (res.data.code === 1){
+            self.hasSubmit = true
+            self.getAppealInfo()
+            self.showReviewSubmit = false
+          }else {
+            self.$message.error(res.data.msg)
+          }
+        })
+        .finally(() => {
+          self.submitting = false
+        })
+    },
+    closeReviewSubmit(){
+      this.showReviewSubmit = false
+    },
+    reviewApproval(){
+      if (!this.appealInfo) return
+      let self = this
+      self.submitting = true
+      let params = {
+        appeal_id:self.appealInfo.id,
+        remark:self.formData.remark
+      }
+      self.$axiosUser('post','api/pro/integral/appeal/review/approval',params)
+        .then(res => {
+          if (res.data.code === 1){
+            self.hasSubmit = true
+            self.getAppealInfo()
+            self.showReviewApproval = false
+          }else {
+            self.$toast(res.data.msg)
+          }
+        })
+        .finally(() => {
+          self.submitting = false
+        })
+    },
+    closeReviewApproval(){
+      this.showReviewApproval = false
+    },
+    reviewCancel(){
+      if (!this.appealInfo) return
+      this.submitting = true
+      let self = this
+      self.$axiosUser('post','api/pro/integral/appeal/review/cancel',{appeal_id:self.appealInfo.id})
+        .then(res => {
+          if (res.data.code === 1){
+            self.hasSubmit = true
+            self.getAppealInfo()
+          }else {
+            self.$toast(res.data.msg)
+          }
+        })
+        .finally(() => {
+          self.submitting = false
+        })
+    },
+    appealCancel(){
+      if (!this.appealInfo) return
+      this.submitting = true
+      let self = this
+      self.$axiosUser('post','api/pro/integral/appeal/cancel',{appeal_id:self.appealInfo.id})
+        .then(res => {
+          if (res.data.code === 1){
+            self.hasSubmit = true
+            self.getAppealInfo()
+          }else {
+            self.$toast(res.data.msg)
+          }
+        })
+        .finally(() => {
+          self.submitting = false
+        })
+    },
+    handleRewriteSubmit(){
+      this.hasSubmit = true
+      this.getAppealInfo()
+    },
+    collapseChange(activeName){
+      if (activeName === 'logs'){
+        this.logs = this.appealInfo.logs
+      }else {
+        this.logs = []
+      }
+    }
+  },
+}
+</script>
+
+
+<style scoped lang="less">
+/deep/ .van-nav-bar--fixed{
+  position: fixed;
+  top: 10%;
+  left: 0;
+  width: 100%;
+}
+.container {
+  position: relative;
+  width: 100%;
+  margin-top: 15%;
+
+  & .card-box{
+    margin: 0.2rem;
+    padding: 0.1rem;
+    border-radius: 0.3rem;
+    border: 1px solid #ebeef5;
+    background-color: #ffffff;
+    overflow: hidden;
+    color: #303133;
+    text-align: center;
+    box-shadow: 0 2px 12px 0 rgba(0,0,0,0.1);
+
+    & .card-content{
+      font-size: 0.25rem;
+      line-height: 0.5rem;
+      color: #909399;
+      text-align: left;
+      margin-left: 0.3rem;
+    }
+
+    & .card-content1{
+      font-size: 0.25rem;
+      line-height: 0.25rem;
+      color: #909399;
+      text-align: left;
+
+    }
+
+  }
+
+  .content-font{
+    font-size: 0.25rem;
+    line-height: 0.25rem;
+    color: #909399;
+    text-align: left;
+  }
+
+}
+
+</style>

+ 253 - 0
src/components/AppealRewrite.vue

@@ -0,0 +1,253 @@
+<template>
+  <van-popup
+    v-model="showAppealRewrite"
+    position="bottom"
+    duration="0.2"
+    :style="{height: '90%', width:'100vw','background-color': 'rgb(245, 245, 245)'}"
+    @open="onOpen"
+    @closed="onClosed"
+  >
+    <van-nav-bar
+      title="申诉重写"
+      :left-arrow="true"
+      @click-left="showAppealRewrite = false"
+      @click-right="showActions = true"
+    >
+      <template slot="right" v-if="canActions">
+        <van-icon name="bars"/>
+      </template>
+    </van-nav-bar>
+
+    <div :style="{marginTop:'0.1rem',height:'90%'}">
+      <van-notice-bar
+        left-icon="volume-o"
+        text="手机端暂不支持添加积分事件,请在电脑端操作"
+      />
+      <van-form>
+        <van-cell-group>
+          <EmployeeSelectorCell
+            title="递交审批"
+            v-model="rewriteData.reviewer"
+            :multi="false"
+            icon-type="records"
+            :employee_list="userInfo.employee_detail.superior_list"
+            :is_employee_list="true"
+          />
+        </van-cell-group>
+        <van-cell-group>
+          <van-cell>
+            <Mtextarea v-model="rewriteData.globalRemark" :text_max="100" placeholder="申诉原因"/>
+          </van-cell>
+        </van-cell-group>
+        <div class="card-box">
+          <div class="box-header">
+            <span v-if="rewriteData.events.length > 0">共{{rewriteData.events.length}}条积分事件</span>
+            <span v-else>暂无积分事件</span>
+          </div>
+          <van-divider/>
+          <div class="box-content">
+            <div v-for="(item,index) in rewriteData.events" :key="index" class="box-content-item">
+              <div class="box-content-item-title">
+                <van-tag type="primary" size="medium" closeable @close="deleteEvent(item)" >{{item.remark}}</van-tag>
+              </div>
+              <div class="box-content-item-content">
+                <Mtextarea :text_max="100" placeholder="申诉原因" v-model="item.appeal_remark"/>
+              </div>
+            </div>
+          </div>
+        </div>
+      </van-form>
+    </div>
+
+
+    <van-action-sheet
+      v-model="showActions"
+      :actions="[actionRewrite]"
+      @select="actionSelect"
+      close-on-click-action
+    />
+
+  </van-popup>
+</template>
+
+<script>
+import Vue from "vue";
+import {NoticeBar} from "vant";
+Vue.use(NoticeBar)
+
+import EmployeeSelectorCell from "./EmployeeSelectorCell.vue";
+import Mtextarea from "./Mtextarea2.vue";
+export default {
+  name: "AppealRewrite",
+  components:{Mtextarea,EmployeeSelectorCell},
+  props:{
+    visible:{
+      type: Boolean,
+      default : false
+    },
+    id:{
+      type: Number,
+      default: 0
+    },
+  },
+  data(){
+    return {
+      userInfo:this.$userInfo(),
+      hasOpen:false,
+      showAppealRewrite:false,
+      showActions:false,
+      hasSubmit: false,
+      pts:this.$getTypes,
+      appealInfo:null,
+      rewriteData:{
+        events:[],
+        globalRemark:'',
+        reviewer:[]
+      },
+      loading:false,
+      actionRewrite:{name:'提交',subname:'提交申诉进入审批流程',action:'rewrite',loading:false,disabled:false},
+      submitting:false,
+    }
+  },
+  watch:{
+    showAppealRewrite(v){
+      this.$emit('update:visible',v)
+    },
+    visible(v){
+      this.showAppealRewrite = v
+    }
+  },
+  computed:{
+    canActions(){
+      return this.appealInfo && this.appealInfo.can_rewrite && this.rewriteData.reviewer.length === 1 && this.rewriteData.events.length >= 1 && !this.submitting
+    }
+  },
+  methods:{
+    onOpen(){
+      this.hasOpen = true
+      this.getAppealInfo()
+    },
+    onClosed(){
+      this.hasOpen = false
+      if (this.hasSubmit) this.$emit('hasSubmit')
+    },
+    initRewriteData(){
+      if (!this.appealInfo) return
+      this.rewriteData.events = this.appealInfo.events.map(event => {
+        let pt = this.pts.find(item => item.id === event.pt_id)
+        pt = pt ? pt.name : ''
+        return {
+          id:event.id,
+          remark:`${event.point} ${pt} ${event.event_time} ${event.event_remark}`,
+          appeal_remark:event.appeal_remark
+        }
+      })
+      this.rewriteData.globalRemark = this.appealInfo.global_remark
+      let node = this.appealInfo.process.find(item => item.step === 1)
+      if (node){
+        this.rewriteData.reviewer = []
+        this.rewriteData.reviewer.push({id: node.reviewer_id,name: node.reviewer_name,img_url:node.reviewer_img_url})
+      }
+
+    },
+    getAppealInfo(){
+      if (!this.id) return
+      let self = this
+      self.loading = true
+      self.$axiosUser('get','api/pro/integral/appeal/info',{appeal_id:this.id})
+        .then((res) => {
+          if (res.data.code === 1){
+            self.appealInfo = res.data.data
+            self.initRewriteData()
+          }
+        })
+        .finally(() => {
+          self.loading = false
+        })
+    },
+    deleteEvent(event){
+      let index = this.rewriteData.events.indexOf(event)
+      if (index >= 0) this.rewriteData.events.splice(index,1)
+    },
+    actionSelect(action){
+      if (action.action === 'rewrite') this.rewriteAppeal()
+
+    },
+    rewriteAppeal(){
+      let self = this
+      if (!self.canActions) return
+
+      let params = {
+        appeal_id:self.appealInfo.id,
+        reviewer_id:self.rewriteData.reviewer[0].id,
+        remark:self.rewriteData.globalRemark,
+        events:self.rewriteData.events.map(item => {
+          return {id:item.id,remark:item.appeal_remark}
+        })
+      }
+
+
+      self.submitting = true
+      self.$toast.loading({ message: '正在处理',overlay:true,duration:0})
+      self.$axiosUser('post','api/pro/integral/appeal/rewrite',params)
+        .then(res => {
+          if (res.data.code === 1){
+            self.hasSubmit = true
+            self.showAppealRewrite = false
+          }
+          self.$toast(res.data.msg)
+          self.$toast.clear()
+        })
+        .catch(e => {
+          self.$toast.clear()
+        })
+        .finally(() => {
+          self.submitting = false
+        })
+    }
+  }
+}
+</script>
+
+<style scoped lang="less">
+.van-nav-bar--fixed{}
+.card-box{
+  margin: 0.2rem auto;
+  border-radius: 0.3rem;
+  border: 1px solid #ebeef5;
+  background-color: #ffffff;
+  overflow: hidden;
+  color: #303133;
+  text-align: center;
+  min-height: 70%;
+  width: 95%;
+  box-shadow: 0 2px 12px 0 rgba(0,0,0,0.1);
+
+  & .box-header{
+    height: 0.5rem;
+    line-height: 0.5rem;
+  }
+
+  & .box-content{
+    margin-bottom: 1rem;
+
+    & .box-content-item{
+      width: 95%;
+      margin: 0.3rem auto 0;
+
+      & .box-content-item-title{
+         padding: 0 0.3rem;
+      }
+
+      & .box-content-item-content{
+        padding: 0 0.3rem;
+        margin-top: 0.2rem;
+        border: 0.02rem solid #ebeef5;
+      }
+
+
+    }
+  }
+
+}
+</style>

+ 5 - 0
src/components/CategorySelectorCell.vue

@@ -45,6 +45,7 @@
       :visible.sync="show_dept_selector"
       :selected.sync="selected_data"
       :cycle_type="cycle_type"
+      :scope="scope"
     ></RuleCategorySelector>
   </van-cell>
 </template>
@@ -111,6 +112,10 @@ export default {
       type: Number,
       default: 0
     },
+    scope:{
+      type: Boolean,
+      default: false
+    }
   },
   watch: {
     selected(val) {

+ 10 - 2
src/components/DeptSelectorBtn.vue

@@ -1,8 +1,8 @@
 <template>
-  <van-button @click="show_dept_selector = true">
+  <van-button @click="show_dept_selector = true" :block="block" >
     <template v-if="selected_data.dept.length > 0">
       {{ selected_data.dept[0].dept_name }}
-      <van-icon name="arrow-down" />
+      <van-icon name="close" @click.stop="clearDept"/>
     </template>
     <template v-if="selected_data.dept.length == 0">
       {{ title }}
@@ -55,6 +55,10 @@ export default {
     max: {
       type: Number,
       default: 0
+    },
+    block:{
+      type: Boolean,
+      default: false
     }
   },
   watch: {
@@ -74,6 +78,10 @@ export default {
   methods: {
     confirm(data) {
       this.$emit('value', data.dept);
+    },
+    clearDept(){
+      this.selected_data = { dept: [], employee: [] };
+      this.$emit('value',this.selected_data.dept)
     }
   },
   created() {

+ 1 - 1
src/components/EmployeeSelector.vue

@@ -475,7 +475,7 @@ export default {
            return false
         }
       }
-      console.log(this.dept_selected_list)
+      // console.log(this.dept_selected_list)
       this.$emit('confirm', {
         employee: this.employee_selected_list,
         dept: this.dept_selected_list

+ 30 - 0
src/components/IntegralEventSelector.vue

@@ -0,0 +1,30 @@
+<template>
+
+</template>
+
+<script>
+export default {
+  name: "IntegralEventSelector",
+  props:{
+    visible:{
+      type: Boolean,
+      default:false
+    },
+    eid:{
+      type: Number,
+      default:0
+    },
+    selected:{
+      type: Array,
+      default: () => []
+    },
+    max:{
+      type: Number,
+      default: 100
+    }
+  }
+}
+</script>
+<style scoped lang="less">
+
+</style>

+ 6 - 2
src/components/Mtextarea.vue

@@ -15,7 +15,7 @@
 
       <div v-else style="position: relative;min-height: 1.6rem;margin: 0.16rem;">
         <div v-html="s_text"></div>
-        <textarea :placeholder="placeholder" v-model="text" class="diy_text"></textarea>
+        <textarea :placeholder="placeholder" v-model="text" class="diy_text" @input="onTextInput"></textarea>
       </div>
       <div style="height: 0.3rem;"></div>
       <span v-show="text_max != ''" class="text-max-tip">{{ text.length }}/{{ text_max }}</span>
@@ -28,6 +28,7 @@
 
 <script>
 import Uploader from '@/components/OssUploader';
+import {specialFilter} from "../utils/helper";
 
 export default {
   name: 'Mtextarea',
@@ -115,7 +116,7 @@ export default {
     }
   },
   created() {
-    this.text = this.value;
+    this.text = specialFilter(this.value);
     this.s_imgs = this.imgs;
   },
   methods: {
@@ -131,6 +132,9 @@ export default {
       // }
       return isJPG;
     },
+    onTextInput(e){
+      this.text = specialFilter(e.target.value)
+    }
   }
 };
 </script>

+ 7 - 3
src/components/Mtextarea2.vue

@@ -15,7 +15,7 @@
       </div>
       <div v-else>
         <div v-html="s_text"></div>
-        <textarea :placeholder="placeholder" v-model="text" class="diy_text"></textarea>
+        <textarea :placeholder="placeholder" v-model="text" class="diy_text" @input="onTextInput"></textarea>
       </div>
     </div>
     <div v-show="imgs.length > 0" style="padding:0.24rem;" class="upload_box">
@@ -37,6 +37,7 @@
 
 <script>
 import Uploader from '@/components/OssUploader'
+import {specialFilter} from "../utils/helper";
 
 export default {
   name: 'Mtextarea',
@@ -124,10 +125,13 @@ export default {
     }
   },
   created () {
-    this.text = this.value
+    this.text = specialFilter(this.value)
     this.s_imgs = this.imgs
   },
   methods: {
+    onTextInput(e){
+      this.text = specialFilter(e.target.value)
+    },
     // 返回布尔值
     beforeRead(file) {
       const isJPG = /^image\/(jpeg|png|jpg)$/.test(file.type);
@@ -256,4 +260,4 @@ export default {
 .mtext-box {
   position: relative;
 }
-</style>
+</style>

+ 1 - 1
src/components/NumberInput.vue

@@ -166,7 +166,7 @@ export default {
   },
   methods: {
     setCurrentValue(value) {
-      console.log('value:'+value,this.numVal)
+      // console.log('value:'+value,this.numVal)
       if(value===''){
         return false
       }

+ 79 - 3
src/components/RuleCategorySelector.vue

@@ -7,7 +7,7 @@
       <a v-for="(item, index) in pid_list_arr" :key="index" href="javascript:void(0);" @click="back_by_index(index + 1)"> <van-icon name="arrow" /> {{item.name}}</a>
     </div>
     <div class="body_com" :class="{show_dept_path:pid_list_arr.length > 0}">
-      <scroller :on-refresh="get_category_list">
+      <scroller :on-refresh="tt">
         <van-cell-group>
         <van-cell :is-link="!can_select_category" v-for="(item,index) in category_list" :key="index" :title="item.name" v-show="item.pid == pid && item.name.indexOf(keyword) >= 0 && category_not_select.indexOf(item.id) < 0" class="employee_cell" @click="select_dept(item)">
           <template slot="icon">
@@ -115,6 +115,10 @@ export default {
       type: Number,
       default: 0
     },
+    scope:{
+      type: Boolean,
+      default: false
+    }
   },
   name: 'RuleCategorySelector',
   data () {
@@ -379,7 +383,72 @@ export default {
         this.parse_tree(trees[i].child, rule_id)
       }
     },
+    getRuleScope(done){
+      let data = {
+        cycle_type:this.cycle_type,
+        pt_id:this.ptId
+      }
+      this.$axiosUser('get','/api/pro/integral/rule/trees/scope',data)
+        .then((res)=>{
+          this.category_list = []
+          this.item_list = res.data.data.item_list
+          let ruleSet = new Set(res.data.data.rule_tree.map(item => item.id))
+          this.rule_tree = res.data.data.rule_tree.map(item => {
+            let rule = {...item}
+            rule.pid = ruleSet.has(item.pid) ? item.pid : 0
+            return rule
+          })
+
+          // this.rule_tree = res.data.data.rule_tree
+          this.parse_tree(this.rule_tree, this.pid)
+          for (let i in this.category_list) {
+            this.category_list[i]['checked'] = false
+            if (this.category_selected.indexOf(this.category_list[i].id) >= 0) {
+              this.category_list[i]['checked'] = true
+              if (this.cate_multi == false) {
+                this.parse_tree(this.rule_tree, this.category_list[i].id)
+              }
+              this.$emit('get_items', this.cur_item_list)
+              this.category_list = []
+              this.parse_tree(res.data.data.rule_tree, this.pid)
+            }
+          }
+
+          if (this.pid == 0) {
+            this.list = []
+            for (let i in this.item_list) {
+              for (let k in this.item_list[i]) {
+                this.list.push(this.item_list[i][k])
+              }
+            }
+          } else {
+            this.list = this.cur_item_list
+          }
+          for (let i in this.list) {
+            this.list[i]['checked'] = false
+            if (this.rule_selected.indexOf(this.list[i].id) >= 0) {
+              this.list[i]['checked'] = true
+            }
+          }
+
+          done()
+          this.$toast.clear()
+        })
+        .catch(e => {
+          done()
+          this.$toast.clear()
+        })
+    },
+    tt(done){
+      this.get_category_list(done)
+    },
     get_category_list (done) {
+      //根据可见范围查询分类树
+      if (this.scope){
+        this.getRuleScope(done)
+        return
+      }
+
       this.category_list = []
       let params = {
         cycle_type:this.cycle_type
@@ -393,7 +462,14 @@ export default {
       this.$axiosUser('get', '/api/pro/integral/rule/trees', params).then((res) => {
         this.category_list = []
         this.item_list = res.data.data.item_list
-        this.rule_tree = res.data.data.rule_tree
+        let ruleSet = new Set(res.data.data.rule_tree.map(item => item.id))
+        this.rule_tree = res.data.data.rule_tree.map(item => {
+          let rule = {...item}
+          rule.pid = ruleSet.has(item.pid) ? item.pid : 0
+          return rule
+        })
+
+        // this.rule_tree = res.data.data.rule_tree
         this.parse_tree(res.data.data.rule_tree, this.pid)
         for (let i in this.category_list) {
           this.category_list[i]['checked'] = false
@@ -465,7 +541,7 @@ export default {
     this.deptIds = this.$userInfo().employee_detail.dept_list.map(item => {
       return item.dept_id
     })
-    this.get_category_list(function () {})
+    // this.get_category_list(function () {})
     this.get_point_types()
     this.$nextTick(() => {
       if (this.append_body) {

+ 44 - 5
src/components/RuleCategorySelector1.vue

@@ -5,7 +5,15 @@
     <div class="body_com">
       <scroller style="right:5.5rem;width:2rem;" class="selector-left _v-container">
         <van-collapse v-model="left_active" accordion>
-          <van-collapse-item :is-link="false" :name="item.id" v-for="(item,index) in category_list" :key="index" :title="item.name" v-show="item.pid == 0" :class="{on: left_active, no_child: item.child.length == 0}">
+          <van-collapse-item
+            :is-link="false"
+            :name="item.id"
+            v-for="(item,index) in category_list"
+            :key="index"
+            :title="item.name"
+            v-show="item.pid === 0"
+            :class="{on: left_active, no_child: item.child.length === 0}"
+          >
             <template v-if="item.child.length > 0">
               <div v-for="(child_item,child_index) in item.child" :key="child_index" @click.stop="show_child(child_item)" style="padding: 0.16rem 0;border-bottom: 1px solid #f1f1f1;">
                 <span :class="{blue: pid == child_item.id}">{{child_item.name}}</span>
@@ -104,6 +112,10 @@ export default {
       type: Number,
       default: 1
     },
+    scope:{
+      type: Boolean,
+      default: false
+    }
   },
   name: 'RuleCategorySelector',
   data () {
@@ -340,7 +352,24 @@ export default {
         this.parse_tree(trees[i].child, rule_id)
       }
     },
-
+    getRuleScope(){
+      let data = {
+        cycle_type:this.cycle_type,
+        pt_id:this.ptId
+      }
+      this.$axiosUser('get','/api/pro/integral/rule/trees/scope',data)
+        .then((res)=>{
+          this.category_list = []
+          // this.rule_tree = res.data.data.rule_tree
+          let ruleSet = new Set(res.data.data.rule_tree.map(item => item.id))
+          this.rule_tree = res.data.data.rule_tree.map(item => {
+            let rule = {...item}
+            rule.pid = ruleSet.has(item.pid) ? item.pid : 0
+            return rule
+          })
+          this.parse_tree(this.rule_tree, this.pid)
+        })
+    },
     get_category_list () {
       let params = {}
       if(this.ptId){ //指定分类
@@ -352,8 +381,14 @@ export default {
       params['cycle_type'] = this.cycle_type
       this.$axiosUser('get', '/api/pro/integral/rule/trees', params).then((res) => {
         this.category_list = []
-        this.rule_tree = res.data.data.rule_tree
-        this.parse_tree(res.data.data.rule_tree, this.pid)
+        // this.rule_tree = res.data.data.rule_tree
+        let ruleSet = new Set(this.rule_tree.map(item => item.id))
+        this.rule_tree = res.data.data.rule_tree.map(item => {
+          let rule = {...item}
+          rule.pid = ruleSet.has(item.pid) ? item.pid : 0
+          return rule
+        })
+        this.parse_tree(this.rule_tree, this.pid)
       })
     },
   },
@@ -364,7 +399,11 @@ export default {
     if (document.documentElement.style.height) {
       this.com_height = document.documentElement.style.height
     }
-    this.get_category_list();
+    if (this.scope){
+      this.getRuleScope()
+    }else {
+      this.get_category_list();
+    }
   }
 }
 </script>

+ 17 - 9
src/components/RuleCategorySelectorCell1.vue

@@ -3,7 +3,6 @@
     class="employee_cell"
     :title="title"
     :value="value"
-    :label="label"
     :icon="icon"
     :url="url"
     :border="border"
@@ -19,19 +18,24 @@
         选择了{{selected_data.rule.length}}条规则
       </div>
     </template>
+    <template slot="label">
+      <slot name="label">{{label}}</slot>
+    </template>
 
     <RuleCategorySelector1
-    :ptId="ptId"
-    :multi.sync="multi"
-    :max="max"
-    :close_clear_data="false"
-     ref="selector"
-     @confirm="confirm"
-    :can_select_category="false"
+      :scope="scope"
+      :ptId="ptId"
+      :multi.sync="multi"
+      :max="max"
+      :close_clear_data="false"
+      ref="selector"
+      @confirm="confirm"
+      :can_select_category="false"
      :visible.sync="show_dept_selector"
      :selected.sync="selected_data"
      :append_body="true"
-     :cycle_type="cycle_type">
+     :cycle_type="cycle_type"
+    >
      <template slot="append">
       <slot name="append"></slot>
     </template></RuleCategorySelector1>
@@ -108,6 +112,10 @@ export default {
     activeIndex: {
       type: Number
     },
+    scope:{
+      type: Boolean,
+      default:false,
+    }
   },
   watch: {
     selected (val) {

+ 5 - 5
src/components/TabsList.vue

@@ -11,13 +11,13 @@
       </van-tabs>
       <div class="list-search__bar">
         <span class="list-filter__btn" v-if="showToolBar" @click="onFilterIconClick">
-          <icon name="tab_filter" width="0.4rem" height="0.4rem"></icon>
+          <icon name="tab_filter" width="0.4rem" height="0.4rem" class="van-hairline--left"></icon>
         </span>
         <span class="list-filter__btn" v-else @click="tips">
           <icon name="tab_filter" width="0.4rem" height="0.4rem"></icon>
         </span>
       </div>
-      
+
     </div>
     <div class="tab-list__content">
       <scroller
@@ -43,7 +43,7 @@
         <van-loading v-if="loding" type="spinner" />
       </scroller>
     </div>
-    
+
     <div ref="popupContainer"  class="popup-container"  :style="popupContainerStyle"  v-show="showPopupContainer">
       <van-popup
         v-model="popupSearchBar"
@@ -60,7 +60,7 @@
         </div>
       </van-popup>
     </div>
-    
+
   </div>
 </template>
 <script>
@@ -96,7 +96,7 @@ export default {
       this.tabsOption.forEach(o => activeTabSatus[o.value] = 1)
     }
 
-    return {
+    return  {
       loding: false,
       activeTab: activeTab,
       activeTabName: activeTabName,

+ 1 - 1
src/components/user_image.vue

@@ -119,7 +119,7 @@
   }
   .user_name_div{
     position: absolute;
-    z-index: 1;
+    //z-index: 1;
     text-align: center;
     color: #fff;
   }

+ 2 - 2
src/okr/view/task/taskDetail.vue

@@ -501,7 +501,7 @@
     <!-- 审批拒绝 -->
     <van-dialog v-model="isShowError" title="审批拒绝" class="reject_popup" show-cancel-button :beforeClose="save_btn">
       <van-cell-group>
-        <van-field v-model="errorContent" rows="2" autosize type="textarea" maxlength="50" placeholder="请输入拒绝理由" show-word-limit v-validate="'required'" name="拒绝理由" />
+        <van-field v-model="errorContent" rows="2" autosize type="textarea" maxlength="50" placeholder="原因说明" show-word-limit v-validate="'required'" name="原因说明" />
       </van-cell-group>
     </van-dialog>
 
@@ -1294,7 +1294,7 @@ export default {
     save_btn(action, done) {
       if (action == 'confirm') {
         if(!this.errorContent){
-          this.$toast('请输入拒绝理由');
+          this.$toast('请填写原因说明');
           done();
           return false;
         }

+ 22 - 14
src/point/view/audit/integralAudit.vue

@@ -61,17 +61,17 @@
        <template v-if="detail_data.item_id && detail_data.rule_id">
           <van-cell-group>
              <NumberInput
-               v-show="detail_data.pid == 0"
+               v-show="isFirstStep"
                title="积分"
                :min="data.item_min_point"
                :max="data.item_max_point"
-               :isForbidSet="detail_data.pid? true:false"
+               :isForbidSet="!isFirstStep"
                required
                v-model="data.point"
                name="积分"
                v-validate="'required'"
              ></NumberInput>
-             <div class="flex-box flex-v-ce jf" v-show="detail_data.item_range_type == 2 && detail_data.pid != 0">
+             <div class="flex-box flex-v-ce jf" v-show="detail_data.item_range_type == 2 && isFirstStep">
                <div>积分</div>
                <div>
                  <span class="red" v-if="data.point > 0">+{{ data.point }}</span>
@@ -86,25 +86,25 @@
          <NumberInput title="积分"
            :min="data.item_min_point"
            :max="data.item_max_point"
-           :isForbidSet="detail_data.pid? true:false"
+           :isForbidSet="!isFirstStep"
            required v-model="data.point"
            name="积分"
            v-validate="'required'">
          </NumberInput>
-        </van-cell-group>
+       </van-cell-group>
 
 
         <van-cell-group>
           <div class="tip" slot="title">奖票多用于优秀表现和重要事项的表彰</div>
           <van-cell center title="发放奖票">
             <template #right-icon>
-              <van-switch v-model="ticket_count" size="24" />
+              <van-switch v-model="ticket_count" size="24" :disabled="!isFirstStep" />
             </template>
           </van-cell>
         </van-cell-group>
 
         <DateCell
-          v-if="(detail_data.source_type == 2 || detail_data.source_type == 3) && detail_data.pid == 0"
+          v-if="(detail_data.source_type == 2 || detail_data.source_type == 3) && isFirstStep"
           title="发生时间"
           v-model="data.event_time"
           :defaultVal="data.event_default"
@@ -113,7 +113,7 @@
 
         <van-cell-group v-if="!isCreator">
           <EmployeeSelectorCell
-            title="递交审批"
+            title="审批"
             v-model="reviewer"
             :multi="false"
             iconType="records"
@@ -191,6 +191,11 @@ export default {
       maxDate: new Date()
     };
   },
+  computed:{
+    isFirstStep(){
+      return this.detail_data && ((this.detail_data.pid === 0 && this.detail_data.step === 0 || this.detail_data.step === 1))
+    },
+  },
   watch: {
     select_cate(val) {
       this.item_list = [];
@@ -294,6 +299,8 @@ export default {
           let obj=res.data.data
           this.data.item_id = obj.item_id;
           this.data.point = obj.point;
+          this.data.ticket_count = obj.ticket_count;
+          this.ticket_count = !!obj.ticket_count;
           if(obj.item_id){
             this.data.item_min_point = obj.item_min_point;
             this.data.item_max_point = obj.item_max_point;
@@ -383,12 +390,13 @@ export default {
           // 20200731
           /** 在 ruleLimitCheck 为0的时候, 超出积分权限都要选择审批人提交 */
           this.validateRuleLimit(items, callback, a => {
-            return !(
-              (a.reviewer_id && a.point !== 0 && a.rule_id > 0) ||
-              (a.reviewer_id <= 0 && a.item_id > 0 && ruleLimitCheck && a.point !== 0 && a.point <= maxPointPermission && Math.abs(a.point) <= maxPointPermission) ||
-              (a.reviewer_id <= 0 && !ruleLimitCheck && this.pointTypeId == 3 && a.rule_id > 0) ||
-              (a.reviewer_id <= 0 && a.item_id >= 0 && a.point !== 0 && a.point <= maxPointPermission && Math.abs(a.point) <= maxPointPermission && a.rule_id > 0)
-            );
+            return false   //统一不验证拦截,乱七八糟。后端会有拦截提示
+            // return !(
+            //   (a.reviewer_id && a.point !== 0 && a.rule_id > 0) ||
+            //   (a.reviewer_id <= 0 && a.item_id > 0 && ruleLimitCheck && a.point !== 0 && a.point <= maxPointPermission && Math.abs(a.point) <= maxPointPermission) ||
+            //   (a.reviewer_id <= 0 && !ruleLimitCheck && this.pointTypeId == 3 && a.rule_id > 0) ||
+            //   (a.reviewer_id <= 0 && a.item_id >= 0 && a.point !== 0 && a.point <= maxPointPermission && Math.abs(a.point) <= maxPointPermission && a.rule_id > 0)
+            // );
           });
 
           // /** 在 ruleLimitCheck 为0的时候, 超出积分权限都要选择审批人提交 */

+ 365 - 0
src/point/view/integral/appealList.vue

@@ -0,0 +1,365 @@
+<template>
+  <div>
+    <van-nav-bar title="申诉记录" left-text="返回" @click-left="$route_back" left-arrow >
+      <template slot="right" v-if="currentTab === 'my'">
+        <van-dropdown-menu>
+          <van-dropdown-item v-model="searchForm.status" :options="appealStatus" />
+        </van-dropdown-menu>
+      </template>
+    </van-nav-bar>
+    <van-notice-bar
+      left-icon="volume-o"
+      text="手机端到积分事件页面选择个人积分发起申诉,一旦审批,积分将自动删除"
+    />
+    <van-tabs
+      v-model="currentTab"
+      :border="false"
+      title-active-color="#26A2FF"
+      color="#FFFFFF"
+    >
+      <van-tab v-for="item in tabs" :key="item.name" :title="item.title" :name="item.name" />
+    </van-tabs>
+    <div class="content-list">
+      <scroller
+        ref="scroller"
+        :on-refresh="onRefresh"
+        :on-infinite="onInfinite"
+        no-data-text="我也是有底线的"
+        :list="list"
+      >
+        <van-cell v-for="item in list" :key="item.id" @click="openDetail(item.id)" >
+          <template slot="title">
+            <van-row>
+              <van-col span="4">
+                <div style="width: 100%; text-align: center;">
+                  <userImage
+                    :img_url="item.employee_img_url"
+                    :user_name="item.employee_name"
+                  />
+                </div>
+              </van-col>
+              <van-col span="6" class="font-flex-word" style="text-align: center">
+                <span style="font-size: 0.35rem;line-height: 0.8rem">
+                  {{item.employee_name}}
+                </span>
+              </van-col>
+              <van-col span="14" class="font-flex-word" >
+                <span style="font-size: 0.35rem;line-height: 0.8rem">
+                  提交了
+                  <van-tag type="primary" round size="medium">{{item.event_count <= 1000 ? item.event_count : '1000+'}}</van-tag>
+                  条积分申诉
+                </span>
+              </van-col>
+            </van-row>
+            <van-row  type="flex" justify="end">
+              <van-col span="8" style="text-align: center;">
+                <span style="font-size: 0.3rem;line-height: 0.8rem; " class="input-ccc">{{item.create_time}}</span>
+              </van-col>
+              <van-col span="8" style="text-align: center;line-height: 0.8rem">
+                <van-tag :type="statusType(item.status)" size="medium" mark>{{appealStatusMap[item.status] || ''}}</van-tag>
+              </van-col>
+            </van-row>
+          </template>
+        </van-cell>
+        <NoData :list="list"/>
+      </scroller>
+    </div>
+
+    <AppealInfo
+      :visible.sync="showAppealInfo"
+      :id="appealId"
+      @closeInfo="closeDetail"
+      @hasSubmit="refresh"
+    />
+  </div>
+</template>
+
+<script>
+import Vue from "vue";
+import {DropdownMenu,DropdownItem,Card,NoticeBar} from "vant";
+import AppealInfo from "@/components/AppealInfo.vue";
+import NoData from "../../../components/noData.vue";
+Vue.use(DropdownMenu).use(DropdownItem).use(Card).use(NoticeBar)
+export default {
+  name: "appeal",
+  components: {AppealInfo,NoData},
+  data(){
+    return {
+      first:true,
+      userInfo:this.$userInfo(),
+      currentTab:'waiting',
+      tabs:[
+        {name:'waiting',title:'待处理列表'},
+        {name:'my',title:'申诉列表'},
+        {name:'join',title:'参与列表'},
+      ],
+      searchForm:{
+        status: 3,
+        page: 1,
+        pageSize: 10,
+        hasFinish:false,
+      },
+      list:[],
+      ll:[],
+      appealStatusMap:{
+        0:'全部',
+        1:'审批中',
+        2:'审批通过',
+        3:'驳回重做',
+        4:'撤回重填',
+        5:'拒绝'
+      },
+      appealStatus:[
+        {
+          value:0,
+          text:'全部'
+        },
+        {
+          value:1,
+          text:'审批中'
+        },
+        {
+          value:2,
+          text:'审批通过'
+        },
+        {
+          value:3,
+          text:'驳回重做'
+        },
+        {
+          value:4,
+          text:'撤回重填'
+        },
+        {
+          value:5,
+          text:'拒绝'
+        },
+      ],
+      showToolBar:false,
+      loading:false,
+      showAppealInfo:false,
+      appealId:0
+    }
+  },
+  methods:{
+    initData(){
+      this.list = []
+      this.currentTab = 'waiting'
+      this.initSearchForm()
+    },
+    initSearchForm(){
+      this.searchForm.status = 3
+      this.searchForm.page = 1
+      this.searchForm.pageSize = 10
+      this.searchForm.hasFinish = false
+    },
+    initPage(){
+      this.searchForm.hasFinish = false
+      this.searchForm.page = 1
+      this.searchForm.pageSize = 10
+    },
+    refresh(){
+      this.initPage()
+      this.$refs.scroller.finishInfinite(false)
+      this.$refs.scroller.triggerPullToRefresh()
+    },
+    statusType(status){
+      let map = {
+        1:'primary',
+        2:'success',
+        3:'warning',
+        4:'warning',
+        5:'danger',
+      }
+      return map[status] || 'primary'
+    },
+    onRefresh(finishPullToRefresh){
+      this.initPage()
+      this.getList(finishPullToRefresh)
+    },
+    onInfinite(finishInfinite){
+      if (this.searchForm.hasFinish) {
+        finishInfinite()
+        this.$refs.scroller.finishPullToRefresh()
+        return
+      }
+      this.searchForm.page++
+      this.getList(finishInfinite)
+    },
+
+    getList(callback){
+      switch (this.currentTab) {
+        case 'waiting':
+          this.getListForWaiting(callback)
+          break;
+        case 'my':
+          this.getPublishList(callback)
+          break;
+        case 'join':
+          this.getJoinList(callback)
+          break;
+      }
+    },
+    getListForWaiting(callback){
+      let self = this
+      self.loading = true
+      let params = {
+        last_reviewer_id:self.userInfo.id,
+        status:1,
+        page:self.searchForm.page,
+        page_size:self.searchForm.pageSize
+      }
+
+      self.$axiosUser('get','/api/pro/integral/appeal/list',params)
+        .then(res => {
+          if (res.data.code === 1){
+            if (self.searchForm.page === 1){
+              self.list = res.data.data.list
+            }else {
+              self.list = self.list.concat(res.data.data.list)
+            }
+            callback && callback()    //将后台获取的数据,复制到vue组件的数据源后,再进行调用done函数。如果在之前调用,会循环调用。如果不调用这个函数,上拉获取数据函数调用不成功
+
+            self.$refs.scroller.finishPullToRefresh()   //停止下拉刷新  loading动画
+
+            self.searchForm.hasFinish = res.data.data.list.length !== self.searchForm.pageSize
+            self.$refs.scroller.finishInfinite(self.searchForm.hasFinish)    //当参数为false时,上拉获取数据可以重新调用。当参数为true,上拉获取数据回调函数停止使用,下拉下部不再显示loading,会显示‘’暂无更多数据
+          }else {
+            self.searchForm.hasFinish = true
+            self.$refs.scroller.finishInfinite(self.searchForm.hasFinish)
+          }
+        })
+        .finally(() => {
+          self.loading = false
+        })
+    },
+    getPublishList(callback){
+      let self = this
+      self.loading = true
+      let params = {
+        status:self.searchForm.status,
+        page:self.searchForm.page,
+        page_size:self.searchForm.pageSize
+      }
+
+      self.$axiosUser('get','/api/pro/integral/appeal/list/publisher',params)
+        .then(res => {
+          if (res.data.code === 1){
+            if (self.searchForm.page === 1){
+              self.list = res.data.data.list
+            }else {
+              self.list = self.list.concat(res.data.data.list)
+            }
+            callback && callback()    //将后台获取的数据,复制到vue组件的数据源后,再进行调用done函数。如果在之前调用,会循环调用。如果不调用这个函数,上拉获取数据函数调用不成功
+
+            self.$refs.scroller.finishPullToRefresh()   //停止下拉刷新  loading动画
+
+            self.searchForm.hasFinish = res.data.data.list.length !== self.searchForm.pageSize
+            self.$refs.scroller.finishInfinite(self.searchForm.hasFinish)    //当参数为false时,上拉获取数据可以重新调用。当参数为true,上拉获取数据回调函数停止使用,下拉下部不再显示loading,会显示‘’暂无更多数据
+          }else {
+            self.searchForm.hasFinish = true
+            self.$refs.scroller.finishInfinite(self.searchForm.hasFinish)
+          }
+        })
+        .finally(() => {
+          self.loading = false
+        })
+    },
+    getJoinList(callback){
+      let self = this
+      self.loading = true
+      let params = {
+        page:self.searchForm.page,
+        page_size:self.searchForm.pageSize
+      }
+
+      self.$axiosUser('get','/api/pro/integral/appeal/list/reviewer',params)
+        .then(res => {
+          if (res.data.code === 1){
+            if (self.searchForm.page === 1){
+              self.list = res.data.data.list
+            }else {
+              self.list = self.list.concat(res.data.data.list)
+            }
+
+            callback && callback()    //将后台获取的数据,复制到vue组件的数据源后,再进行调用done函数。如果在之前调用,会循环调用。如果不调用这个函数,上拉获取数据函数调用不成功
+
+            self.$refs.scroller.finishPullToRefresh()   //停止下拉刷新  loading动画
+
+            self.searchForm.hasFinish = res.data.data.list.length !== self.searchForm.pageSize
+            self.$refs.scroller.finishInfinite(self.searchForm.hasFinish)    //当参数为false时,上拉获取数据可以重新调用。当参数为true,上拉获取数据回调函数停止使用,下拉下部不再显示loading,会显示‘’暂无更多数据
+          }else {
+            self.searchForm.hasFinish = true
+            self.$refs.scroller.finishInfinite(self.searchForm.hasFinish)
+          }
+        })
+        .finally(() => {
+          self.loading = false
+        })
+    },
+    openDetail(appealId){
+      this.appealId = appealId
+      this.showAppealInfo = true
+    },
+    closeDetail(){
+      this.appealId = 0
+      this.showAppealInfo = false
+    },
+
+  },
+  computed:{
+  },
+  watch:{
+    currentTab(v){
+      this.refresh()
+    },
+    'searchForm.status'(){
+      this.refresh()
+    }
+  },
+
+  activated() {
+    this.initData()
+    this.getList()
+  },
+}
+</script>
+
+<style scoped lang="less">
+.popup-container{
+  position: fixed;
+  top: 5rem;
+  right: 0;
+  bottom: 0;
+  left: 0;
+  z-index: 10;
+  overflow: hidden;
+}
+
+/deep/ .van-dropdown-menu__title{
+  position: relative;
+  box-sizing: border-box;
+  max-width: 100%;
+  padding: 0 0.16rem;
+  color: #f8f8f8;
+  font-size: 0.3rem;
+  line-height: 0.44rem;
+}
+
+/deep/ .van-dropdown-menu__bar{
+  height: 0.8rem;
+  background-color: #26A2FF;
+}
+/deep/ .van-dropdown-menu{
+  border-bottom: 0;
+}
+
+.content-list{
+  margin-top: 0.2rem;
+  position: relative;
+  height: calc(100% - 3rem);
+}
+
+
+
+</style>

+ 141 - 28
src/point/view/integral/approval_detail.vue

@@ -3,6 +3,27 @@
     <van-nav-bar :title="title" :left-text="isHome? '首页':'返回'" @click-left="routeBack" left-arrow></van-nav-bar>
     <div class="body_com" :class="{ can_complete: detail_info.can_complete == 1}">
       <scroller>
+        <van-collapse
+          accordion
+          v-model="activeNames"
+          @change="collapseChange"
+        >
+          <van-collapse-item
+            :disabled="detail_info.logs.length === 0"
+            v-if="detail_info && detail_info.logs && detail_info.logs.length > 0"
+            :title="detail_info.logs.length + '条操作日志'"
+            name="logs"
+          >
+            <van-notice-bar
+              v-for="(item,index) in logs"
+              :key="index"
+              left-icon="info-o"
+              color="#1989fa"
+              background="#ecf9ff"
+              :text="item.create_time + item.msg"
+            />
+          </van-collapse-item>
+        </van-collapse>
         <van-cell-group>
           <van-cell :title="detail_info.employee_info.name" v-if="detail_info.process !== null && detail_info.status == 0">
             <template slot="icon">
@@ -94,41 +115,66 @@
         <approvalProcess :data.sync="detail_info.process"></approvalProcess>
         <div style="height: 3.5rem;"></div>
       </scroller>
+
       <!-- 审批者 ||  -->
-      <footer class="flex-box flex-v-ce footer" v-if="detail_info.can_refuse == '1'">
-        <div class="flex-2">撤回后需重新审批</div>
-        <van-button type="info" @click="revoke(1)" class="flex-1">撤回</van-button>
-      </footer>
+<!--      <footer class="flex-box flex-v-ce footer" v-if="detail_info.can_refuse === 1">-->
+<!--        <div class="flex-2">撤回后需重新审批</div>-->
+<!--        <van-button type="info" @click="revoke(1)" class="flex-1">撤回</van-button>-->
+<!--      </footer>-->
       <!-- 申请者 ||  -->
-      <footer class="flex-box flex-v-ce footer" v-if="detail_info.applyor_id==$userInfo().id&&detail_info.can_refuse == '1'&&(detail_info.source_type==2||detail_info.source_type==3)">
-        <div class="flex-2">撤销后数据将不可恢复</div>
-        <van-button type="info" @click="revoke(2)" class="flex-1">撤销</van-button>
+<!--      <footer class="flex-box flex-v-ce footer" v-if="detail_info.applyor_id==$userInfo().id&&detail_info.can_refuse === 1&&(detail_info.source_type===2||detail_info.source_type===3)">-->
+<!--        <div class="flex-2">撤销后数据将不可恢复</div>-->
+<!--        <van-button type="info" @click="revoke(2)" class="flex-1">撤销</van-button>-->
+<!--      </footer>-->
+      <footer class="flex-box flex-v-ce footer" v-if="canRefuse">
+        <van-button type="info" @click="revoke()" :loading="submitting" class="flex-1">撤回审批</van-button>
       </footer>
 
+
       <!-- 驳回弹窗 -->
       <van-popup v-model="show_refuse" position="right" :style="{ height: '100%', width: '100%', 'background-color': 'rgb(245, 245, 245)' }">
         <div :style="'padding-top:' + bar_height + 'px;background-color: #238dfa;'"></div>
-        <van-nav-bar title="确认驳回" left-text="返回" @click-left="show_refuse = false" left-arrow></van-nav-bar>
-        <van-cell-group><van-field v-model="refuse_msg" rows="5" autosize type="textarea" maxlength="50" placeholder="请输入审批意见" show-word-limit /></van-cell-group>
-        <div style="padding:0.32rem;"><van-button block type="info" @click="confirm_refuse">确认驳回</van-button></div>
+        <van-nav-bar title="审批拒绝" left-text="返回" @click-left="show_refuse = false" left-arrow></van-nav-bar>
+        <van-cell-group><van-field v-model="refuse_msg" rows="5" autosize type="textarea" maxlength="50" placeholder="请输入审批意见" show-word-limit @input="onRefuseMsgInput"/></van-cell-group>
+        <div style="padding:0.32rem;"><van-button block type="info" :loading="submitting" @click="confirm_refuse">确认</van-button></div>
       </van-popup>
+
+      <van-popup v-model="showRejectRewrite" position="right" :style="{height:'100%',width:'100%', backgroundColor:'rgb(245, 245, 245)'}">
+        <div :style="'padding-top:' + bar_height + 'px;background-color: #238dfa;'"></div>
+        <van-nav-bar title="驳回重做" left-text="返回" @click-left="showRejectRewrite = false" left-arrow></van-nav-bar>
+        <van-cell-group><van-field v-model="formRejectRewrite.remark" rows="5" autosize type="textarea" maxlength="100" placeholder="原因说明" show-word-limit @input="onRewriteRemarkInput" /></van-cell-group>
+        <div style="padding:0.32rem;"><van-button block type="info" :loading="submitting" @click="rejectRewrite">确认</van-button></div>
+      </van-popup>
+
     </div>
 
-    <van-row justify="center" type="flex" v-if="detail_info.can_complete == 1" class="footer">
-      <van-col :span="detail_info.source_type != 4 ? 8 : 0">
-        <div style="padding:0.16rem;">
-          <van-button block type="info" plain :disabled="detail_info.source_type == '4'" v-if="detail_info.source_type != 4" @click="refuse">驳回</van-button>
-        </div>
+<!--    <van-row justify="center" type="flex" v-if="detail_info.can_complete === 1" class="footer">-->
+<!--      <van-col :span="detail_info.source_type !== 4 ? 8 : 0">-->
+<!--        <div style="padding:0.16rem;">-->
+<!--          <van-button block type="info" plain :disabled="detail_info.source_type === 4" v-if="detail_info.source_type !== 4" @click="refuse">拒绝</van-button>-->
+<!--        </div>-->
+<!--      </van-col>-->
+<!--      <van-col :span="detail_info.source_type !== 4 ? 16 : 24">-->
+<!--        <div style="padding:0.16rem; padding-left:0;">-->
+<!--          <van-button block type="info" v-if="detail_info.source_type !== 4" @click="$router.push({ name: 'integralAudit', query: { review_id: detail_info.id } })">-->
+<!--            通过-->
+<!--          </van-button>-->
+<!--          <van-button block type="info" v-else @click="$router.push({ name: 'performanceAudit', query: { review_id: detail_info.id } })">-->
+<!--            通过-->
+<!--          </van-button>-->
+<!--        </div>-->
+<!--      </van-col>-->
+<!--    </van-row>-->
+    <van-row justify="space-around" gutter="10" type="flex" v-if="canComplete" class="footer" >
+      <van-col v-if="canReject" :span="8">
+        <van-button block plain :loading="submitting" @click="refuse" >拒绝</van-button>
       </van-col>
-      <van-col :span="detail_info.source_type != 4 ? 16 : 24">
-        <div style="padding:0.16rem; padding-left:0;">
-          <van-button block type="info" v-if="detail_info.source_type != '4'" @click="$router.push({ name: 'integralAudit', query: { review_id: detail_info.id } })">
-            通过
-          </van-button>
-          <van-button block type="info" v-else @click="$router.push({ name: 'performanceAudit', query: { review_id: detail_info.id } })">
-            通过
-          </van-button>
-        </div>
+      <van-col v-if="canRejectRewrite" :span="8">
+        <van-button block  plain type="warning" :loading="submitting" @click="showRejectRewrite = true" >驳回重做</van-button>
+      </van-col>
+      <van-col :span="canRejectRewrite ? 8 : 16">
+        <van-button block type="info" v-if="detail_info.source_type !== 4" @click="$router.push({ name: 'integralAudit', query: { review_id: detail_info.id } })" :loading="submitting" >通过</van-button>
+        <van-button block type="info" v-else @click="$router.push({ name: 'performanceAudit', query: { review_id: detail_info.id } })" :loading="submitting" >通过</van-button>
       </van-col>
     </van-row>
 
@@ -138,18 +184,24 @@
 <script>
 import Vue from 'vue'
 import approvalProcess from '@/point/view/integral/approval_process'
-import { Dialog, Panel, Step, Steps, Overlay, ImagePreview } from 'vant'
+import { Dialog, Panel, Step, Steps, Overlay, ImagePreview, Collapse, CollapseItem,NoticeBar } from 'vant'
+import Footer from "../../../components/footer.vue";
+import {specialFilter} from "../../../utils/helper";
 Vue.use(Dialog)
   .use(Panel)
   .use(Step)
   .use(Steps)
   .use(Overlay)
   .use(ImagePreview)
+  .use(Collapse)
+  .use(CollapseItem)
+  .use(NoticeBar)
 export default {
   // 数据
-  components: { approvalProcess },
+  components: {Footer, approvalProcess },
   data () {
     return {
+      userInfo:this.$userInfo(),
       imageSrc: [],
       show: false,
       title: '审批详情',
@@ -177,6 +229,13 @@ export default {
       adopt_two: false,
       types_list: {},
       isHome:false,//微信信息点击进来
+      showRejectRewrite:false,
+      formRejectRewrite:{
+        remark:''
+      },
+      submitting:false,
+      activeNames:[],
+      logs: []
     }
   },
   watch: {
@@ -188,6 +247,12 @@ export default {
   },
   // 方法
   methods: {
+    onRefuseMsgInput(v){
+      this.refuse_msg = specialFilter(v)
+    },
+    onRewriteRemarkInput(v){
+      this.formRejectRewrite.remark = specialFilter(v)
+    },
     routeBack(){
       this.isHome? this.$router.replace({ name: 'home' }):this.$route_back();
     },
@@ -320,7 +385,7 @@ export default {
       let self = this
       Dialog.confirm({
         title: '提示',
-        message: '您确定要' + str + '此项吗?'
+        message: '确定要撤回此项吗?'
       })
         .then(() => {
           self.showLoading()
@@ -343,11 +408,40 @@ export default {
         .catch(() => {
           // on cancel
         })
+    },
+    rejectRewrite(){
+      let self = this
+      this.submitting = true
+      self.showLoading()
+      let params = {
+        review_id:self.detail_info.id,
+        remark:self.formRejectRewrite.remark || ''
+      }
+      self.$axiosUser('post','/api/pro/integral/review/reject/rewrite',params)
+        .then(res => {
+          if (res.data.code === 1){
+            self.get_info()
+          }else {
+            self.$toast(res.data.msg)
+          }
+        })
+        .finally(() => {
+          self.$toast.clear()
+          self.showRejectRewrite = false
+          self.submitting = false
+        })
+    },
+    collapseChange(activeName){
+      if (activeName === 'logs'){
+        this.logs = this.detail_info.logs
+      }else {
+        this.logs = []
+      }
     }
   },
   created () {
     this.get_point_types()
-    
+
     if (window.plus) {
       this.bar_height = window.plus.navigator.getStatusbarHeight()
     }
@@ -361,6 +455,7 @@ export default {
     }
   },
   activated() {
+    this.activeNames = []
   	this.get_info()
     if(this.$route.query.isHome){
        this.isHome = true;
@@ -368,6 +463,24 @@ export default {
       this.isHome = false;
     }
   },
+  computed:{
+    isFirstStep(){
+      return this.detail_info && ((this.detail_info.pid === 0 && this.detail_info.step === 0) || this.detail_info.step === 1)
+    },
+    canComplete(){
+      return this.detail_info && this.detail_info.can_complete === 1
+    },
+    canRefuse(){
+      return this.detail_info && this.detail_info.can_refuse === 1
+    },
+    canRejectRewrite(){
+      return this.canComplete && this.detail_info.source_type === 1
+    },
+    canReject(){
+      return this.canComplete && this.detail_info.source_type !== 4
+    }
+
+  }
 }
 </script>
 <style scoped lang="less">

+ 42 - 17
src/point/view/integral/approval_list.vue

@@ -32,25 +32,24 @@
               <userImage :user_name="item.employee_name" v-if="item.source_type == 1 || item.source_type == 4" width="0.72rem" height="0.72rem" />
               <userImage :user_name="item.employee_name" v-if="item.source_type == 2 || item.source_type == 3" width="0.72rem" height="0.72rem" />
               <div class="task-title__bar">
-                <span class="title" v-show="item.source_type == 1">{{ item.employee_name }}的积分任务</span>
-                <span class="title" v-show="item.source_type == 2">{{ item.employee_name }}的积分申请</span>
-                <span class="title" v-show="item.source_type == 3">{{ item.employee_name }}的积分奖扣</span>
-                <!-- <span class="title" v-show="item.source_type == 4">{{item.employee_name}}的绩效工作</span> -->
-                <!-- <span class="title" v-show="item.source_type == 4">{{item.employee_name}}提交的绩效工作包</span> -->
+                <span class="title">
+                  {{item.employee_name}}
+                  &nbsp;<van-tag type="primary">{{sourceTypeMap[item.source_type] || '--'}}</van-tag>
+                </span>
                 <span v-if="filter.type === 'reviewed' && item.status !== 0 && item.status !== 2">
-                  <span class="task-item__point red" v-if="item.review_point >= 0">+{{ item.review_point }}{{ $getTypesName(item.pt_id) }}</span>
-                  <span class="task-item__point green" v-else>{{ item.review_point }}{{ $getTypesName(item.pt_id) }}</span>
+                  <span class="task-item__point red" v-if="item.review_point > 0">+{{ item.review_point }}{{ $getTypesName(item.pt_id) }}</span>
+                  <span class="task-item__point green" v-else-if="item.review_point < 0">{{ item.review_point }}{{ $getTypesName(item.pt_id) }}</span>
                 </span>
               </div>
             </div>
 
             <div class="task-remark__content">
-              <span>{{ item.remark.customize }}</span>
+              <span class="input-ccc">{{ item.remark.customize }}</span>
             </div>
             <div class="task-item__bottom" v-if="item.status == 0">
               <span class="task-item__date">{{ item.event_time }}</span>
               <span class="task-item__toolbar" v-if="item.status === 0">
-                <span v-show="item.source_type != 4" @click.stop="reject(item)">驳回</span>
+                <span v-show="item.source_type != 4" @click.stop="reject(item)">拒绝</span>
                 <div class="divider"></div>
                 <span v-if="item.source_type == '1'" @click.stop="$router.push({ name: 'integralAudit', query: { review_id: item.id } })">通过</span>
                 <span v-if="item.source_type == '2'" @click.stop="$router.push({ name: 'integralAudit', query: { review_id: item.id } })">通过</span>
@@ -65,8 +64,7 @@
             <div class="task-item__bottom" v-else>
               <span class="task-item__date">{{ item.event_time }}</span>
               <span class="task-item__toolbar">
-                <span class="green" v-if="item.status == 1">审批通过</span>
-                <span class="red" v-if="item.status == 2">审批驳回</span>
+                <van-tag :type="statusType(item.review_status)" mark size="medium" >{{statusMap[item.review_status] || '--'}}</van-tag>
               </span>
             </div>
           </div>
@@ -75,9 +73,9 @@
       </div>
     </TabsList>
 
-    <van-dialog v-model="show" title="确认驳回" class="reject_popup" show-cancel-button :beforeClose="save_btn">
+    <van-dialog v-model="show" title="审批拒绝" class="reject_popup" show-cancel-button :beforeClose="save_btn">
       <van-cell-group>
-        <van-field v-model="reject_text" rows="2" autosize type="textarea" maxlength="50" placeholder="请输入审批意见" show-word-limit v-validate="'required'" name="审批意见" />
+        <van-field v-model="reject_text" rows="2" autosize type="textarea" maxlength="50" placeholder="请输入审批意见" show-word-limit v-validate="'required'" name="审批意见" @input="onRejectTextInput" />
       </van-cell-group>
     </van-dialog>
   </div>
@@ -89,6 +87,7 @@ import { Tab, Tabs, Empty, DropdownMenu, DropdownItem, Search } from 'vant';
 
 import TabsList from '@/components/TabsList';
 import { _debounce } from '@/utils/auth';
+import {specialFilter} from "../../../utils/helper";
 
 Vue.use(Empty)
   .use(Tab)
@@ -117,7 +116,7 @@ export default {
       reject_text: '',
 
       // 0411
-      tabsOption: [{ title: '待我审批', value: 'waiting' }, { title: '我已审批', value: 'reviewed' }],
+      tabsOption: [{ title: '待审批', value: 'waiting' }, { title: '参与审批', value: 'reviewed' }],
       screen_list: [
         {
           title: '任务类型',
@@ -130,7 +129,19 @@ export default {
             // {name: '绩效工作', id: '4'}
           ]
         }
-      ]
+      ],
+      statusMap:{
+        0:'待审核',
+        1:'审核通过',
+        2:'拒绝',
+        3:'驳回重做',
+        4:'重填',
+      },
+      sourceTypeMap:{
+        1:'积分任务',
+        2:'积分申请',
+        3:'积分奖扣',
+      }
     };
   },
   components: { TabsList },
@@ -153,7 +164,7 @@ export default {
     }
   },
   activated() {
-  	 this.onRefresh({ pageIndex: 1, isRefresh: true });
+  	this.onRefresh({ pageIndex: 1, isRefresh: true });
   },
   methods: {
     openBatch() {
@@ -271,6 +282,20 @@ export default {
       } else {
         done();
       }
+    },
+    statusType(status){
+      if (status === -1) return 'info'
+      const map = {
+        0:'warning',
+        1:'success',
+        2:'danger',
+        3:'danger',
+        4:'primary',
+      }
+      return map[status] || 'info'
+    },
+    onRejectTextInput(v){
+      this.reject_text = specialFilter(v)
     }
   },
 };
@@ -349,7 +374,7 @@ export default {
   .task-remark__content {
     display: -webkit-box;
     padding-left: 0.92rem;
-    font-size: 0.32rem;
+    font-size: 0.3rem;
     color: #333;
     text-overflow: ellipsis;
     overflow: hidden;

+ 66 - 11
src/point/view/integral/approval_process.vue

@@ -12,23 +12,47 @@
         <userImage :user_name="item.name" :id="0" :img_url="item.img_url"></userImage>
       </template>
       <template slot="title">
-        <span class="process-item__name">{{ item.name }}</span>
-        <span class="process-item__remark" v-if="item.remark == '申请人'">{{ item.remark }}</span>
-        <span class="process-item__remark" v-else :class="{orange:item.remark == '待审核',green:item.remark == '审核通过',red:item.remark == '审核驳回','color-FF9600': item.remark == '待处理','color-F56C6C':item.remark == '驳回'}">
-          {{ item.remark }}
-        </span>
+        <span v-if="item.step > 0">阶段{{item.step}}</span>
+        <van-tag :type="processStatusType(item.status)" size="medium" mark>{{processStatusMap[item.status] || '--'}}</van-tag>
       </template>
       <template slot="right-icon">
         <span class="red" v-if="item.review_point > 0">+{{ item.review_point }}</span>
         <span class="green" v-else>{{ item.review_point || '' }}</span>
       </template>
       <template slot="label">
-        <span class="datetime">{{ item.time }}</span>
-        <div v-if="item.remark != '申请人'" style="color: #323233;font-size: 0.28rem;margin-top: 0.12rem;">{{ item.review_remark }}</div>
-        <div class="h40"></div>
+        <span class="datetime" v-if="item.time">{{ item.time }}</span>
+<!--        <van-cell title="姓名" :value="item.name" />-->
+<!--        <van-cell title="申请分值" v-if="item.point" :value="item.point ? item.point : ''" />-->
+<!--        <van-cell title="发放奖票" v-if="i > 0" :value="item.ticket_count ? '是': '否'"  />-->
+<!--        <van-cell title="审批分值" v-if="item.remark !== '发起' && item.review_point" :value="item.review_point ? item.review_point : ''"  />-->
+        <van-row >
+          <van-col span="8" class="process-title">姓名</van-col>
+          <van-col span="16" class="process-content">{{item.name}}</van-col>
+        </van-row>
+        <van-row v-if="item.point">
+          <van-col span="8" class="process-title">申请分值</van-col>
+          <van-col span="16" class="process-content">{{item.point ? item.point : ''}}</van-col>
+        </van-row>
+        <van-row v-if="i > 0">
+          <van-col span="8" class="process-title">发放奖票</van-col>
+          <van-col span="16" class="process-content">{{item.ticket_count ? '是': '否'}}</van-col>
+        </van-row>
+        <van-row v-if="item.remark !== '发起' && item.review_point">
+          <van-col span="8" class="process-title">审批分值</van-col>
+          <van-col span="16" class="process-content">{{item.review_point ? item.review_point : ''}}</van-col>
+        </van-row>
+        <van-row v-if="item.review_remark">
+          <van-col span="8" class="process-title">备注</van-col>
+          <van-col span="16" class="process-content">
+            <van-notice-bar
+              color="#1989fa"
+              background="#ecf9ff"
+              :text="item.review_remark"
+            />
+          </van-col>
+        </van-row>
       </template>
     </van-cell>
-
   </div>
 </template>
 
@@ -44,7 +68,16 @@ export default {
     }
   },
   data() {
-    return {};
+    return {
+      processStatusMap:{
+        '-1':'发起',
+        0:'待审核',
+        1:'审核通过',
+        2:'拒绝',
+        3:'驳回重做',
+        4:'重填',
+      }
+    };
   },
   methods: {
     getIconText(employeeName) {
@@ -53,6 +86,17 @@ export default {
         return employeeName[len - 2] + employeeName[len - 1];
       }
       return employeeName;
+    },
+    processStatusType(status){
+      if (status === -1) return 'primary'
+      const map = {
+        0:'warning',
+        1:'success',
+        2:'danger',
+        3:'danger',
+        4:'primary',
+      }
+      return map[status] || 'info'
     }
   }
 };
@@ -61,7 +105,7 @@ export default {
 <style scoped>
 .process-item {
   padding-top: 0;
-  padding-bottom: 0;
+  padding-bottom: 0.1rem;
   position: relative;
 }
 
@@ -126,4 +170,15 @@ export default {
 /deep/ .img_round {
   margin-right: 0.16rem;
 }
+.process-title{
+  font-size: 0.3rem;
+  line-height: 0.7rem;
+  text-align: center;
+}
+.process-content{
+  font-size: 0.3rem;
+  line-height: 0.7rem;
+  text-align: right;
+}
+
 </style>

+ 4 - 4
src/point/view/integral/batchList.vue

@@ -265,12 +265,12 @@
         <div style="height: 2rem;"></div>
       </scroller>
       <div class="flex-box btns" v-show="rightText" :class="{ isIos: isIos }" >
-        <van-button plain type="danger" class="flex-1" style="margin-right: 0.24rem" @click="reject()">驳回</van-button>
+        <van-button plain type="danger" class="flex-1" style="margin-right: 0.24rem" @click="reject()">拒绝</van-button>
         <van-button plain type="info" class="flex-1" @click="pass()">通过</van-button>
       </div>
-      <van-dialog v-model="showReject" title="确认驳回" class="reject_popup" show-cancel-button :beforeClose="save_btn">
+      <van-dialog v-model="showReject" title="批量拒绝" class="reject_popup" show-cancel-button :beforeClose="save_btn">
         <van-cell-group>
-          <van-field v-model="reject_text" rows="2" autosize  type="textarea" maxlength="50" placeholder="请输入审批意见"  show-word-limit v-validate="'required'" name="审批意见"/>
+          <van-field v-model="reject_text" rows="2" autosize  type="textarea" maxlength="50" placeholder="原因说明"  show-word-limit v-validate="'required'" name="原因说明"/>
         </van-cell-group>
       </van-dialog>
       <van-image-preview v-model="show" :images="imageSrc"></van-image-preview>
@@ -353,7 +353,7 @@ export default {
     reject () {
       Dialog.confirm({
         title: '提示',
-        message: `确定驳回已选的${this.activeCheckedNum}条审批吗?`
+        message: `确定拒绝已选的${this.activeCheckedNum}条审批吗?`
       }).then(() => {
         this.showReject = true
       }).catch(() => {

+ 272 - 0
src/point/view/integral/deptRank.vue

@@ -0,0 +1,272 @@
+<template>
+  <div class="mrd-container">
+    <van-nav-bar title="部门对比" left-text="返回" @click-left="$route_back" left-arrow />
+    <van-dropdown-menu v-if="showSearchBar">
+<!--  A/B分    -->
+      <van-dropdown-item @open="calendarOpen">
+        <van-icon name="calendar-o" slot="title" size="1.5em" />
+      </van-dropdown-item>
+      <van-dropdown-item :title="searchForm.deptName" ref="deptDropdownItem"><DeptSelectorDropdown @onConfirm="onConfirmDept" /></van-dropdown-item>
+      <van-dropdown-item title="规则" ref="ruleDropdownItem"><RuleCategorySelDropdown @onConfirm="onConfirmRule" @onCancel="searchForm.ruleId = 0"/></van-dropdown-item>
+      <van-dropdown-item>
+        <van-icon name="list-switch" slot="title" size="1.5em" />
+        <template slot="default">
+          <van-cell center title="积分类型">
+            <template #right-icon>
+              <van-radio-group v-model="searchForm.ptId" direction="horizontal">
+                <van-radio v-for="pt in pts" :key="pt.value" :name="pt.value">{{pt.text}}</van-radio>
+              </van-radio-group>
+            </template>
+          </van-cell>
+          <van-cell center title="包含子部门">
+            <van-switch v-model="searchForm.deptIncludeSub" active-color="#26A2FF" slot="right-icon" size="24"/>
+          </van-cell>
+          <van-cell center title="包含子规则分类">
+            <van-switch v-model="searchForm.ruleIncludeSub" active-color="#26A2FF" slot="right-icon" size="24"/>
+          </van-cell>
+        </template>
+      </van-dropdown-item>
+    </van-dropdown-menu>
+    <div class="mrd-content">
+      <scroller
+        ref="scroller"
+        :on-refresh="onRefresh"
+      >
+        <van-cell v-for="item in dataList" :key="item.id" :title="item.name" :value="item.point"/>
+        <noData :list="dataList" />
+
+      </scroller>
+    </div>
+
+
+
+    <van-calendar
+      v-model="showCalendar"
+      type="range"
+      :allow-same-day="true"
+      :min-date="minDate"
+      :max-date="maxDate"
+      :default-date="timeScope"
+      :show-confirm="false"
+      color="#26A2FF"
+      @close="calendarClose"
+      @confirm="calendarConfirm"
+    >
+      <template v-slot:title>
+        <van-row>
+          <van-col span="20">
+            <van-row type="flex" justify="space-between" style="height: 1rem;">
+              <van-col span="6" style="text-align: center; align-self: center;">
+                <van-tag type="success" size="medium" @click="timeScopeThisWeek">本周</van-tag>
+              </van-col>
+              <van-col span="6" style="text-align: center; align-self: center;">
+                <van-tag type="success" size="medium" @click="timeScopeLastWeek">上周</van-tag>
+              </van-col>
+              <van-col span="6" style="text-align: center; align-self: center;">
+                <van-tag type="primary" size="medium" @click="timeScopeThisMoth">本月</van-tag>
+              </van-col>
+              <van-col span="6" style="text-align: center; align-self: center;">
+                <van-tag type="primary" size="medium" @click="timeScopeLastMonth">上月</van-tag>
+              </van-col>
+            </van-row>
+          </van-col>
+        </van-row>
+      </template>
+    </van-calendar>
+
+
+  </div>
+</template>
+
+
+<script>
+import Vue from 'vue';
+import moment from "moment/moment";
+import { DropdownMenu, DropdownItem ,Calendar,Switch} from 'vant';
+import DeptSelectorDropdown from '@/components/DeptSelectorDropdown';
+import RuleCategorySelDropdown from '@/components/RuleCategorySelDropdown';
+
+Vue.use(DropdownMenu).use(DropdownItem).use(Calendar).use(Switch);
+
+export default {
+  name: "dept_rank",
+  components:{
+    DeptSelectorDropdown,
+    RuleCategorySelDropdown
+  },
+  data(){
+    let startDate = new Date();
+    startDate.setTime(startDate.getTime() - 3600 * 1000 * 24 * 7);
+    startDate = moment(startDate).format('YYYY-MM-DD');
+    let endDate = moment().format('YYYY-MM-DD');
+    let pts = this.$getTypes.map(type => {
+      return {value:type.id,text:type.name,code:type.code}
+    });
+    let ptB = pts.filter(pt => pt.code === 'BF');
+    ptB = ptB.length > 0 ? ptB[0] : null;
+
+    let today = new Date();
+    let minDate = new Date();
+    minDate.setTime(today.getTime() - 3600 * 1000 * 24 * 30 * 6);
+    let maxDate = new Date(today.getFullYear(),today.getMonth(),1);
+    maxDate.setMonth(maxDate.getMonth() + 1);
+    maxDate.setDate(0);
+
+    return{
+      pts:pts,
+      searchForm:{
+        startDate:startDate,
+        endDate:endDate,
+        deptId:0,
+        deptName:'全公司',
+        deptIncludeSub:false,
+        ptId:ptB ? ptB.value : 0,
+        ptName: ptB ? ptB.text : '',
+        ruleId:0,
+        ruleIncludeSub:false,
+        itemId:0
+      },
+      dataList:[],
+      showCalendar:false,
+      minDate:minDate,
+      maxDate:maxDate,
+      timeScope:[new Date(startDate),new Date(endDate)],
+      showSearchBar:!this.$supremeAuthority('employee')
+    }
+  },
+  computed:{
+    timeScopeText(){
+      return moment(this.searchForm.startDate).format('MM/DD') + '-' + moment(this.searchForm.endDate).format('MM/DD')
+    },
+    currentPtName(){
+      if (this.searchForm.ptId <= 0) return '积分分类';
+      let pt = this.pts.filter(pt => pt.id === this.searchForm.ptId);
+      return pt ? pt.name : '积分分类';
+    }
+  },
+  watch:{
+    timeScope(val){
+      this.$nextTick(()=>{
+        this.searchForm.startDate = moment(val[0]).format('YYYY-MM-DD');
+        this.searchForm.endDate = moment(val[1]).format('YYYY-MM-DD');
+      })
+    },
+    'searchForm.startDate'(val){
+      this.onRefresh()
+    },
+    'searchForm.endDate'(val){
+      this.onRefresh()
+    },
+    'searchForm.deptId'(val){
+      this.onRefresh()
+    },
+    'searchForm.deptIncludeSub'(val){
+      this.onRefresh()
+    },
+    'searchForm.ptId'(val){
+      this.onRefresh()
+    },
+    'searchForm.ruleId'(val){
+      this.onRefresh()
+    },
+    'searchForm.ruleIncludeSub'(val){
+      this.onRefresh()
+    },
+
+  },
+  created() {},
+  methods:{
+    timeScopeThisWeek(){
+      this.timeScope = [new Date(moment().startOf('week').format('YYYY-MM-DD')),new Date(moment().endOf('week').format('YYYY-MM-DD'))]
+      this.showCalendar= false
+    },
+    timeScopeLastWeek(){
+      this.timeScope = [new Date(moment().subtract(1,'week').startOf('week').format('YYYY-MM-DD')),new Date(moment().subtract(1,'week').endOf('week').format('YYYY-MM-DD'))]
+      this.showCalendar = false
+    },
+    timeScopeThisMoth(){
+      this.timeScope = [new Date(moment().startOf('month').format('YYYY-MM-DD')),new Date(moment().endOf('month').format('YYYY-MM-DD'))]
+      this.showCalendar = false
+    },
+    timeScopeLastMonth(){
+      this.timeScope = [new Date(moment().subtract(1,'month').startOf('month').format('YYYY-MM-DD')),new Date(moment().subtract(1,'month').endOf('month').format('YYYY-MM-DD'))]
+      this.showCalendar = false
+    },
+    calendarOpen(){
+      this.showCalendar = true;
+    },
+    calendarClose(){
+      this.showCalendar = false;
+    },
+    calendarConfirm(event){
+      const [start,end] = event;
+      this.timeScope = [start,end];
+      this.showCalendar = false;
+    },
+    truncateString(str,length){
+      if (str.length > length){
+      }
+      return str.length > length ? str.substring(0,length) : str;
+    },
+    onConfirmDept(deptItem){
+      if (deptItem){
+        this.searchForm.deptId = deptItem.id;
+        this.searchForm.deptName = this.truncateString(deptItem.name,3);
+      }else {
+        this.searchForm.deptId = 0;
+        this.searchForm.deptName = '全公司';
+      }
+      this.$refs.deptDropdownItem.toggle();
+    },
+    onConfirmRule(ruleId){
+      this.searchForm.ruleId = ruleId || 0;
+      this.$refs.ruleDropdownItem.toggle();
+    },
+    onRefresh(done){
+      if (!this.searchForm.startDate || !this.searchForm.endDate || !this.searchForm.ptId){
+        if (typeof done === 'function') done();
+        return;
+      }
+
+      let msg = {
+        type:'dr',
+        start_date:this.searchForm.startDate,
+        end_date:this.searchForm.endDate,
+        pt_id:this.searchForm.ptId,
+        dept_id:this.searchForm.deptId,
+        dept_include_sub:this.searchForm.deptIncludeSub ? 1 : 0,
+        item_id:0,
+        rule_id:this.searchForm.ruleId,
+        rule_include_sub:this.searchForm.ruleIncludeSub ? 1 : 0
+      }
+
+      this.$socketApiTow.sendData(msg,(res) => {
+        if (res.code !== 1 || res.type !== msg.type){
+          if (typeof done === 'function') done();
+          return;
+        }
+        this.dataList = res.result.list;
+        if (typeof done === 'function') done();
+      })
+
+
+    }
+  }
+}
+
+</script>
+
+
+
+<style scoped lang="less">
+.mrd-container {
+  background-color: white;
+
+  & .mrd-content {
+    margin-top: 0.2rem;
+    position: relative;
+    height: calc(100% - 2.1rem);
+  }
+
+}
+</style>

+ 98 - 7
src/point/view/integral/event_detail.vue

@@ -8,7 +8,10 @@
             <div class="flex-1 flex-box-ce">
               <userImage :id="eventInfo.employee_id" :img_url="eventInfo.img_url" :user_name="eventInfo.employee_name" width="1.1rem" height="1.1rem"></userImage>
               <div style="margin-left: 0.1rem;">
-                <div class="event-employee__name">{{ eventInfo.employee_name }}</div>
+                <div class="event-employee__name">
+                  {{ eventInfo.employee_name }}
+                  <van-tag type="primary" size="medium"  v-if="eventInfo && eventInfo.has_appeal" >已申诉</van-tag>
+                </div>
                 <div class="deptName">{{ deptName }}</div>
               </div>
             </div>
@@ -82,12 +85,43 @@
         <div style="height: 1.5rem;"></div>
       </scroller>
 
-      <!-- 奖扣者 ||  -->
-      <footer class="flex-box flex-v-ce footer" v-if="eventInfo.recorder_id == $userInfo().id && eventInfo.process.length == 1 && (eventInfo.event_type == 3 || eventInfo.event_type == 4)">
-        <div class="flex-2">撤销后数据将不可恢复</div>
-        <van-button type="info" @click="revocation()" class="flex-1">撤销</van-button>
+      <footer class="footer">
+        <van-row type="flex" justify="center">
+          <!--    发起申诉    -->
+          <van-col span="24" v-if="appealEnable">
+            <van-button type="info" block @click="showAppeal = true">发起申诉</van-button>
+          </van-col>
+          <!-- 奖扣者 ||  -->
+          <van-col span="24" v-else-if="eventInfo.recorder_id == $userInfo().id && eventInfo.process.length == 1 && (eventInfo.event_type == 3 || eventInfo.event_type == 4)">
+            <van-button type="info" @click="revocation()" block>撤销</van-button>
+          </van-col>
+        </van-row>
       </footer>
     </div>
+    <van-popup v-model="showAppeal" position="bottom" :style="{height:'100%',width:'100%',backgroundColor:'rgb(245, 245, 245)'}">
+      <div :style="'padding-top:' + barHeight + 'px;background-color: #238dfa;'"></div>
+      <van-nav-bar title="发起申诉" left-text="返回" @click-left="showAppeal = false" left-arrow></van-nav-bar>
+      <van-cell-group>
+        <EmployeeSelectorCell
+          title="审批人"
+          v-model="appealForm.reviewer"
+          :multi="false"
+          iconType="records"
+          :employee_list="userInfo.employee_detail.superior_list"
+          :is_employee_list="true"
+        />
+        <van-cell>
+          <Mtextarea
+            v-model="appealForm.remark"
+            placeholder="申诉原因"
+          />
+        </van-cell>
+      </van-cell-group>
+      <footer class="flex-box flex-v-ce footer">
+        <van-button type="info" block :loading="submitting" :disabled="!canAppealSubmit" @click="createAppeal">提交</van-button>
+      </footer>
+
+    </van-popup>
   </div>
 </template>
 
@@ -95,6 +129,9 @@
 import approval_process from '@/point/view/integral/approval_process'
 import Vue from 'vue'
 import { Panel, Skeleton, Image, ImagePreview, Dialog } from 'vant'
+import Footer from "../../../components/footer.vue";
+import EmployeeSelectorCell from "../../../components/EmployeeSelectorCell.vue";
+import Mtextarea from "../../../components/Mtextarea2.vue";
 
 Vue.use(Panel)
   .use(Skeleton)
@@ -103,12 +140,21 @@ Vue.use(Panel)
   .use(Dialog)
 export default {
   name: 'event_detail_info',
-  components: {approval_process },
+  components: {Mtextarea, EmployeeSelectorCell, Footer, approval_process },
   data () {
     return {
+      userInfo:this.$userInfo(),
       loading: true,
       eventInfo: { remark: { customize: '' }, process: [] },
       deptName:'',
+      siteAppealEnable: false,
+      showAppeal: false,
+      barHeight:'',
+      appealForm:{
+        reviewer:[],
+        remark:''
+      },
+      submitting:false
     }
   },
   computed: {
@@ -117,15 +163,30 @@ export default {
     },
     hasAttachmentFile () {
       return Array.isArray(this.eventInfo.files) && this.eventInfo.files.length > 0
+    },
+    appealEnable(){
+      return this.eventInfo && this.userInfo && this.siteAppealEnable && this.eventInfo.employee_id === this.userInfo.id
+    },
+    canAppealSubmit(){
+      return this.appealEnable && this.appealForm.reviewer.length === 1 && !this.submitting
     }
   },
   methods: {
+    getConfig(){
+      let self = this
+      self.$axiosUser('get','/api/pro/integral/site/config')
+        .then(res => {
+          if (res.data.code === 1){
+            self.siteAppealEnable = res.data.data.appeal === 1
+          }
+        })
+    },
     // 撤销奖扣
     revocation () {
       var that = this
       Dialog.confirm({
         title: '提示',
-        message: '您确定要撤销此项吗?'
+        message: '撤销后数据将不可恢复,确定要撤销此项吗?'
       }).then(() => {
         let data = { target_id: this.$route.query.id, type: 1}
         this.$axiosUser('post', '/api/pro/integral/review/prize/destroy', data).then(res => {
@@ -165,10 +226,40 @@ export default {
           this.$toast.clear()
           this.loading = false
         })
+    },
+    createAppeal(){
+      let self = this
+      self.submitting = true
+      self.$toast.loading({message:'提交中...'})
+      let params = {
+        reviewer_id:self.appealForm.reviewer[0].id,
+        events:[{id:self.eventInfo.event_id,remark:self.appealForm.remark}]
+      }
+      self.$axiosUser('post','api/pro/integral/appeal/create',params)
+        .then(res => {
+          if (res.data.code === 1){
+            self.appealForm.reviewer = []
+            self.appealForm.remark = ''
+            self.$toast('申诉已发起')
+            self.showAppeal = false
+          }else {
+            self.$toast(res.data.msg)
+          }
+        })
+        .finally(() => {
+          self.$toast.clear()
+          self.submitting = false
+        })
+    }
+  },
+  created() {
+    if (window.plus){
+      this.barHeight = window.plus.navigator.getStatusbarHeight()
     }
   },
   mounted () {
     this.getEventDetail()
+    this.getConfig()
   }
 }
 </script>

+ 49 - 10
src/point/view/integral/event_list.vue

@@ -1,12 +1,17 @@
 <template>
   <div class="event-list__container">
     <van-nav-bar title="积分事件" left-text="返回" @click-left="$route_back" left-arrow></van-nav-bar>
+    <van-notice-bar
+      left-icon="volume-o"
+      text="积分事件列表,根据角色数据权限返回对应的人员积分事件.用户可对自己的积分事件进行申诉,审批通过后积分事件将自动删除"
+    />
     <van-search placeholder="请输入事件内容搜索" v-model="searchParams.keyword" @input="keyVal()" />
     <van-dropdown-menu>
       <van-dropdown-item :title="dateItemTitle" ref="dateDropdownItem"><DateSelectorDropdown :title.sync="dateItemTitle" @onConfirm="onConfirmDate" /></van-dropdown-item>
       <van-dropdown-item :title="deptDropdownItemTitle" ref="deptDropdownItem"><DeptSelectorDropdown @onConfirm="onConfirmDept" /></van-dropdown-item>
-      <van-dropdown-item title="规则分类" ref="ruleDropdownItem"><RuleCategorySelDropdown @onConfirm="onConfirmRule" @onCancel="searchParams.rule_id = null"/></van-dropdown-item>
+      <van-dropdown-item title="规则" ref="ruleDropdownItem"><RuleCategorySelDropdown @onConfirm="onConfirmRule" @onCancel="searchParams.rule_id = null"/></van-dropdown-item>
       <van-dropdown-item :title="pointTypeDropdownItemTitle" :options="pointTypeOption" v-model="pointType" @change="onChangePointType" />
+      <van-dropdown-item v-model="searchParams.add_subtract"  :options="[{text:'全部',value:0},{text:'奖分',value: 1},{text:'扣分',value: 2}]" ><van-icon name="list-switch" slot="title" size="1.5em" /></van-dropdown-item>
     </van-dropdown-menu>
     <div class="event-list__content">
       <scroller ref="scroller" :on-refresh="refresh" :on-infinite="infinite" noDataText="我也是有底线的" :list="eventData">
@@ -27,7 +32,7 @@
               <span class="event-item__value red" v-if="item.point >= 0">+{{ item.point }}{{ $getTypesName(item.pt_id)}}</span>
               <span class="event-item__value green" v-else>{{ item.point }}{{ $getTypesName(item.pt_id) }}</span>
             </div>
-            <div class="event-content__text">
+            <div class="event-content__text input-ccc">
               <span>{{ item.remark }}</span>
             </div>
             <div class="event-time__text">
@@ -46,7 +51,7 @@ import Vue from 'vue';
 import moment from 'moment';
 
 import { _debounce, _throttle } from '@/utils/auth';
-import { DropdownMenu, DropdownItem, Empty, Search } from 'vant';
+import { DropdownMenu, DropdownItem, Empty, Search,NoticeBar } from 'vant';
 import DateSelectorDropdown from '@/components/DateSelectorDropdown';
 import DeptSelectorDropdown from '@/components/DeptSelectorDropdown';
 import RuleCategorySelDropdown from '@/components/RuleCategorySelDropdown';
@@ -54,7 +59,8 @@ import RuleCategorySelDropdown from '@/components/RuleCategorySelDropdown';
 Vue.use(Empty)
   .use(DropdownMenu)
   .use(DropdownItem)
-  .use(Search);
+  .use(Search)
+  .use(NoticeBar)
 
 export default {
   name: 'event_list',
@@ -67,6 +73,7 @@ export default {
       dateItemTitle: '本月',
       deptDropdownItemTitle: '全公司',
       eventData: [],
+      hasFinish: false,
       searchParams: {
         dept_ids: null,
         end_day: null,
@@ -77,10 +84,25 @@ export default {
         page_size: 10,
         rule_id: null,
         pt_id: pointTypeId,
-        keyword: ''
+        keyword: '',
+        add_subtract:0
       },
       types_list: {},
-      month: moment().format('YYYY-MM')
+      month: moment().format('YYYY-MM'),
+      add_subtract_items: [
+        {
+          value: '全部',
+          id: 0
+        },
+        {
+          value: '奖分',
+          id: 1
+        },
+        {
+          value: '扣分',
+          id: 2
+        },
+      ]
     };
   },
   components: {
@@ -98,7 +120,7 @@ export default {
     },
     pointTypeDropdownItemTitle() {
       if (this.pointType === -1) {
-        return '积分类';
+        return '积分类';
       }
       return this.pointTypeOption.find(a => a.value === this.pointType).text;
     },
@@ -135,9 +157,15 @@ export default {
     },
     refresh(done) {
       this.searchParams.page = 1;
+      this.hasFinish = false
       this.getEventData(done);
     },
     infinite(done) {
+      if (this.hasFinish){
+        done()
+        this.$refs.scroller.finishPullToRefresh()
+        return
+      }
       this.searchParams.page++;
       this.getEventData(done);
     },
@@ -216,16 +244,27 @@ export default {
             } else {
               this.eventData = this.eventData.concat(list);
             }
-            scroller.finishInfinite(list.length !== this.searchParams.page_size);
+            callback && callback();
+            scroller.finishPullToRefresh();
+
+            this.hasFinish = list.length !== this.searchParams.page_size
+
+            scroller.finishInfinite(this.hasFinish);
           } else {
-            scroller.finishInfinite(true);
+            this.hasFinish = true
+            scroller.finishInfinite(this.hasFinish);
           }
         })
         .finally(() => {
           this.loading = false;
-          callback && callback();
         });
     }
+  },
+  watch: {
+    'searchParams.add_subtract'(val,oVal){
+      this.searchParams.page = 1;
+      this.$refs.scroller.triggerPullToRefresh();
+    }
   }
 };
 </script>

+ 1 - 1
src/point/view/integral/integral_application.vue

@@ -19,7 +19,7 @@
             </template>
           </van-cell>
           <!--选择规则  -->
-          <RuleCategorySelectorCell v-if="rule_switch" required  ref="rule_selector" name="选择规则"  title="选择规则" v-model="itemRule"></RuleCategorySelectorCell>
+          <RuleCategorySelectorCell v-if="rule_switch" required  ref="rule_selector" name="选择规则"  title="选择规则" v-model="itemRule" scope/>
         </van-cell-group>
 
         <div v-for="(item, index) in items" :key="index">

+ 2 - 2
src/point/view/integral/integral_entry_n.vue

@@ -16,9 +16,9 @@
             </template>
           </van-cell>
           <!--选择规则  -->
-          <RuleCategorySelectorCell v-if="rule_switch" required  ref="rule_selector" name="选择规则"  title="选择规则" v-model="itemRule" :ptId="ptId"></RuleCategorySelectorCell>
+          <RuleCategorySelectorCell v-if="rule_switch" required  ref="rule_selector" name="选择规则"  title="选择规则" v-model="itemRule" :ptId="ptId" scope></RuleCategorySelectorCell>
           <!--选择分类  -->
-          <CategorySelectorCell v-if="!rule_switch" title="选择分类" ref="rule_selector2" v-model="ruleCate" required :ptId="ptId"></CategorySelectorCell>
+          <CategorySelectorCell v-if="!rule_switch" title="选择分类" ref="rule_selector2" v-model="ruleCate" required :ptId="ptId" scope></CategorySelectorCell>
         </van-cell-group>
 
         <div v-for="(item, index) in items" :key="index">

+ 2 - 2
src/point/view/integral/manager_reward_deduction.vue

@@ -1,6 +1,6 @@
 <template>
   <div class="mrd-container">
-   <van-nav-bar title="管理者奖扣" left-text="返回" @click-left="$route_back" left-arrow>
+   <van-nav-bar title="奖扣目标" left-text="返回" @click-left="$route_back" left-arrow>
       <div class="department" slot="right">
         <DeptSelectorBtn title="选择部门" v-model="dept" :multi="false"></DeptSelectorBtn>
       </div>
@@ -168,7 +168,7 @@ export default {
         complete:this.checkedAllStandard? 1:0
       };
       this.$socketApiTow.sendData(params,(res)=>{
-      	if (res.code == 1&&res.type=='es') {
+      	if (res.code === 1&&res.type === params.type) {
             let list=res.result.list;
             if (this.searchParams.page === 1) {
               this.list = list

+ 336 - 0
src/point/view/integral/reward_deduction_search.vue

@@ -0,0 +1,336 @@
+
+
+<template>
+  <div class="mrd-container">
+    <van-nav-bar title="奖扣信息" left-text="返回" @click-left="$route_back" left-arrow />
+    <van-notice-bar color="#1989fa" background="#ecf9ff" left-icon="info-o" mode="closeable">
+      管理者奖扣任务均为B分,对A分不做要求
+    </van-notice-bar>
+    <van-cell-group>
+      <DeptSelectorBtn title="选择部门" v-model="dept" :multi="false" :block="true"></DeptSelectorBtn>
+      <van-cell title="姓名" :value="searchForm.keyword" @click="showKeyword = true" :center="true" >
+        <van-icon name="arrow" slot="right-icon" v-if="!searchForm.keyword" />
+        <van-icon name="close" slot="right-icon" v-else style="margin-left: 10px" color="#646464" @click.stop="searchForm.keyword = ''" />
+      </van-cell>
+      <van-cell title="时间" :value="timeScopeText" is-link @click="showTimeScope = true" />
+    </van-cell-group>
+
+    <div class="mrd-content">
+      <scroller
+        ref="scroller"
+        :on-refresh="onRefresh"
+      >
+        <div class="mrd-list__item" v-for="item in dataList" :key="item.id" >
+          <div class="mrd-item__header">
+            <span>{{ item.name }}</span>
+          </div>
+          <div class="mrd-item__content">
+            <div class="mrd-item">
+              <span class="mrd-item__value">{{ item.reward_point}}</span>
+              <span class="mrd-item__label">奖分</span>
+            </div>
+            <div class="mrd-item">
+              <span class="mrd-item__value">{{ item.deduction_point}}</span>
+              <span class="mrd-item__label">扣分</span>
+            </div>
+            <div class="mrd-item">
+              <span class="mrd-item__value black-color">{{ item.ratio ? item.ratio : '--' }}</span>
+              <span class="mrd-item__label">奖扣比例</span>
+            </div>
+            <div class="mrd-item">
+              <span class="mrd-item__value black-color">{{ item.exec}}</span>
+              <span class="mrd-item__label">奖扣人次</span>
+            </div>
+          </div>
+        </div>
+        <noData :list="dataList" />
+
+      </scroller>
+    </div>
+
+
+<!--  姓名输入  -->
+    <van-dialog
+      v-model="showKeyword"
+      :close-on-click-overlay="true"
+      @confirm="searchForm.keyword = keyword"
+    >
+      <van-field label="姓名" placeholder="搜索姓名" v-model="keyword"></van-field>
+    </van-dialog>
+<!--  日期区间选择  -->
+    <van-calendar
+      v-model="showTimeScope"
+      type="range"
+      :allow-same-day="true"
+      :min-date="minDate"
+      :max-date="maxDate"
+      :default-date="timeScope"
+      :show-confirm="false"
+      color="#26A2FF"
+      @close="calendarClose"
+      @confirm="calendarConfirm"
+    />
+
+  </div>
+
+</template>
+
+
+<script>
+import Vue from 'vue'
+import moment from 'moment'
+import {Calendar, Empty, NoticeBar} from 'vant'
+import DeptSelectorBtn from '@/components/DeptSelectorBtn'
+import {_debounce } from '@/utils/auth'
+Vue.use(Empty).use(Calendar).use(NoticeBar)
+export default {
+  name: 'reward_deduction_search',
+  components:{DeptSelectorBtn},
+  data(){
+
+
+    let today = new Date();
+    let minDate = new Date();
+    minDate.setTime(today.getTime() - 3600 * 1000 * 24 * 30 * 6);
+    let maxDate = new Date(today.getFullYear(),today.getMonth(),1);
+    maxDate.setMonth(maxDate.getMonth() + 1);
+    maxDate.setDate(0);
+
+    let startDate = new Date();
+    startDate.setTime(today.getTime() - 3600 * 1000 * 24 * 7);
+    startDate = moment(startDate).format('YYYY-MM-DD');
+    let endDate = moment(today).format('YYYY-MM-DD');
+
+    return{
+      dept:[],
+      searchForm:{
+        startDate:startDate,
+        endDate:endDate,
+        deptId:0,
+        keyword:'',
+        page:1,
+        pageSize:10
+      },
+      showKeyword:false,
+      keyword:'',
+      showTimeScope:false,
+      timeScope:[new Date(startDate),new Date(endDate)],
+      minDate:minDate,
+      maxDate:maxDate,
+      dataList:[],
+      isLoading:false,
+      isFinished:true
+    }
+  },
+  watch:{
+    dept(val){
+      if (Array.isArray(val) && val.length > 0) {
+        this.searchForm.deptId = val[0].dept_id
+      } else {
+        this.searchForm.deptId = 0
+      }
+    },
+    timeScope(val){
+      this.searchForm.startDate = moment(val[0]).format('YYYY-MM-DD');
+      this.searchForm.endDate = moment(val[1]).format('YYYY-MM-DD');
+    },
+    'searchForm.deptId'(val,oVal){
+      if (val === oVal) return;
+      this.$refs.scroller.triggerPullToRefresh();
+    },
+    'searchForm.keyword'(val,oVal){
+      if (val === oVal) return;
+      this.$refs.scroller.triggerPullToRefresh();
+    },
+    'searchForm.startDate'(){
+      this.$refs.scroller.triggerPullToRefresh();
+    },
+    'searchForm.endDate'(){
+      this.$refs.scroller.triggerPullToRefresh();
+    },
+  },
+  computed:{
+    timeScopeText(){
+      return moment(this.searchForm.startDate).format('MM/DD') + '-' + moment(this.searchForm.endDate).format('MM/DD')
+    }
+  },
+  methods:{
+    calendarClose(){
+      this.showTimeScope = false;
+    },
+    calendarConfirm(event){
+      const [start,end] = event;
+      this.timeScope = [start,end];
+      this.showTimeScope = false;
+    },
+    onRefresh(done){
+      if (!this.searchForm.startDate || !this.searchForm.endDate) {
+        if (typeof done === 'function') done();
+        return;
+      }
+      let msg = {
+        type:'ess',
+        dept_id: this.searchForm.deptId,
+        employee_id:this.$userInfo().id,
+        start_date: this.searchForm.startDate,
+        end_date: this.searchForm.endDate,
+        keyword: this.searchForm.keyword,
+        page:0,
+        page_size:10
+      }
+      this.$socketApiTow.sendData(msg,(res)=>{
+        if (res.code !== 1 || res.type !== msg.type){
+          if (typeof done === 'function') done();
+          return;
+        }
+        this.dataList = res.result.list;
+        if (typeof done === 'function') done();
+      })
+    },
+  }
+}
+
+</script>
+
+<style scoped lang="less">
+.mrd-container {
+  & /deep/ .department .van-button {
+    background-color: transparent;
+    border: none;
+    color: #fff;
+    max-width: 2.5rem;
+    padding: 0;
+    overflow: hidden;
+    text-overflow: ellipsis;
+    white-space: nowrap;
+  }
+
+  & .mrd-filter__wrap {
+    position: relative;
+    padding: 0.15rem 0.32rem;
+
+    & /deep/ .van-checkbox__label {
+      font-size: 0.28rem;
+      color: #909399;
+    }
+
+    & /deep/ .van-checkbox__icon {
+      position: relative;
+      top: -0.05em;
+    }
+  }
+
+  & .mrd-content {
+    position: relative;
+    height: calc(100% - 5rem);
+  }
+
+  & .mrd-list__item {
+    margin-bottom: 0.24rem;
+    padding: 0 0.32rem 0.32rem 0.32rem;
+    font-size: 0.32rem;
+    color: #303133;
+    background: #fff;
+    touch-action: none;
+
+    & .mrd-item__header {
+      display: flex;
+      padding: 0.24rem 0;
+      align-items: center;
+
+      & .mrd-item__icon {
+        display: flex;
+        margin-right: 0.16rem;
+        width: 0.56rem;
+        height: 0.56rem;
+        font-size: 0.24rem;
+        color: #fff;
+        background: #26a2ff;
+        align-items: center;
+        justify-content: center;
+        border-radius: 100%;
+      }
+
+      & .mrd-item__standard {
+        margin-left: 0.2rem;
+        padding: 0.02rem 0.08rem;
+        font-size: 0.24rem;
+        color: #fff;
+        background: #53B87F;
+        border-radius: 0.06rem;
+      }
+    }
+
+    & .mrd-item__content {
+      display: flex;
+      flex-direction: row;
+
+      & .mrd-item {
+        display: flex;
+        flex: 1;
+        align-items: center;
+        justify-content: center;
+        flex-direction: column;
+
+        & /deep/ .icon-doubt {
+          position: absolute;
+          top: 0.13rem;
+          right: -0.3rem;
+        }
+
+        & .mrd-item__value {
+          color: #26a2ff;
+          font-size: 0.44rem;
+          font-weight: 600;
+
+          &.black-color {
+            color: #444444;
+          }
+        }
+
+        & .mrd-item__label {
+          position: relative;
+          display: inline-block;
+          padding-top: 0.04rem;
+          font-size: 0.28rem;
+          color: #303133;
+          font-weight: 400;
+        }
+
+        & .mrd-item__target {
+          padding-top: 0.08rem;
+          font-size: 0.24rem;
+          color: #909399;
+          font-weight: 400;
+        }
+      }
+    }
+
+    .mrd-standard__wrap {
+      display: flex;
+      padding-top: 0.1rem;
+      flex-direction: row;
+
+      .mrd-standard__item {
+        display: flex;
+        flex: 1;
+        justify-content: center;
+
+        & .mrd-standard__text {
+          padding: 0.02rem 0.08rem;
+          font-size: 0.24rem;
+          color: #fff;
+          background: #53B87F;
+          border-radius: 0.06rem;
+        }
+      }
+    }
+  }
+
+  & .van-list{
+    background-color: #F5F7FA;
+  }
+}
+
+
+</style>

+ 5 - 1
src/point/view/integral/rule_category_add.vue

@@ -4,7 +4,7 @@
     <div class="body_com has_header">
       <scroller>
         <van-cell-group>
-          <van-field v-model="data.name" label="分类名称" name="名称" placeholder="请输入名称" v-validate="'required|max:10'" required maxlength="10" show-word-limit/>
+          <van-field v-model="data.name" label="分类名称" name="名称" placeholder="请输入名称" v-validate="'required|max:20'" required maxlength="20" show-word-limit @input="onNameInput"/>
         </van-cell-group>
         <van-cell-group>
           <CategorySelectorCell title="选择父级分类" v-model="rule_cate" :max="2" :multi="false"></CategorySelectorCell>
@@ -20,6 +20,7 @@
 
 import CategorySelectorCell from '@/components/CategorySelectorCell'
 import DeptSelectorCell from '@/components/DeptSelectorCell'
+import {specialFilter} from "../../../utils/helper";
 export default {
   name: 'rule_category_add',
   components: {
@@ -87,6 +88,9 @@ export default {
         self.send_loading = false
         self.$toast.clear()
       })
+    },
+    onNameInput(v){
+      this.data.name = specialFilter(v)
     }
   },
   created () {

+ 6 - 2
src/point/view/integral/rule_category_edit.vue

@@ -4,7 +4,7 @@
     <div class="body_com has_header">
       <scroller>
         <van-cell-group>
-          <van-field v-model="data.name" label="分类名称" name="名称" placeholder="请输入名称" v-validate="'required|max:10'" required  maxlength="10" show-word-limit/>
+          <van-field v-model="data.name" label="分类名称" name="名称" placeholder="请输入名称" v-validate="'required|max:10'" required  maxlength="10" show-word-limit @input="onNameInput"/>
         </van-cell-group>
         <van-cell-group>
           <CategorySelectorCell title="选择父级分类" v-model="rule_cate" :max="2" :multi="false"></CategorySelectorCell>
@@ -23,6 +23,7 @@
 
 import CategorySelectorCell from '@/components/CategorySelectorCell'
 import DeptSelectorCell from '@/components/DeptSelectorCell'
+import {specialFilter} from "../../../utils/helper";
 export default {
   name: 'rule_category_edit',
   components: {
@@ -116,13 +117,16 @@ export default {
         self.send_loading = false
         self.$toast.clear()
       })
+    },
+    onNameInput(v){
+      this.data.name = specialFilter(v)
     }
   },
   created () {
     if (this.$route.query.rule_id) {
       this.data.rule_id = this.$route.query.rule_id
       this.data.pid = this.$route.query.pid
-      this.data.name = this.$route.query.rule_name
+      this.data.name = specialFilter(this.$route.query.rule_name)
       let departments = JSON.parse(this.$route.query.departments)
       if (departments.length > 0) {
         this.depts = departments.map(item => {

+ 5 - 1
src/point/view/integral/rule_item_add.vue

@@ -5,7 +5,7 @@
       <scroller>
         <van-cell-group>
           <van-cell required>
-            <Mtextarea required v-model="item.remark" placeholder="输入规则内容" :text_max="300" :imgs_max="3"></Mtextarea>
+            <Mtextarea required v-model="item.remark" placeholder="输入规则内容" :text_max="300" :imgs_max="3" @input="onRemarkInput" ></Mtextarea>
           </van-cell>
         </van-cell-group>
         <van-cell-group>
@@ -65,6 +65,7 @@ import { Switch } from 'vant'
 import Mtextarea from '@/components/Mtextarea'
 import NumberInput from '@/components/NumberInput'
 import CategorySelectorCell from '@/components/CategorySelectorCell'
+import {specialFilter} from "../../../utils/helper";
 
 Vue.use(Switch)
 export default {
@@ -181,6 +182,9 @@ export default {
           self.types_list.push(list[i])
         }
       }
+    },
+    onRemarkInput(v){
+      this.item.remark = specialFilter(v)
     }
   },
   created () {

+ 6 - 1
src/point/view/integral/rule_item_edit.vue

@@ -4,7 +4,7 @@
     <div class="body_com has_header">
       <scroller>
         <van-cell-group>
-          <van-cell><Mtextarea v-model="item.remark" placeholder="输入规则内容" :text_max="300" :imgs_max="3"></Mtextarea></van-cell>
+          <van-cell><Mtextarea v-model="item.remark" placeholder="输入规则内容" :text_max="300" :imgs_max="3" @input="onRemarkInput"></Mtextarea></van-cell>
         </van-cell-group>
         <van-cell-group>
           <van-cell title="分值" class="cell-right-4rem">
@@ -41,6 +41,7 @@ import NumberInput from '@/components/NumberInput';
 import CategorySelectorCell from '@/components/CategorySelectorCell';
 import Vue from 'vue';
 import { Switch } from 'vant';
+import {specialFilter} from "../../../utils/helper";
 
 Vue.use(Switch);
 export default {
@@ -175,6 +176,9 @@ export default {
           this.types_list.push(list[i]);
         }
       }
+    },
+    onRemarkInput(v){
+      this.item.remark = specialFilter(v)
     }
   },
   created() {
@@ -189,6 +193,7 @@ export default {
         this.rule_cate = [{ id: this.item.rule_id * 1, name: this.$route.query.rule_name }];
       }
     }
+    this.item.remark = specialFilter(this.item.remark)
     this.get_point_types();
   }
 };

+ 101 - 12
src/point/view/pointHome.vue

@@ -13,8 +13,8 @@
               <div class="blue" style="font-size: 26px;font-weight: 600;">{{showPoint? userStatistics.b:userStatistics.a}}</div>
             </div>
             <div class="point-box flex-box">
-              <span @click.stop="showPoint=!showPoint" style="border-top-left-radius: 4px;border-bottom-left-radius: 4px;border-right: none;" :class="showPoint? 'pointActive':''">B分</span>
-              <span @click.stop="showPoint=!showPoint" style="border-top-right-radius: 4px;border-bottom-right-radius: 4px;border-left: none;" :class="!showPoint? 'pointActive':''">A分</span>
+              <span class="tp" @click.stop="showPoint=!showPoint" style="border-top-left-radius: 4px;border-bottom-left-radius: 4px;border-right: none;" :class="showPoint? 'pointActive':''">B分</span>
+              <span class="tp" @click.stop="showPoint=!showPoint" style="border-top-right-radius: 4px;border-bottom-right-radius: 4px;border-left: none;" :class="!showPoint? 'pointActive':''">A分</span>
             </div>
           </div>
           <div class="flex-box-ce">
@@ -41,12 +41,25 @@
           </div>
         </div>
         <van-grid :border="false" style="background-color: #fff;position: relative;" class="border-bottom">
-
           <van-grid-item v-for="(app, app_index) in topMenuList" :dot="app.dot" :badge="app.badge" :key="app.code" @click="openUrl(4,app)" :text="app.code">
             <template slot="icon">
               <img :src="app.icon" style="-webkit-touch-callout: none;" />
             </template>
           </van-grid-item>
+          <van-grid-item @click="goAppeal" text="申诉">
+            <template #icon>
+              <img src="static/images/caback6.png" style="-webkit-touch-callout: none;"/>
+            </template>
+          </van-grid-item>
+          <van-grid-item @click="goDeptRank">
+            <template #text>
+              <van-loading v-if="!deptRank" type="spinner" size="10px"/>
+              <span class="van-grid-item__text" v-else>部门对比</span>
+            </template>
+            <template #icon>
+              <img src="static/images/callback1.png" style="-webkit-touch-callout: none;"/>
+            </template>
+          </van-grid-item>
 
           <van-grid-item v-for="(app, app_index) in common_menu" :key="app_index" @click="url_jump(app)" :icon="app.icon" :text="app.code">
             <template slot="icon">
@@ -133,10 +146,26 @@
             </div>
           </div>
         </div>
-        <div class="rankingLists flex-box-ce flex-center-center" @click="openUrl(3)" style="border-top: 1px solid #f1f1f1;">
-          <span>查看所有管理者奖扣</span>
-          <i class="van-icon van-icon-arrow van-cell__right-icon"></i>
-        </div>
+<!--        <div class="rankingLists flex-box-ce flex-center-center" @click="openUrl(3)" style="border-top: 1px solid #f1f1f1;">-->
+<!--          <span>查看管理者奖扣目标</span>-->
+<!--          <i class="van-icon van-icon-arrow van-cell__right-icon"></i>-->
+<!--        </div>-->
+<!--        <div class="rankingLists flex-box-ce flex-center-center" @click="openUrl(3)" style="border-top: 1px solid #f1f1f1;">-->
+<!--          <span>查看管理者奖扣信息</span>-->
+<!--          <i class="van-icon van-icon-arrow van-cell__right-icon"></i>-->
+<!--        </div>-->
+        <van-row type="flex" justify="center" align="center">
+          <van-col span="12" @click="openUrl(3)">
+            <div class="van-hairline--right" style="text-align: center; color: #909399; height: 3em; line-height: 3em; font-size: 0.28rem;">
+              <span style="line-height: 3em" >查看奖扣目标</span>
+            </div>
+          </van-col>
+          <van-col span="12" @click="openUrl(7)">
+            <div style="text-align: center; color: #909399;  height: 3em; line-height: 3em; font-size: 0.28rem;">
+              <span >查看奖扣信息</span>
+            </div>
+          </van-col>
+        </van-row>
       </div>
 
 <!--  团队PK    -->
@@ -174,8 +203,30 @@
       :min-date="pk.minDate"
       :max-date="pk.maxDate"
       :default-date="pkTimeScope"
+      :show-confirm="false"
       color="#26A2FF"
-    />
+    >
+      <template v-slot:title >
+        <van-row>
+          <van-col span="20">
+            <van-row type="flex" justify="space-between" style="height: 1rem;">
+              <van-col span="6" style="text-align: center; align-self: center;">
+                <van-tag type="success" size="medium" @click="timeScopeThisWeek">本周</van-tag>
+              </van-col>
+              <van-col span="6" style="text-align: center; align-self: center;">
+                <van-tag type="success" size="medium" @click="timeScopeLastWeek">上周</van-tag>
+              </van-col>
+              <van-col span="6" style="text-align: center; align-self: center;">
+                <van-tag type="primary" size="medium" @click="timeScopeThisMoth">本月</van-tag>
+              </van-col>
+              <van-col span="6" style="text-align: center; align-self: center;">
+                <van-tag type="primary" size="medium" @click="timeScopeLastMonth">上月</van-tag>
+              </van-col>
+            </van-row>
+          </van-col>
+        </van-row>
+      </template>
+    </van-calendar>
   </div>
 </template>
 
@@ -184,18 +235,19 @@
 import {getToken, setToken} from '@/utils/auth';
 import moment, {min} from 'moment';
 import Vue from 'vue';
-import { NoticeBar, Swipe, SwipeItem, Cell, Dialog,Popup  } from 'vant';
-import {authWebSocket} from "../../api/websocketTow";
+import { NoticeBar, Swipe, SwipeItem, Cell, Dialog,Popup,Loading  } from 'vant';
 Vue.use(NoticeBar)
   .use(Swipe)
   .use(SwipeItem)
   .use(Cell)
+  .use(Loading)
   .use(Popup);
 
 export default {
   name: 'pointHome',
   data() {
     return {
+      deptRank:false,
       userMonth:{task:{reward:{},deduction:{},exec:{}},ratio:{}},
 
       // rankingList: [], // 我的排名列表
@@ -288,6 +340,22 @@ export default {
     });
   },
   methods: {
+    timeScopeThisWeek(){
+      this.pkTimeScope = [new Date(moment().startOf('week').format('YYYY-MM-DD')),new Date(moment().endOf('week').format('YYYY-MM-DD'))]
+      this.pk.showDocDatePicker= false
+    },
+    timeScopeLastWeek(){
+      this.pkTimeScope = [new Date(moment().subtract(1,'week').startOf('week').format('YYYY-MM-DD')),new Date(moment().subtract(1,'week').endOf('week').format('YYYY-MM-DD'))]
+      this.pk.showDocDatePicker = false
+    },
+    timeScopeThisMoth(){
+      this.pkTimeScope = [new Date(moment().startOf('month').format('YYYY-MM-DD')),new Date(moment().endOf('month').format('YYYY-MM-DD'))]
+      this.pk.showDocDatePicker = false
+    },
+    timeScopeLastMonth(){
+      this.pkTimeScope = [new Date(moment().subtract(1,'month').startOf('month').format('YYYY-MM-DD')),new Date(moment().subtract(1,'month').endOf('month').format('YYYY-MM-DD'))]
+      this.pk.showDocDatePicker = false
+    },
     getCount(done) {
       var http1 = this.$axiosUser('get','/api/pro/integral/review/list', { type: 'waiting', page: 1,page_size:1, pt_id: 0, source_type: 0 }); // 获取为审批数量
       var http2 = this.$axiosUser('get','/api/pro/integral/work/list', { status: 'running', page: 1,page_size:1, pt_id: 0 }); // 获取任务数
@@ -567,8 +635,12 @@ export default {
               ratio: ratio,
               target_ratio: target_ratio
             }
-            this.userMonth=data
+            this.userMonth=data;
+
+            //ws数据初始化完成,部门排名才可以点击
+            this.deptRank = true;
             // this.$socketApiTow.closewebsocket();
+
         }
       }, true);
     },
@@ -617,6 +689,10 @@ export default {
           this.$router.push({ name: 'statistics_personal_a', query: { month: this.month } });
           break;
         }
+        case 7: {
+          this.$router.push({ name: 'reward_deduction_search' })
+          break;
+        }
       }
     },
     docCalendarConfirm(event){
@@ -669,12 +745,22 @@ export default {
         if (res.type !== type || res.code !== 1) return;
         this.pk.pkTeamList = res.result.teams;
         this.pk.teamLoading = false;
+
+        //ws数据初始化完成,部门排名才可以点击
+        this.deptRank = true;
       })
       this.$nextTick(() => {
         setTimeout(() => {
           this.restoreScrollerPosition()
         },50)
       })
+    },
+    goDeptRank(){
+      if (!this.deptRank) return;
+      this.$router.push({ name: 'dept_rank' });
+    },
+    goAppeal(){
+      this.$router.push({name:'appeal'})
     }
   },
   watch: {
@@ -700,7 +786,7 @@ export default {
 .point-box{
    border-radius: 2px;
 }
-.point-box span{
+.point-box .tp{
   padding: 0rem 0.2rem;
   border: 1px solid #c0c4cc;
   height: 0.4rem;
@@ -987,5 +1073,8 @@ export default {
   }
 }
 
+.dept-rank-active{
+  background-color: #F1F1F1;
+}
 
 </style>

+ 529 - 0
src/point/view/task/TaskEdit.vue

@@ -0,0 +1,529 @@
+<template>
+  <div>
+    <van-nav-bar
+      title="悬赏更新"
+      left-text="返回"
+      @click-left="$route_back"
+      left-arrow
+    />
+    <div class="content">
+      <scroller :is-need="isNeed">
+        <van-cell-group>
+          <van-cell required>
+            <Mtextarea
+              v-model="formData.task_name"
+              name="任务内容"
+              v-validate="'required|max:20'"
+              placeholder="请输入任务内容"
+              :text_max="20"
+              :imgs_max="3"
+              images
+              :imgs.sync="formData.file_list"
+            ></Mtextarea>
+          </van-cell>
+        </van-cell-group>
+
+        <van-cell-group class="point-field">
+          <van-cell title="积分类型" required id="task_types">
+            <template slot="right-icon">
+              <van-radio-group v-model="formData.pt_id" direction="horizontal" class="radio_button">
+                <van-radio checked-color class="list" :name="item.id" v-for="(item, index) in pts" v-if="item.code !== 'JX'" :key="index">{{ item.name }}</van-radio>
+              </van-radio-group>
+            </template>
+          </van-cell>
+          <van-cell title="指定规则">
+            <template slot="right-icon">
+              <van-radio-group
+                v-model="formData.rule_type"
+                direction="horizontal"
+              >
+                <van-radio class="list" :name="0" >
+                  <span class="rule_type_span">不指定</span>
+                </van-radio>
+                <van-radio class="list" :name="1" >
+                  <span class="rule_type_span">分类</span>
+                </van-radio>
+                <van-radio class="list" :name="2" >
+                  <span class="rule_type_span">规则</span>
+                </van-radio>
+              </van-radio-group>
+            </template>
+          </van-cell>
+
+          <!--     选择分类     -->
+          <CategorySelectorCell
+            v-if="formData.rule_type === 1"
+            title="细则分类"
+            v-model="rules"
+            required
+            :pt-id="formData.pt_id"
+            :multi="false"
+            scope
+          />
+
+          <!--选择规则  -->
+          <RuleCategorySelectorCell
+            v-if="formData.rule_type === 2"
+            :pt-id="formData.pt_id"
+            required
+            name="请选择积分规则"
+            title="积分规则"
+            v-model="rule_items"
+            scope
+            :multi="false"
+          >
+            <template slot="label">
+              <span style="color: red">{{ruleItemLabel}}</span>
+            </template>
+          </RuleCategorySelectorCell>
+
+          <van-cell title="任务积分" style="padding:0 0.32rem; padding-top:0.16rem;" :border="false" required/>
+          <NumberInput v-model="formData.base_point" v-validate="'required'"  :min="minPoint" :max="maxPoint"/>
+        </van-cell-group>
+
+        <van-cell-group>
+          <EmployeeSelectorCell
+            required
+            title="审批人"
+            iconType="records"
+            :show_manager_only="true"
+            v-model="reviewer"
+            v-validate="'required'"
+            name="审批人"
+            :multi="false"
+          />
+          <DateTimeCell
+            required
+            title="截止时间"
+            v-validate="'required'"
+            name="截止时间"
+            v-model="formData.expire_time"
+          />
+          <van-field v-model="formData.ahead_award_point" type="digit">
+            <template slot="label">
+              <div class="flex-box-ce">
+                <span>提前奖分(天)</span>
+                <span class="flex-1 red" style="text-align: right;">+</span>
+              </div>
+            </template>
+          </van-field>
+          <van-field v-model="formData.ahead_award_point_limit" type="digit" label="奖分上限">
+            <template slot="label">
+              <div class="flex-box-ce">
+                <span>奖分上限</span>
+                <span class="flex-1 red" style="text-align: right;">+</span>
+              </div>
+            </template>
+          </van-field>
+          <van-field v-model="formData.timeout_deduction_point" type="digit" label="逾期扣分(天)">
+            <template slot="label">
+              <div class="flex-box-ce">
+                <span>逾期扣分(天)</span>
+                <span class="flex-1 green" style="text-align: right;">-</span>
+              </div>
+            </template>
+          </van-field>
+          <van-field v-model="formData.timeout_deduction_point_limit" type="digit" label="扣分上限">
+            <template slot="label">
+              <div class="flex-box-ce">
+                <span>扣分上限</span>
+                <span class="flex-1 green" style="text-align: right;">-</span>
+              </div>
+            </template>
+          </van-field>
+        </van-cell-group>
+
+        <van-cell-group :border="false">
+          <van-cell title="任务备注"/>
+          <van-cell>
+            <Mtextarea v-model="formData.task_remark" placeholder="请输入关于任务备注" :text_max="300"/>
+          </van-cell>
+          <DeptSelectorCell title="可见范围" v-model="departments"></DeptSelectorCell>
+        </van-cell-group>
+
+
+        <van-button type="info" block @click="taskSubmit">确定修改</van-button>
+        <div style="height: 1rem;"></div>
+      </scroller>
+    </div>
+  </div>
+</template>
+
+<script>
+import Mtextarea from "@/components/Mtextarea";
+import RuleCategorySelectorCell from '@/components/RuleCategorySelectorCell1'
+import CategorySelectorCell from '@/components/CategorySelectorCell'
+import NumberInput from '@/components/NumberInput';
+import EmployeeSelectorCell from '@/components/EmployeeSelectorCell';
+import DateTimeCell from '@/components/DateTimeCell'
+import DeptSelectorCell from '@/components/DeptSelectorCell'
+
+export default {
+  name: "TaskEdit",
+  components:{
+    Mtextarea,
+    RuleCategorySelectorCell,
+    CategorySelectorCell,
+    NumberInput,
+    EmployeeSelectorCell,
+    DateTimeCell,
+    DeptSelectorCell
+  },
+  props:{
+    taskId:{
+      require:true,
+      type: String
+    }
+  },
+  data(){
+    return {
+      isNeed: !this.$getCache('isAndroid'),
+      pts:this.$getTypes,
+      rule_items:[],
+      rules:[],
+      reviewer:[],
+      departments:[],
+      hasInit:false,
+      formData:{
+        id:0,
+        pt_id:0,
+        base_point:0,
+        expire_time:'',
+        reviewer_id:0,
+        rule_type:0,
+        rule_id:0,
+        item_id:0,
+        rule_item:{
+          id:0,
+          remark:"",
+          cycle_type: 0,
+          is_attendance: 0,
+          max_point: 0,
+          min_point: 0,
+          prize_type: 0,
+          pt_id: 0,
+          range_type: 0,
+          rule_id: 0,
+        },
+        task_remark:'',
+        task_name:'',
+        file_list: [],
+        ahead_award_point:0,
+        ahead_award_point_limit:0,
+        timeout_deduction_point:0,
+        timeout_deduction_point_limit:0,
+        dept_ids:[],
+        dept_names:''
+      }
+    }
+  },
+  watch:{
+    'formData.pt_id'(v){
+      if (this.hasInit && this.formData.rule_type === 2) this.initRuleData()
+    },
+    'formData.rule_type'(v){
+      if(this.hasInit) this.initRuleData()
+    },
+    rules(rules){
+      if (this.hasInit) this.formData.rule_id = rules.length <= 0 ? 0 : rules[0].id
+    },
+    rule_items(items){
+      if (!this.hasInit) return
+      this.formData.rule_item = items.length <= 0 ? {
+        id:0,
+        remark:"",
+        cycle_type: 0,
+        is_attendance: 0,
+        max_point: 0,
+        min_point: 0,
+        prize_type: 0,
+        pt_id: 0,
+        range_type: 0,
+        rule_id: 0,
+      } : {
+        id:items[0].id,
+        remark:items[0].remark,
+        cycle_type: items[0].cycle_type,
+        is_attendance: items[0].is_attendance,
+        max_point: items[0].max_point,
+        min_point: items[0].min_point,
+        prize_type: items[0].prize_type,
+        pt_id: items[0].pt_id,
+        range_type: items[0].range_type,
+        rule_id: items[0].rule_id,
+      }
+      this.formData.rule_id = this.formData.rule_item.rule_id
+      this.formData.item_id = this.formData.rule_item.id
+      this.formData.base_point = this.formData.rule_item.min_point !== 0 ? this.formData.rule_item.min_point : 1
+    },
+    reviewer(v){
+      if (v.length === 0){
+        this.formData.reviewer_id = 0
+      } else {
+        this.formData.reviewer_id = v[0].id
+      }
+    },
+    departments(v){
+      if (v.length === 0){
+        this.formData.dept_ids = []
+      }else {
+        this.formData.dept_ids = v.map(item => item.dept_id)
+      }
+    },
+  },
+  computed:{
+    ruleItemLabel(){
+      if (this.formData.rule_item.id <= 0) return ''
+      let pt = this.pts.find( t => t.id === this.formData.rule_item.pt_id)
+      return this.formData.rule_item.range_type === 1 ? `${this.formData.rule_item.min_point} ${pt.name}` : `${this.formData.rule_item.min_point} - ${this.formData.rule_item.max_point} ${pt.name}`
+    },
+    minPoint(){
+      return this.formData.rule_type !== 2 ? 1 : (this.formData.rule_item.id <= 0 ? 1 : this.formData.rule_item.min_point)
+    },
+    maxPoint(){
+      return this.formData.rule_type !== 2 ? 100000 : (this.formData.rule_item.id <= 0 ? 1 : this.formData.rule_item.max_point)
+    }
+  },
+  methods:{
+    initRuleData(){
+      this.formData.rule_id = 0
+      this.formData.item_id = 0
+      this.formData.rule_item = {
+        id:0,
+        remark:"",
+        cycle_type: 0,
+        is_attendance: 0,
+        max_point: 0,
+        min_point: 0,
+        prize_type: 0,
+        pt_id: 0,
+        range_type: 0,
+        rule_id: 0,
+      }
+      this.formData.base_point = 1
+      this.rules = []
+      this.rule_items = []
+    },
+    getInfo(){
+      if (!this.taskId){
+        this.$toast.fail('悬赏信息丢失')
+        return
+      }
+
+      this.$toast.loading({
+        loadingType: 'spinner',
+        forbidClick:true
+      })
+
+      let data = {
+        task_id:this.taskId
+      }
+      this.hasInit = false
+      this.$axiosUser('get','/api/pro/integral/task',data)
+        .then(res => {
+          if (res.data.code !== 1) throw new Error(res.data.msg)
+
+          let info = res.data.data
+          let formData = {
+            id:info.id,
+            pt_id:info.pt_id,
+            base_point:info.point_config.base_point,
+            expire_time:info.expire_time,
+            reviewer_id:info.reviewer_id,
+            rule_type:0,
+            rule_id:info.rule_id,
+            item_id:info.item_id,
+            rule_item:{
+              id:0,
+              remark:"",
+              cycle_type: 0,
+              is_attendance: 0,
+              max_point: 0,
+              min_point: 0,
+              prize_type: 0,
+              pt_id: 0,
+              range_type: 0,
+              rule_id: 0,
+            },
+            task_remark:info.task_remark,
+            task_name:info.task_name,
+            task_file_list: info.task_file_list,
+            ahead_award_point:info.point_config.ahead_award_point,
+            ahead_award_point_limit:info.point_config.ahead_award_point_limit,
+            timeout_deduction_point:info.point_config.timeout_deduction_point,
+            timeout_deduction_point_limit:info.point_config.timeout_deduction_point_limit,
+            dept_ids:[],
+            dept_names:'',
+          }
+          if (info.item_info){
+            formData.rule_item = {
+              id:info.item_id,
+              remark:info.item_info.remark,
+              cycle_type: info.item_info.cycle_type,
+              is_attendance: info.item_info.is_attendance,
+              max_point: info.item_info.max_point,
+              min_point: info.item_info.min_point,
+              prize_type: info.item_info.prize_type,
+              pt_id: info.item_info.pt_id,
+              range_type: info.item_info.range_type,
+              rule_id: info.rule_id,
+            }
+            this.rule_items = [formData.rule_item]
+          } else if (info.rule_info){
+            this.rules = [{id:info.rule_info.id,name:info.rule_info.name}]
+          }
+          this.reviewer = [{id:info.reviewer_id,name:info.reviewer_name,img_url:info.reviewer_img_url}]
+          formData.rule_type = formData.item_id > 0 && formData.rule_id > 0 ? 2 : (formData.rule_id > 0 ? 1 : 0)
+          this.departments = []
+          if (info.department_info){
+            info.department_info.forEach((item,index) => {
+              formData.dept_ids.push(item.id)
+              this.departments.push({dept_id: item.id, dept_name: item.name})
+              formData.dept_names +=  index === 0 ? item.name : `,${item.name}`
+            })
+          }
+
+          this.formData = formData
+
+
+          this.$nextTick(() => {
+            this.hasInit = true
+          })
+        })
+        .catch(err => {
+          this.$toast.fail(err)
+        })
+        .finally(() => {
+          this.$toast.clear()
+        })
+
+    },
+    taskSubmit(){
+      if (this.formData.rule_type === 1 && this.formData.rule_id <= 0){
+        this.$toast.fail('请选择规则分类')
+        return
+      }
+      if (this.formData.rule_type === 2 && this.formData.item_id <= 0){
+        this.$toast.fail('请选择积分规则')
+        return
+      }
+      this.$validator.validate().then(result => {
+        if (!result){
+          this.$notify({type: 'danger', message: this.$validator.errors.items[0].msg});
+        }else {
+          this.sub()
+        }
+      })
+    },
+    ahead_timeout(item,arr,codes,code){
+      if(item){
+        if(arr){
+          if(Number(item) > Number(arr)){
+            this.$notify({type: 'danger', message: code + '上限不能小于每日' + codes});
+            return true
+          }
+        }else{
+          this.$notify({type: 'danger', message:codes + '不为0时,' + code + '上限不能为空'});
+          return true
+        }
+      }
+    },
+    sub(){
+      let data = {
+        id:this.formData.id,
+        pt_id:this.formData.pt_id,
+        task_name:this.formData.task_name,
+        task_remark:this.formData.task_remark,
+        base_point:this.formData.base_point,
+        expire_time:this.formData.expire_time,
+        reviewer_id:this.formData.reviewer_id,
+        timeout_deduction_point:this.formData.timeout_deduction_point,
+        timeout_deduction_point_limit:this.formData.timeout_deduction_point_limit,
+        ahead_award_point:this.formData.ahead_award_point,
+        ahead_award_point_limit:this.formData.ahead_award_point_limit,
+        dept_ids:this.formData.dept_ids,
+        rule_id:this.formData.rule_id,
+        item_id:this.formData.item_id,
+      }
+      if (!data.ahead_award_point && data.ahead_award_point_limit) {
+        this.$notify({type: 'danger', message: '奖分上限不为0时,提前奖分不能为空'});
+        return;
+      } else if (data.ahead_award_point && !data.ahead_award_point_limit) {
+        this.$notify({type: 'danger', message: '提前奖分不为0时,奖分上限不能为空'});
+        return;
+      }
+      if (!data.timeout_deduction_point && data.timeout_deduction_point_limit) {
+        this.$notify({type: 'danger', message: '扣分上限不为0时,逾期扣分不能为空'});
+        return;
+      } else if (data.timeout_deduction_point && !data.timeout_deduction_point_limit) {
+        this.$notify({type: 'danger', message: '逾期扣分不为0时,扣分上限不能为空'});
+        return;
+      }
+
+      if (this.ahead_timeout(data.ahead_award_point, data.ahead_award_point_limit, '提前奖分', '奖分')) return;
+      if (this.ahead_timeout(data.timeout_deduction_point, data.timeout_deduction_point_limit, '逾期扣分', '扣分')) return;
+
+      let point_limit = this.$userInfo().point_config.point_limit ? this.$userInfo().point_config.point_limit.find(pt => pt.pt_id === 3) : null
+      if (!this.$userInfo().is_creator && point_limit) {
+        let entry_limit = Number(point_limit.point);
+        if (entry_limit > 0) {
+          if (data.ahead_award_point > entry_limit || data.timeout_deduction_point > entry_limit) {
+            this.$notify({type: 'danger', message: '每日奖扣分 不能超过您的奖扣分权限(您的奖扣分权限:' + entry_limit + '分)'});
+            return;
+          }
+          if (data.ahead_award_point_limit > entry_limit * 10 || data.timeout_deduction_point_limit > entry_limit * 10) {
+            this.$notify({type: 'danger', message: '奖扣分上限不能超过' + entry_limit * 10 + '分(您的奖扣分权限' + entry_limit + '分*10)'});
+            return;
+          }
+        }
+      }
+
+      let self = this
+      self.$toast.loading({
+        loadingType: 'spinner',
+        forbidClick:true
+      })
+
+      self.$axiosUser('post','/api/pro/integral/task/update',data)
+        .then(res => {
+          if (res.data.code !== 1) throw new Error(res.data.msg)
+
+          self.$toast.success(res.data.msg)
+          setTimeout(() => {
+            self.$route_back()
+          },500)
+        })
+        .catch(err => {
+          self.$toast.fail(err)
+        })
+        .finally(() => {
+          self.$toast.clear()
+        })
+
+
+    }
+  },
+  activated() {
+    this.getInfo()
+  }
+}
+</script>
+
+
+<style scoped lang="less">
+.content{
+  height: calc(100% - 0.92rem);
+  position: relative;
+  overflow-y: scroll;
+}
+.point-field /deep/ .van-cell__title.van-field__label span {
+  width: 0;
+  color: transparent;
+  height: 0;
+  overflow: hidden;
+  font-size: 0;
+}
+.point-field /deep/ .van-cell__title {
+  width: 0;
+}
+</style>

+ 520 - 0
src/point/view/task/WorkEdit.vue

@@ -0,0 +1,520 @@
+<template>
+  <div>
+    <van-nav-bar
+      title="任务更新"
+      left-text="返回"
+      @click-left="$route_back"
+      left-arrow
+    />
+    <div class="content">
+      <scroller :is-need="isNeed">
+        <van-cell-group>
+          <van-cell required>
+            <Mtextarea
+              v-model="formData.task_name"
+              name="任务内容"
+              v-validate="'required|max:20'"
+              placeholder="请输入任务内容"
+              :text_max="20"
+              :imgs_max="3"
+              images
+              :imgs.sync="formData.file_list"
+            ></Mtextarea>
+          </van-cell>
+        </van-cell-group>
+
+        <van-cell-group class="point-field">
+          <van-cell title="积分类型" required id="task_types">
+            <template slot="right-icon">
+              <van-radio-group v-model="formData.pt_id" direction="horizontal" class="radio_button">
+                <van-radio checked-color class="list" :name="item.id" v-for="(item, index) in pts" v-if="item.code !== 'JX'" :key="index">{{ item.name }}</van-radio>
+              </van-radio-group>
+            </template>
+          </van-cell>
+          <van-cell title="指定规则">
+            <template slot="right-icon">
+              <van-radio-group
+                v-model="formData.rule_type"
+                direction="horizontal"
+              >
+                <van-radio class="list" :name="0" >
+                  <span class="rule_type_span">不指定</span>
+                </van-radio>
+                <van-radio class="list" :name="1" >
+                  <span class="rule_type_span">分类</span>
+                </van-radio>
+                <van-radio class="list" :name="2" >
+                  <span class="rule_type_span">规则</span>
+                </van-radio>
+              </van-radio-group>
+            </template>
+          </van-cell>
+
+          <!--     选择分类     -->
+          <CategorySelectorCell
+            v-if="formData.rule_type === 1"
+            title="细则分类"
+            v-model="rules"
+            required
+            :pt-id="formData.pt_id"
+            :multi="false"
+            scope
+          />
+
+          <!--选择规则  -->
+          <RuleCategorySelectorCell
+            v-if="formData.rule_type === 2"
+            :pt-id="formData.pt_id"
+            required
+            name="请选择积分规则"
+            title="积分规则"
+            v-model="rule_items"
+            scope
+            :multi="false"
+          >
+            <template slot="label">
+              <span style="color: red">{{ruleItemLabel}}</span>
+            </template>
+          </RuleCategorySelectorCell>
+
+          <van-cell title="任务积分" style="padding:0 0.32rem; padding-top:0.16rem;" :border="false" required/>
+          <NumberInput v-model="formData.base_point" v-validate="'required'"  :min="minPoint" :max="maxPoint"/>
+        </van-cell-group>
+
+        <van-cell-group>
+          <EmployeeSelectorCell
+            required
+            title="执行人"
+            :max="10"
+            is_employee_list
+            v-validate="'required'"
+            :employee_list="$userInfo().employee_detail.manage_scope"
+            name="执行人"
+            :multi="false"
+            v-model="executor_name"
+          />
+          <EmployeeSelectorCell
+            required
+            title="审批人"
+            iconType="records"
+            :show_manager_only="true"
+            v-model="reviewer"
+            v-validate="'required'"
+            name="审批人"
+            :multi="false"
+          />
+          <DateTimeCell
+            required
+            title="截止时间"
+            v-validate="'required'"
+            name="截止时间"
+            v-model="formData.expire_time"
+          />
+          <van-field v-model="formData.ahead_award_point" type="digit">
+            <template slot="label">
+              <div class="flex-box-ce">
+                <span>提前奖分(天)</span>
+                <span class="flex-1 red" style="text-align: right;">+</span>
+              </div>
+            </template>
+          </van-field>
+          <van-field v-model="formData.ahead_award_point_limit" type="digit" label="奖分上限">
+            <template slot="label">
+              <div class="flex-box-ce">
+                <span>奖分上限</span>
+                <span class="flex-1 red" style="text-align: right;">+</span>
+              </div>
+            </template>
+          </van-field>
+          <van-field v-model="formData.timeout_deduction_point" type="digit" label="逾期扣分(天)">
+            <template slot="label">
+              <div class="flex-box-ce">
+                <span>逾期扣分(天)</span>
+                <span class="flex-1 green" style="text-align: right;">-</span>
+              </div>
+            </template>
+          </van-field>
+          <van-field v-model="formData.timeout_deduction_point_limit" type="digit" label="扣分上限">
+            <template slot="label">
+              <div class="flex-box-ce">
+                <span>扣分上限</span>
+                <span class="flex-1 green" style="text-align: right;">-</span>
+              </div>
+            </template>
+          </van-field>
+        </van-cell-group>
+        <van-cell-group :border="false">
+          <van-cell title="任务备注"/>
+          <van-cell>
+            <Mtextarea v-model="formData.task_remark" placeholder="请输入关于任务备注" :text_max="300"/>
+          </van-cell>
+        </van-cell-group>
+
+        <van-button type="info" block @click="taskSubmit">确定修改</van-button>
+        <div style="height: 1rem;"></div>
+      </scroller>
+    </div>
+  </div>
+</template>
+
+<script>
+import Mtextarea from "@/components/Mtextarea";
+import RuleCategorySelectorCell from '@/components/RuleCategorySelectorCell1'
+import CategorySelectorCell from '@/components/CategorySelectorCell'
+import NumberInput from '@/components/NumberInput';
+import EmployeeSelectorCell from '@/components/EmployeeSelectorCell';
+import DateTimeCell from '@/components/DateTimeCell'
+
+export default {
+  name: "WorkEdit",
+  components: {
+    Mtextarea,
+    RuleCategorySelectorCell,
+    CategorySelectorCell,
+    NumberInput,
+    EmployeeSelectorCell,
+    DateTimeCell,
+  },
+  props:{
+    workId:{
+      require:true,
+      type: String
+    }
+  },
+  data() {
+    return {
+      isNeed: !this.$getCache('isAndroid'),
+      pts:this.$getTypes,
+      rule_items:[],
+      rules:[],
+      executor_name:[],
+      reviewer:[],
+      hasInit:false,
+      formData:{
+        id:0,
+        pt_id:0,
+        publisher_id:0,
+        base_point:0,
+        expire_time:'',
+        reviewer_id:0,
+        rule_type:0,
+        rule_id:0,
+        item_id:0,
+        rule_item:{
+          id:0,
+          remark:"",
+          cycle_type: 0,
+          is_attendance: 0,
+          max_point: 0,
+          min_point: 0,
+          prize_type: 0,
+          pt_id: 0,
+          range_type: 0,
+          rule_id: 0,
+        },
+        task_remark:'',
+        task_name:'',
+        targets:[],
+        file_list: [],
+        ahead_award_point:0,
+        ahead_award_point_limit:0,
+        timeout_deduction_point:0,
+        timeout_deduction_point_limit:0,
+      }
+    }
+  },
+  watch:{
+    'formData.pt_id'(v){
+      if (this.hasInit && this.formData.rule_type === 2) this.initRuleData()
+    },
+    executor_name(v){
+      if (v.length === 0){
+        this.formData.targets = []
+      } else {
+        this.formData.targets = [v[0].id]
+      }
+    },
+    'formData.rule_type'(v){
+      if (this.hasInit) this.initRuleData()
+    },
+    rules(rules){
+      if (this.hasInit) this.formData.rule_id = rules.length <= 0 ? 0 : rules[0].id
+    },
+    rule_items(items){
+      if (!this.hasInit) return
+      this.formData.rule_item = items.length <= 0 ? {
+        id:0,
+        remark:"",
+        cycle_type: 0,
+        is_attendance: 0,
+        max_point: 0,
+        min_point: 0,
+        prize_type: 0,
+        pt_id: 0,
+        range_type: 0,
+        rule_id: 0,
+      } : {
+        id:items[0].id,
+        remark:items[0].remark,
+        cycle_type: items[0].cycle_type,
+        is_attendance: items[0].is_attendance,
+        max_point: items[0].max_point,
+        min_point: items[0].min_point,
+        prize_type: items[0].prize_type,
+        pt_id: items[0].pt_id,
+        range_type: items[0].range_type,
+        rule_id: items[0].rule_id,
+      }
+      this.formData.rule_id = this.formData.rule_item.rule_id
+      this.formData.item_id = this.formData.rule_item.id
+      this.formData.base_point = this.formData.rule_item.min_point !== 0 ? this.formData.rule_item.min_point : 1
+    },
+    reviewer(v){
+      if (v.length === 0){
+        this.formData.reviewer_id = 0
+      } else {
+        this.formData.reviewer_id = v[0].id
+      }
+    }
+  },
+  computed:{
+    ruleItemLabel(){
+      if (this.formData.rule_item.id <= 0) return ''
+      let pt = this.pts.find( t => t.id === this.formData.rule_item.pt_id)
+      return this.formData.rule_item.range_type === 1 ? `${this.formData.rule_item.min_point} ${pt.name}` : `${this.formData.rule_item.min_point} - ${this.formData.rule_item.max_point} ${pt.name}`
+    },
+    minPoint(){
+      return this.formData.rule_type !== 2 ? 1 : (this.formData.rule_item.id <= 0 ? 1 : this.formData.rule_item.min_point)
+    },
+    maxPoint(){
+      return this.formData.rule_type !== 2 ? 100000 : (this.formData.rule_item.id <= 0 ? 1 : this.formData.rule_item.max_point)
+    }
+  },
+  methods:{
+    initRuleData(){
+      this.formData.rule_id = 0
+      this.formData.item_id = 0
+      this.formData.rule_item = {
+        id:0,
+        remark:"",
+        cycle_type: 0,
+        is_attendance: 0,
+        max_point: 0,
+        min_point: 0,
+        prize_type: 0,
+        pt_id: 0,
+        range_type: 0,
+        rule_id: 0,
+      }
+      this.formData.base_point = 1
+      this.rules = []
+      this.rule_items = []
+    },
+    getInfo(){
+      if (!this.workId){
+        this.$toast.fail('任务信息丢失')
+        return
+      }
+
+      this.$toast.loading({
+        loadingType: 'spinner',
+        forbidClick:true
+      })
+
+      this.hasInit = false
+      this.$axiosUser('get', '/api/pro/integral/work', { work_id: this.workId })
+        .then(res => {
+          if (res.data.code !== 1){
+            this.$toast.fail(res.data.msg)
+            return
+          }
+          let info = res.data.data
+          this.formData = {
+            id:info.id,
+            pt_id:info.pt_id,
+            publisher_id:info.publisher_id,
+            base_point:info.point_config.base_point,
+            expire_time:info.expire_time,
+            reviewer_id:info.reviewer_id,
+            rule_type:0,
+            rule_id:info.rule_id,
+            item_id:info.item_id,
+            rule_item:{
+              id:0,
+              remark:"",
+              cycle_type: 0,
+              is_attendance: 0,
+              max_point: 0,
+              min_point: 0,
+              prize_type: 0,
+              pt_id: 0,
+              range_type: 0,
+              rule_id: 0,
+            },
+            task_remark:info.task_remark,
+            task_name:info.task_name,
+            targets:[info.employee_id],
+            file_list: info.task_file_list ? info.task_file_list : [],
+            ahead_award_point:info.point_config.ahead_award_point,
+            ahead_award_point_limit:info.point_config.ahead_award_point_limit,
+            timeout_deduction_point:info.point_config.timeout_deduction_point,
+            timeout_deduction_point_limit:info.point_config.timeout_deduction_point_limit,
+          }
+          if (info.item_info){
+            this.formData.rule_item = {
+              id:info.item_id,
+              remark:info.item_info.remark,
+              cycle_type: info.item_info.cycle_type,
+              is_attendance: info.item_info.is_attendance,
+              max_point: info.item_info.max_point,
+              min_point: info.item_info.min_point,
+              prize_type: info.item_info.prize_type,
+              pt_id: info.item_info.pt_id,
+              range_type: info.item_info.range_type,
+              rule_id: info.rule_id,
+            }
+            this.rule_items = [this.formData.rule_item]
+          } else if (info.rule_info){
+            this.rules = [{id:info.rule_info.id,name:info.rule_info.name}]
+          }
+          this.executor_name = [{id:info.employee_id,name:info.employee_name,img_url:info.img_url}]
+          this.reviewer = [{id:info.reviewer_id,name:info.reviewer_name,img_url:info.reviewer_img_url}]
+          this.formData.rule_type = this.formData.item_id > 0 && this.formData.rule_id > 0 ? 2 : (this.formData.rule_id > 0 ? 1 : 0)
+
+
+          this.$nextTick(() => {
+            this.hasInit = true
+          })
+        })
+        .finally(() => {
+          this.$toast.clear()
+        })
+    },
+    taskSubmit(){
+      if (this.formData.rule_type === 1 && this.formData.rule_id <= 0){
+        this.$toast.fail('请选择规则分类')
+        return
+      }
+      if (this.formData.rule_type === 2 && this.formData.item_id <= 0){
+        this.$toast.fail('请选择积分规则')
+        return
+      }
+      this.$validator.validate().then(result => {
+        if (!result){
+          this.$notify({type: 'danger', message: this.$validator.errors.items[0].msg});
+        }else {
+          this.sub()
+        }
+      })
+    },
+    ahead_timeout(item,arr,codes,code){
+      if(item){
+        if(arr){
+          if(Number(item) > Number(arr)){
+            this.$notify({type: 'danger', message: code + '上限不能小于每日' + codes});
+            return true
+          }
+        }else{
+          this.$notify({type: 'danger', message:codes + '不为0时,' + code + '上限不能为空'});
+          return true
+        }
+      }
+    },
+    sub(){
+      let data = {
+        id:this.formData.id,
+        targets:this.formData.targets,
+        pt_id:this.formData.pt_id,
+        task_name:this.formData.task_name,
+        task_remark:this.formData.task_remark,
+        base_point:Number(this.formData.base_point),
+        expire_time:this.formData.expire_time,
+        package_id:0,
+        weight:0,
+        file_list:this.formData.file_list,
+        reviewer_id:this.formData.reviewer_id,
+        ahead_award_point:this.formData.ahead_award_point,
+        ahead_award_point_limit:this.formData.ahead_award_point_limit,
+        timeout_deduction_point:this.formData.timeout_deduction_point,
+        timeout_deduction_point_limit:this.formData.timeout_deduction_point_limit,
+        rule_id:this.formData.rule_id,
+        item_id:this.formData.item_id,
+      }
+      if (!data.ahead_award_point && data.ahead_award_point_limit) {
+        this.$notify({type: 'danger', message: '奖分上限不为0时,提前奖分不能为空'});
+        return;
+      } else if (data.ahead_award_point && !data.ahead_award_point_limit) {
+        this.$notify({type: 'danger', message: '提前奖分不为0时,奖分上限不能为空'});
+        return;
+      }
+      if (!data.timeout_deduction_point && data.timeout_deduction_point_limit) {
+        this.$notify({type: 'danger', message: '扣分上限不为0时,逾期扣分不能为空'});
+        return;
+      } else if (data.timeout_deduction_point && !data.timeout_deduction_point_limit) {
+        this.$notify({type: 'danger', message: '逾期扣分不为0时,扣分上限不能为空'});
+        return;
+      }
+
+      if (this.ahead_timeout(data.ahead_award_point, data.ahead_award_point_limit, '提前奖分', '奖分')) return;
+      if (this.ahead_timeout(data.timeout_deduction_point, data.timeout_deduction_point_limit, '逾期扣分', '扣分')) return;
+
+      let point_limit = this.$userInfo().point_config.point_limit ? this.$userInfo().point_config.point_limit.find(pt => pt.pt_id === 3) : null
+
+      if (!this.$userInfo().is_creator && point_limit) {
+        let entry_limit = Number(point_limit.point);
+        if (entry_limit > 0) {
+          if (data.ahead_award_point > entry_limit || data.timeout_deduction_point > entry_limit) {
+            this.$notify({type: 'danger', message: '每日奖扣分 不能超过您的奖扣分权限(您的奖扣分权限:' + entry_limit + '分)'});
+            return;
+          }
+          if (data.ahead_award_point_limit > entry_limit * 10 || data.timeout_deduction_point_limit > entry_limit * 10) {
+            this.$notify({type: 'danger', message: '奖扣分上限不能超过' + entry_limit * 10 + '分(您的奖扣分权限' + entry_limit + '分*10)'});
+            return;
+          }
+        }
+      }
+
+      let self = this
+      self.$toast.loading({
+        loadingType: 'spinner',
+        forbidClick:true
+      })
+      self.$axiosUser('post', '/api/pro/integral/work/update', data)
+        .then(res => {
+          if (res.data.code !== 1){
+            self.$toast.fail(res.data.msg)
+            return
+          }
+          self.$toast.success(res.data.msg)
+          setTimeout(() => {
+            self.$route_back()
+          },500)
+        })
+        .finally(() => {
+          self.$toast.clear()
+        })
+    }
+  },
+  activated() {
+    this.getInfo()
+  }
+}
+</script>
+
+<style scoped lang="less">
+.content{
+  height: calc(100% - 0.92rem);
+  position: relative;
+  overflow-y: scroll;
+}
+.point-field /deep/ .van-cell__title.van-field__label span {
+  width: 0;
+  color: transparent;
+  height: 0;
+  overflow: hidden;
+  font-size: 0;
+}
+.point-field /deep/ .van-cell__title {
+  width: 0;
+}
+</style>

+ 14 - 2
src/point/view/task/my_publish.vue

@@ -108,7 +108,7 @@
 
       <div slot="repetitive">
         <van-cell-group class="list_box" :border="false">
-          <van-cell v-for="(item, index) in list" style="border-bottom: 17px solid #F5F7FA;" :key="index" @click="repetitive_detail(item)">
+          <van-cell v-for="(item, index) in list" style="border-bottom: 17px solid #F5F7FA;" :key="index" @click="repetitive_detail(item)" v-bind:class="scheduleClassName(item)">
             <template slot="title">
               <span class="title_name">{{ item.name }}</span>
             </template>
@@ -194,7 +194,7 @@ export default {
   computed: {
     hasData() {
       return this.loading || (Array.isArray(this.list) && this.list.length > 0);
-    }
+    },
   },
   // 方法
   methods: {
@@ -321,7 +321,14 @@ export default {
     // 时间对比
     date_contrast(date) {
       return moment(this.date) > moment(date);
+    },
+    scheduleClassName(schedule){
+      if (!schedule.schedule_expire_time) return "";
+      let now = new Date();
+      let expire_date = new Date(schedule.schedule_expire_time);
+      return now >= expire_date ? "schedule-expire" : "";
     }
+
   },
   // 组件挂载完成
   mounted() {
@@ -415,4 +422,9 @@ export default {
   padding: 0;
   margin-right: 0.1rem;
 }
+
+.schedule-expire{
+  background-color: oldlace;
+}
+
 </style>

+ 4 - 3
src/point/view/task/my_task.vue

@@ -131,7 +131,7 @@
                 <van-button class="fr complete_task" v-show="item.status == 1" type="info" @click.stop="complete_task(item)" size="small">完成任务</van-button>
                 <span class="fr orange bg" v-show="item.review_status == 0">待处理</span>
                 <span class="fr green  bg" v-show="item.review_status == 1">已通过</span>
-                <span class="fr red bg" v-show="item.review_status == 2">已驳回</span>
+                <span class="fr red bg" v-show="item.review_status == 2">已拒绝</span>
               </div>
             </template>
           </van-cell>
@@ -171,7 +171,7 @@ export default {
       time: moment().format('YYYY-MM-DD HH:mm'),
       date: moment().format('YYYY-MM-DD'),
       tips: '暂无数据',
-      title: '我的任务',
+      title: '我负责的',
       loading: true,
       activeNames: '2',
       filter: {
@@ -184,6 +184,7 @@ export default {
       },
       tabsOption: [
         { title: '待完成', value: 'running' },
+        { title: '驳回重做', value: 'rewrite' },
         { title: '待审批', value: 'complete' },
         { title: '已审批', value: 'reviewed' }
       ],
@@ -251,7 +252,7 @@ export default {
       }
     },
     onRefresh (params) {
-      if(this.filter.status=='running'){
+      if(this.filter.status === 'running'){
         this.getToDay(false,params.done)
       }else{
         this.get_list(false,params.done)

+ 297 - 66
src/point/view/task/repetitive_tasks_detail.vue

@@ -9,74 +9,243 @@
     </van-nav-bar>
     <div class="body_com has_header">
       <scroller class="scroller-top">
-        <van-cell-group>
-          <div class="flex-box item-box">
-            <div class="laber">任务内容</div>
-            <div class="flex-1">{{info.name}}</div>
-          </div>
-          <div class="flex-box item-box" v-if="info.remark">
-            <div class="laber">任务备注</div>
-            <div class="flex-1">{{info.remark}}</div>
-          </div>
-          <div class="flex-box item-box flex-v-ce">
-            <div class="laber">执行周期</div>
-            <div class="flex-1">{{info.target_info.length>0? '临时任务-':'悬赏任务-'}}{{info.task_cycle_mark}}</div>
-          </div>
-          <div class="flex-box item-box flex-v-ce" v-if="info.point_config.base_point">
-            <div class="laber">任务积分</div>
-            <div class="flex-1">{{info.point_config.base_point}}{{info.pt_name}}</div>
-          </div>
-          <div class="flex-box item-box flex-v-ce">
-            <div class="laber">发布人</div>
-            <div class="flex-1">{{info.owner_name}}</div>
-          </div>
-          <div class="flex-box item-box">
-            <div class="laber">截止时间</div>
-            <div class="flex-1" v-if="info.task_cycle==1">{{info.task_cycle_mark}}{{info.task_cycle_value > 9 ? info.task_cycle_value + ': 00' : '0' + info.task_cycle_value + ': 00'}}点截止</div>
-            <div class="flex-1" v-if="info.task_cycle==2">{{info.task_cycle_mark}}{{weekList[info.task_cycle_value - 1] }}截止</div>
-            <div class="flex-1" v-if="info.task_cycle==3">{{info.task_cycle_mark}}{{info.task_cycle_value}}号截止</div>
-          </div>
-          <div class="flex-box item-box flex-v-ce">
-            <div class="laber">可见范围</div>
-            <div class="flex-1" v-if="info.department_info.length>0">
-              <span v-for="item in info.department_info" :key="item.id">{{item.name}},</span>
-            </div>
-            <div class="flex-1" v-else>全公司</div>
-          </div>
-          <div class="flex-box item-box flex-v-ce" v-if="info.point_config.ahead_award_point">
-            <div class="laber">提前奖分</div>
-            <div class="flex-1">{{info.point_config.ahead_award_point}}B分/天</div>
-          </div>
-          <div class="flex-box item-box flex-v-ce" v-if="info.point_config.ahead_award_point_limit">
-            <div class="laber">奖分上限</div>
-            <div class="flex-1">{{info.point_config.ahead_award_point_limit}}B分</div>
-          </div>
-          <div class="flex-box item-box flex-v-ce" v-if="info.point_config.timeout_deduction_point">
-            <div class="laber">逾期扣分</div>
-            <div class="flex-1">{{info.point_config.timeout_deduction_point}}B分/天</div>
-          </div>
-          <div class="flex-box item-box flex-v-ce" v-if="info.point_config.timeout_deduction_point_limit">
-            <div class="laber">扣分上限</div>
-            <div class="flex-1">{{info.point_config.timeout_deduction_point_limit}}B分</div>
-          </div>
-
-
-        </van-cell-group>
-        <van-cell-group class="padding-cell-group">
-          <div class="tip">审批人</div>
-          <div style="width:0.9rem; margin-top:0.16rem;">
-              <userImage :user_name="info.reviewer_name" :id="parseInt(info.reviewer_id)"  width="0.8rem" height="0.8rem"  ></userImage>
-            <div style=" font-size: 0.2rem; text-align: center;">{{info.reviewer_name}}</div>
-          </div>
+        <van-cell-group inset>
+          <van-cell
+            title-class="align_self"
+            value-class="align_self"
+          >
+            <template slot="icon">
+              <user-image
+                class="fl"
+                :img_url="info.owner_img_url"
+                :user_name="info.owner_name"
+              />
+            </template>
+            <template slot="title">
+              {{info.owner_name}}&nbsp;
+              {{$getTypesName(info.pt_id)}}{{scheduleTypeMark}}&nbsp;
+            </template>
+            <template slot="default">
+              <van-tag type="primary" size="medium" >{{info.point_config.base_point}}</van-tag>
+            </template>
+          </van-cell>
+          <van-cell
+            :border="false"
+            :title="scheduleTypeMark + '内容'"
+            :value="info.name"
+            title-class="align_self"
+            value-class="align_self"
+          />
+          <van-cell
+            v-if="info.remark"
+            :border="false"
+            :title="scheduleTypeMark + '备注'"
+            :value="info.remark"
+            title-class="align_self"
+            value-class="align_self"
+          />
+          <van-cell
+            :border="false"
+            title="执行周期"
+            :value="`${info.target_info.length > 0 ? '临时任务-' : '悬赏任务-'}${info.task_cycle_mark}`"
+            title-class="align_self"
+            value-class="align_self"
+          />
+          <van-cell
+            :border="false"
+            v-if="info.point_config"
+            :title="`${scheduleTypeMark}积分`"
+            :value="`${info.point_config.base_point}${$getTypesName(info.pt_id)}`"
+            title-class="align_self"
+            value-class="align_self"
+          />
+          <van-cell
+            :border="false"
+            v-if="info.file_list && info.file_list.length > 0"
+            title="附件"
+            title-class="align_self"
+            value-class="align_self"
+          >
+            <template slot="default">
+              <van-image
+                @click="open_img(index)"
+                style="margin-right: 0.1rem"
+                v-for="(item,index) in info.file_list"
+                :key="index"
+                :src="item"
+                width="50"
+                height="50"
+                radius="5"
+                type="contain"
+              />
+            </template>
+          </van-cell>
+          <van-cell
+            :border="false"
+            title="截止时间"
+            :title="expireTimeMark"
+            title-class="align_self"
+            value-class="align_self"
+          />
+          <van-cell
+            :border="false"
+            v-if="info.schedule_expire_time"
+            title="有效日期"
+            title-class="align_self"
+            value-class="align_self"
+          >
+            <template slot="default">
+              <span v-if="!isExpire(info.schedule_expire_time)">{{info.schedule_expire_time}}</span>
+              <span v-else>
+                <van-tag type="warning" size="medium">{{info.schedule_expire_time}}</van-tag>
+              </span>
+            </template>
+          </van-cell>
+          <van-cell
+            :border="false"
+            v-if="info.department_info"
+            title="可见范围"
+            title-class="align_self"
+            value-class="align_self"
+          >
+            <template v-if="info.department_info.length > 0">
+              <span
+                v-for="(item,index) in info.department_info"
+                :key="index"
+              >
+                {{item.name}}&nbsp;
+              </span>
+            </template>
+            <span v-else >全公司</span>
+          </van-cell>
+          <template v-if="info.point_config">
+            <van-cell
+              title="逾期扣分"
+              :value="`${info.point_config.timeout_deduction_point} B分/天`"
+              title-class="align_self"
+              value-class="align_self"
+            />
+            <van-cell
+              title="提前奖分"
+              :value="`${info.point_config.ahead_award_point} B分/天`"
+              title-class="align_self"
+              value-class="align_self"
+            />
+          </template>
         </van-cell-group>
 
-        <van-cell-group class="padding-cell-group" >
-          <div class="tip">执行者</div>
-          <div class="" style="margin-top:0.16rem;display: inline-block;margin-right: 0.2rem; width: 0.8rem;" v-if="info.target_info" v-for="(item,index) in info.target_info" :key="index">
-            <userImage fontSize="0.28" :user_name="item.name" :id="parseInt(item.id)" width="0.8rem" height="0.8rem"></userImage>
-            <div style="font-size: 0.2rem; text-align: center; overflow: hidden; white-space: nowrap; text-overflow: ellipsis;">{{item.name}}</div>
-          </div>
+        <van-cell-group inset>
+          <van-cell
+            title="审批人"
+            :value="info.reviewer_name"
+            title-class="align_self"
+            value-class="align_self"
+          />
+          <van-cell
+            v-if="info.target_info.length > 0"
+            title="执行人"
+            title-class="align_self"
+            value-class="align_self"
+          >
+            <template slot="default">
+              <span
+                v-for="(item,index) in info.target_info"
+                :key="index"
+              >
+                {{item.name}}&nbsp;
+              </span>
+            </template>
+          </van-cell>
         </van-cell-group>
+
+        <template v-if="info.item_info">
+          <van-row justify="space-around" class="item-title" >
+            <van-col span="6">规则依据</van-col>
+          </van-row>
+          <van-cell-group
+            :border="false"
+            class="task_detail_group"
+            inset
+          >
+            <van-cell
+              title-class="align_self"
+              value-class="align_self"
+              :border="false"
+              title="规则"
+              :value="info.item_info.remark"
+            />
+            <van-cell
+              title-class="align_self"
+              value-class="align_self"
+              :border="false"
+              title="积分"
+              :value="pointRemark"
+            />
+            <van-cell
+              title-class="align_self"
+              value-class="align_self"
+              v-if="info.item_info.has_delete"
+              :border="false"
+              title="规则状态"
+            >
+              <template slot="default">
+                <van-tag type="warning">规则已删除</van-tag>
+              </template>
+            </van-cell>
+            <van-cell
+              title-class="align_self"
+              value-class="align_self"
+              v-if="info.rule_info"
+              :border="false"
+              title="分类"
+              :value="info.rule_info.name"
+            />
+            <van-cell
+              title-class="align_self"
+              value-class="align_self"
+              v-if="info.rule_info && info.rule_info.has_delete"
+              :border="false"
+              title="分类状态"
+            >
+              <template slot="default">
+                <van-tag type="warning">分类已删除</van-tag>
+              </template>
+            </van-cell>
+          </van-cell-group>
+        </template>
+
+        <template v-else-if="info.rule_info">
+          <van-row justify="space-around" class="item-title">
+            <van-col span="6" >分类依据</van-col>
+          </van-row>
+          <van-cell-group
+            :border="false"
+            class="task_detail_group"
+            inset
+          >
+            <van-cell
+              title-class="align_self"
+              value-class="align_self"
+              :border="false"
+              title="分类"
+              :value="info.rule_info.name"
+            />
+            <van-cell
+              title-class="align_self"
+              value-class="align_self"
+              v-if="info.rule_info.has_delete"
+              :border="false"
+              title="分类状态"
+            >
+              <template slot="default">
+                <van-tag type="warning">分类已删除</van-tag>
+              </template>
+            </van-cell>
+          </van-cell-group>
+        </template>
+
+
+
       </scroller>
     </div>
     <van-action-sheet
@@ -112,8 +281,35 @@ export default {
       user_info: this.$userInfo()
     }
   },
+  computed:{
+    scheduleTypeMark(){
+      return !this.info ? '--' : (this.info.type === 2 ? '悬赏' : '任务')
+    },
+    expireTimeMark(){
+      if (!this.info) return '--'
+      let etMark = {
+        1:`${this.info.task_cycle_mark}${this.dayTime(this.info.task_cycle_value)}截止`,
+        2:`${this.info.task_cycle_mark}${this.weekList[this.info.task_cycle_value - 1]}截止`,
+        3:`${this.info.task_cycle_mark}${this.info.task_cycle_value}号截止`,
+      }
+      return etMark[this.info.task_cycle] || '--'
+    },
+    pointRemark(){
+      if (!(this.info && this.info.item_info)) return ''
+      return this.info.item_info.range_type === 1 ? `${this.info.item_info.min_point} ${this.$getTypesName(this.info.item_info.pt_id)}` : `${this.info.item_info.min_point} -- ${this.info.item_info.max_point} ${this.$getTypesName(this.info.item_info.pt_id)}`
+    }
+  },
   // 方法
   methods: {
+    isExpire(expire_time){
+      if (!expire_time) return false
+      let now = new Date()
+      let expire_date = new Date(expire_time)
+      return now >= expire_date
+    },
+    dayTime(item){
+      return item > 9 ? item + ':00' : '0' + item + ':00'
+    },
     // 上拉菜单点击
     sheet_select (action) {
       if (action.name == '删除任务') {
@@ -158,7 +354,7 @@ export default {
       let self = this
       self.showLoading()
       this.$axiosUser('get', '/api/pro/integral/schedule', {schedule_id: self.get_id}).then((res) => {
-        if (res.data.code == '1') {
+        if (res.data.code === 1) {
           self.info = res.data.data
         } else {
           self.$toast(res.data.msg)
@@ -171,6 +367,11 @@ export default {
     }
   },
   mounted () {
+    // console.log('mounted')
+    // this.get_data()
+  },
+  activated() {
+    // console.log('activated')
     this.get_data()
   }
 }
@@ -209,4 +410,34 @@ export default {
   .task_content /deep/ .van-grid-item__content{padding:0;}
 .task_content /deep/ .van-cell__value{text-align: left; color:#323233;}
   .task_content_last{padding-bottom:0.32rem;}
+
+
+.align_self{
+  align-self: center;
+}
+.item-title{
+  text-align: center;
+  margin-top: 10px;
+  font-size: 0.25rem;
+  line-height: 0.5rem;
+  color: #969799;
+}
+.sub-title{
+  font-size: 0.25rem;
+  line-height: 0.25rem;
+  color: #969799;
+}
+.align_self{
+  align-self: center;
+}
+
+.task_detail_group .van-cell {
+  padding: 0.1rem 0.32rem 0.1rem;
+}
+.task_detail_group .name {
+  padding-bottom: 0.2rem;
+}
+.task_detail_group {
+  padding: 0.16rem 0;
+}
 </style>

+ 209 - 16
src/point/view/task/short_task.vue

@@ -19,8 +19,64 @@
         </van-cell-group>
 
         <van-cell-group class="point-field">
+          <van-cell title="积分类型" required id="task_types">
+            <template slot="right-icon">
+              <van-radio-group v-model="data.pt_id" direction="horizontal" class="radio_button">
+                <van-radio checked-color class="list" :name="item.id" v-for="(item, index) in point_types" v-if="item.code !== 'JX'" :key="index">{{ item.name }}</van-radio>
+              </van-radio-group>
+              <van-icon class="small_tip" @click="show_small_tip = true" name="question-o" />
+            </template>
+          </van-cell>
+          <van-cell title="指定规则">
+            <template slot="right-icon">
+              <van-radio-group
+                v-model="data.rule_type"
+                direction="horizontal"
+                class="radio_button"
+              >
+                <van-radio class="list" :name="0" >
+                  <span class="rule_type_span">不指定</span>
+                </van-radio>
+                <van-radio class="list" :name="1" >
+                  <span class="rule_type_span">分类</span>
+                </van-radio>
+                <van-radio class="list" :name="2" >
+                  <span class="rule_type_span">规则</span>
+                </van-radio>
+              </van-radio-group>
+            </template>
+          </van-cell>
+
+          <!--     选择分类     -->
+          <CategorySelectorCell
+            v-if="data.rule_type === 1"
+            title="细则分类"
+            v-model="rules"
+            required
+            :pt-id="data.pt_id"
+            :multi="false"
+            scope
+          />
+
+          <!--选择规则  -->
+          <RuleCategorySelectorCell
+            v-if="data.rule_type === 2"
+            :pt-id="data.pt_id"
+            required
+            name="请选择积分规则"
+            title="积分规则"
+            v-model="rule_items"
+            scope
+            :multi="false"
+          >
+            <template slot="label">
+              <span style="color: red">{{ruleItemLabel}}</span>
+            </template>
+          </RuleCategorySelectorCell>
+
+
           <van-cell title="任务积分" style="padding:0 0.32rem; padding-top:0.16rem;" :border="false" required></van-cell>
-          <NumberInput v-model="data.base_point" v-validate="'required'" :chosePoint="false" :min="0" :max="100000"></NumberInput>
+          <NumberInput v-model="data.base_point" v-validate="'required'"  :min="minPoint" :max="maxPoint"></NumberInput>
         </van-cell-group>
 
         <van-cell-group>
@@ -35,14 +91,7 @@
             v-model="executor_name"
           ></EmployeeSelectorCell>
           <EmployeeSelectorCell required title="审批人" iconType="records" :show_manager_only="true" v-model="reviewer" v-validate="'required'" name="审批人" :multi="false"></EmployeeSelectorCell>
-          <van-cell title="任务类型" required id="task_types">
-            <template slot="right-icon">
-              <van-radio-group v-model="data.pt_id" direction="horizontal" class="radio_button">
-                <van-radio checked-color class="list" :name="item.id" v-for="(item, index) in point_types" v-if="item.code != 'JX'" :key="index">{{ item.name }}</van-radio>
-              </van-radio-group>
-              <van-icon class="small_tip" @click="show_small_tip = true" name="question-o" />
-            </template>
-          </van-cell>
+
           <van-cell title="重复周期"  @click="show_task_cycle_popup = true">
               <template>
                 <span v-if="data.task_cycle == 0">不重复</span>
@@ -55,6 +104,12 @@
           <van-cell required :value="'每天' + task_expire_day_text" is-link @click="show_task_expire_day = true" title="截止时间" v-if="data.task_cycle == 1" />
           <van-cell required :value="'每' + task_expire_day_text" is-link @click="show_task_expire_day = true" title="截止时间" v-if="data.task_cycle == 2" />
           <van-cell required :value="'每月' + task_expire_day_text" is-link @click="show_task_expire_day = true" title="截止时间" v-if="data.task_cycle == 3" />
+          <van-cell title="有效日期" v-if="data.task_cycle !== 0"  @click="showScheduleExpireDate = true" :value="data.schedule_expire_date" :center="true" >
+            <template #right-icon>
+              <van-icon color="#A4A5A7" name="arrow" v-if="!data.schedule_expire_date" />
+              <van-icon color="#A4A5A7" name="cross" v-else @click.stop="clearScheduleExpireDate" style="margin-left: 10px" />
+            </template>
+          </van-cell>
           <van-field v-model="data.ahead_award_point" type="digit">
             <template slot="label">
               <div class="flex-box-ce">
@@ -260,11 +315,22 @@
       />
     </van-popup>
     <van-popup v-model="show_small_tip" :get-container="'#task_types'" :overlay-class="'bg_opacity'"><div class="small_tip_popup_content">内容</div></van-popup>
+
+    <van-calendar
+      title="有效日期"
+      color="#26A2FF"
+      v-model="showScheduleExpireDate"
+      :show-confirm="false"
+      :default-date="scheduleExpireDate"
+      @confirm="scheduleExpireDateConfirm"
+    />
+
   </div>
 </template>
 <script>
 import DateTimeCell from '@/components/DateTimeCell';
-
+import RuleCategorySelectorCell from '@/components/RuleCategorySelectorCell1'
+import CategorySelectorCell from '@/components/CategorySelectorCell'
 import NumberInput from '@/components/NumberInput';
 import Vue from 'vue';
 import moment from 'moment'
@@ -283,9 +349,14 @@ export default {
     EmployeeSelectorCell,
     Mtextarea,
     DateTimeCell,
-    NumberInput
+    NumberInput,
+    RuleCategorySelectorCell,
+    CategorySelectorCell
   },
   data() {
+    let pts = this.$getTypes;
+    let ptB = pts.filter(pt => pt.code === 'BF');
+    ptB = ptB ? ptB[0] : null;
     return {
       point: 0,
       exced: 0, // 超预期计算标准
@@ -378,12 +449,30 @@ export default {
       executor_name: [],
       reviewer: [], // 登录员工的信息,
       manage_scope: this.$userInfo().employee_detail.manage_scope,
+      pts:pts,
+      rule_items:[],
+      rules:[],
       data: {
+        rule_type:0,
+        rule_id:0,
+        item_id:0,
+        rule_item:{
+          id:0,
+          remark:"",
+          cycle_type: 0,
+          is_attendance: 0,
+          max_point: 0,
+          min_point: 0,
+          prize_type: 0,
+          pt_id: 0,
+          range_type: 0,
+          rule_id: 0,
+        },
         targets: [],
-        pt_id: 0,
+        pt_id: ptB ? ptB.id : 0,
         task_name: '',
         task_remark: '',
-        base_point: 0,
+        base_point: 1,
         expire_time: '',
         package_id: 0,
         weight: 0,
@@ -399,7 +488,8 @@ export default {
         super_satisfied: 0,
         cate_id: 0,
         task_cycle: 0,
-        task_expire_day: 0
+        task_expire_day: 0,
+        schedule_expire_date:''
       },
       title: '发布指派任务',
       url1: '/api/pro/integral/work/publish',
@@ -417,7 +507,9 @@ export default {
       pointLevel: {},
       employee_map: this.$getEmployeeMap(),
       approver_manage_scope: [],
-      point_types: this.$getTypes
+      point_types: pts,
+      showScheduleExpireDate:false,
+      scheduleExpireDate:null
     };
   },
   watch: {
@@ -436,6 +528,7 @@ export default {
     'data.task_cycle': function(val) {
       this.data.task_expire_day = 1;
       this.task_expire_day = 0;
+      this.scheduleExpireDate = null;
       if (this.data.task_cycle == 1) {
         this.task_expire_day_text = this.columns1[this.data.task_expire_day - 1];
       } else if (this.data.task_cycle == 2) {
@@ -464,9 +557,84 @@ export default {
           arr.push(self.employee_map[val[i].id].employee_detail.superior_list);
         }
       }
+    },
+    scheduleExpireDate(val){
+      // console.log('任务 schedule expire Date',val);
+      this.data.schedule_expire_date = val ? moment(val).format('YYYY-MM-DD') : '';
+      // console.log('任务 ',this.data)
+      if (val) this.toast("重复任务将在" + this.data.schedule_expire_date + "停止自动发布")
+    },
+    'data.rule_type'(val){
+      this.initRuleData()
+    },
+    rules(rules){
+      this.data.rule_id = rules.length <= 0 ? 0 : rules[0].id
+    },
+    rule_items(items){
+      this.data.rule_item = items.length <= 0 ? {
+        id:0,
+        remark:"",
+        cycle_type: 0,
+        is_attendance: 0,
+        max_point: 0,
+        min_point: 0,
+        prize_type: 0,
+        pt_id: 0,
+        range_type: 0,
+        rule_id: 0,
+      } : {
+        id:items[0].id,
+        remark:items[0].remark,
+        cycle_type: items[0].cycle_type,
+        is_attendance: items[0].is_attendance,
+        max_point: items[0].max_point,
+        min_point: items[0].min_point,
+        prize_type: items[0].prize_type,
+        pt_id: items[0].pt_id,
+        range_type: items[0].range_type,
+        rule_id: items[0].rule_id,
+      }
+      this.data.rule_id = this.data.rule_item.rule_id
+      this.data.item_id = this.data.rule_item.id
+      this.data.base_point = this.data.rule_item.min_point !== 0 ? this.data.rule_item.min_point : 1
+    },
+    'data.pt_id'(val){
+      if (this.data.rule_type === 2) this.initRuleData()
+    }
+  },
+  computed:{
+    ruleItemLabel(){
+      if (this.data.rule_item.id <= 0) return ''
+      let pt = this.pts.find( t => t.id === this.data.rule_item.pt_id)
+      return this.data.rule_item.range_type === 1 ? `${this.data.rule_item.min_point} ${pt.name}` : `${this.data.rule_item.min_point} - ${this.data.rule_item.max_point} ${pt.name}`
+    },
+    minPoint(){
+      return this.data.rule_type !== 2 ? 1 : (this.data.rule_item.id <= 0 ? 1 : this.data.rule_item.min_point)
+    },
+    maxPoint(){
+      return this.data.rule_type !== 2 ? 100000 : (this.data.rule_item.id <= 0 ? 1 : this.data.rule_item.max_point)
     }
   },
   methods: {
+    initRuleData(){
+      this.data.rule_id = 0
+      this.data.item_id = 0
+      this.data.rule_item = {
+        id:0,
+        remark:"",
+        cycle_type: 0,
+        is_attendance: 0,
+        max_point: 0,
+        min_point: 0,
+        prize_type: 0,
+        pt_id: 0,
+        range_type: 0,
+        rule_id: 0,
+      }
+      this.data.base_point = 1
+      this.rule_items = []
+      this.rules = []
+    },
     changeunqualified(val) {
       let str = '' + this.data.super_satisfied;
       let str2 = '';
@@ -628,6 +796,7 @@ export default {
     qkData() {
       this.executor_name = [];
       this.reviewer = [];
+      this.scheduleExpireDate = null;
       this.data = {
         targets: [],
         pt_id: 0,
@@ -646,7 +815,7 @@ export default {
         super_satisfied: 0,
         cate_id: 0,
         task_cycle: 0,
-        task_expire_day: 0
+        schedule_expire_date:''
       };
     },
     ahead_timeout(item, arr, codes, code) {
@@ -732,6 +901,9 @@ export default {
       }else if(this.data.task_cycle==3&&this.data.task_expire_day<=moment().format('D')){
       	is=false
       }
+
+      if (!data.schedule_expire_date) delete data.schedule_expire_date;
+
       this.$axiosUser('post', url, data).then(res => {
             if(this.data.task_cycle&&is){
               let str=this.data.task_cycle==1? '您发布的每日重复任务将于明天0点执行自动发布,是否需要立即发布一条任务?':this.data.task_cycle==2? '您发布的每周重复任务将于下周一执行自动发布,是否需要立即发布一条任务?':'您发布的每月重复任务将于下个月1号执行自动发布,是否需要立即发布一条任务?'
@@ -783,6 +955,19 @@ export default {
     	});
     },
     sava_btn() {
+      // console.log('任务 save btn',this.data);return;
+      if (this.data.rule_type === 1 && this.data.rule_id <= 0){
+        this.$toast.fail ("请选择规则分类")
+        return
+      }
+      if (this.data.rule_type === 2 && this.data.item_id <= 0){
+        this.$toast.fail('请选择积分规则')
+        return;
+      }
+      if (this.data.base_point <= 0) {
+        this.$toast.fail('积分必须大于0')
+        return;
+      }
       let self = this;
       if (this.data.base_point === 0) {
         self.$notify({ type: 'danger', message: '任务积分不能为0' });
@@ -795,6 +980,14 @@ export default {
           self.sub();
         }
       });
+    },
+    scheduleExpireDateConfirm(val){
+      this.showScheduleExpireDate = false;
+      this.scheduleExpireDate = val;
+    },
+    clearScheduleExpireDate(){
+      this.showScheduleExpireDate = false;
+      this.scheduleExpireDate = null;
     }
   },
   activated() {

+ 341 - 122
src/point/view/task/taskFile.vue

@@ -8,42 +8,53 @@
 
     <div class="body_com has_header">
       <scroller>
-        <van-cell class="efficiency_list" size="large">
+        <van-cell
+          class="efficiency_list"
+          size="large"
+          :title="info.employee_name"
+        >
           <template slot="icon">
             <userImage :user_name="info.employee_name" :img_url="info.img_url" width="1rem" height="1rem" style="margin-right: 0.12rem;"></userImage>
           </template>
-          <template slot="title">
-            <span>{{ info.employee_name }}</span>
-            <div style="color: #909399;" v-if="info.dept_list.length > 0">
-              <span v-for="(item, index) in info.dept_list" :key="index">
+          <template slot="label">
+            <span v-if="info.dept_list.length > 0" v-for="(item, index) in info.dept_list" :key="index" class="sub-title">
                 <em v-if="index > 0">,</em>
                 {{ item.dept_name }}
               </span>
-            </div>
-            <div style="color: #909399;" v-if="info.dept_list.length == 0">暂无部门</div>
+            <span v-else>暂无部门</span>
           </template>
           <template slot="default">
-            <div style="float: right;text-align: center;padding:0 0.1rem;" v-if="info.status == 4">
+            <div style="float: right;text-align: center;padding:0 0.1rem;" v-if="info.status == 4" class="sub-title">
               <span class="point-span">{{ info.point_config.review_point }}</span>
               <div style="color: #909399;">最终分</div>
             </div>
-
             <div style="float: right;text-align: center;padding:0 0.1rem;">
-              <span class="point-span">{{ info.point_config.base_point }}</span>
-              <div style="color: #909399;">{{ info.pt_name }}</div>
+              <span class="point-span">{{ `${info.point_config.base_point} ${info.pt_name}` }}</span>
             </div>
           </template>
         </van-cell>
-        <van-cell-group :border="false" class="task_detail_group" v-if="info.review_status == 2">
-          <van-cell :border="false">
+        <van-cell-group
+          :border="false"
+          class="task_detail_group"
+          v-if="info.review_status === 2"
+        >
+          <van-cell
+            :border="false"
+            title-class="align_self"
+            value-class="align_self"
+          >
             <template slot="title">
               <div class="time">
                 <span>审批结果</span>
-                <span class="timeExactly red">已驳回</span>
+                <span class="timeExactly red">已拒绝</span>
               </div>
             </template>
           </van-cell>
-          <van-cell :border="false">
+          <van-cell
+            :border="false"
+            title-class="align_self"
+            value-class="align_self"
+          >
             <template slot="title">
               <div class="time">
                 <span>驳回理由</span>
@@ -53,106 +64,283 @@
           </van-cell>
         </van-cell-group>
 
-        <van-cell-group :border="false" class="task_detail_group">
-          <van-cell :border="false">
-            <template slot="title">
-              <div class="time">
-                <span>工作内容</span>
-                <span class="timeExactly" style="white-space: pre-line;">{{ info.task_name }}</span>
-              </div>
-            </template>
-          </van-cell>
-          <van-cell :border="false">
-            <template slot="title">
-              <div class="time">
-                <span>发布时间</span>
-                <span class="timeExactly">{{ info.create_time }}</span>
-              </div>
-            </template>
-          </van-cell>
-          <van-cell :border="false">
-            <template slot="title">
-              <div class="time">
-                <span>截止时间</span>
-                <span class="timeExactly">{{ info.expire_time }}</span>
-                <span style="padding-left: 10px;" class="red" v-show="info.expire_day > 0">逾期{{ info.expire_day }}天</span>
-              </div>
-            </template>
-          </van-cell>
-          <van-cell v-if="info.point_config.ahead_award_point * 1 > 0" :border="false">
-            <template slot="title">
-              <div class="time">
-                <span>提前奖分</span>
-                <span class="timeExactly">{{ info.point_config.ahead_award_point }}分/天</span>
-              </div>
-            </template>
-          </van-cell>
-          <van-cell v-if="info.point_config.timeout_deduction_point * 1 > 0" :border="false">
-            <template slot="title">
-              <div class="time">
-                <span>逾期扣分</span>
-                <span class="timeExactly">{{ info.point_config.timeout_deduction_point }}分/天</span>
-              </div>
-            </template>
-          </van-cell>
-          <van-cell :border="false">
-            <template slot="title">
-              <div class="time">
-                <span>任务备注</span>
-                <span class="timeExactly" style="white-space: pre-line;">{{ info.task_remark }}</span>
-              </div>
+        <van-row justify="space-around" class="item-title">
+          <van-col span="6" >任务信息</van-col>
+        </van-row>
+        <van-cell-group
+          :border="false"
+          class="task_detail_group"
+          inset
+        >
+          <van-cell
+            title-class="align_self"
+            value-class="align_self"
+            :border="false"
+            title="审批人"
+            :value="info.reviewer_name"
+          />
+          <van-cell
+            title-class="align_self"
+            value-class="align_self"
+            :border="false"
+            title="发布人"
+            :value="info.publisher_name"
+          />
+          <van-cell
+            title-class="align_self"
+            value-class="align_self"
+            :border="false"
+            title="任务积分"
+            :value="`${info.point_config.base_point} ${info.pt_name || ''}`"
+          />
+          <van-cell
+            title-class="align_self"
+            value-class="align_self"
+            :border="false"
+            title="内容"
+            :value="info.task_name"
+          />
+          <van-cell
+            title-class="align_self"
+            value-class="align_self"
+            v-if="info.task_remark"
+            :border="false"
+            title="任务备注"
+            :value="info.task_remark"
+          />
+          <van-cell
+            title-class="align_self"
+            value-class="align_self"
+            :border="false"
+            title="发布时间"
+            :value="info.create_time"
+          />
+          <van-cell
+            title-class="align_self"
+            value-class="align_self"
+            v-if="info.point_config.review_point"
+            :border="false"
+            title="最终分"
+            :value="info.point_config.review_point"
+          />
+          <van-cell
+            title-class="align_self"
+            value-class="align_self"
+            :border="false"
+            title="截止时间"
+          >
+            <template slot="default">
+              {{ info.expire_time }} <span style="padding-left: 10px;" class="red" v-show="info.expire_day > 0">逾期{{ info.expire_day }}天</span>
             </template>
           </van-cell>
+          <van-cell
+            title-class="align_self"
+            value-class="align_self"
+            v-if="info.point_config.timeout_deduction_point > 0"
+            :border="false"
+            title="逾期扣分"
+            :value="`${info.point_config.timeout_deduction_point} B分/天`"
+          />
+          <van-cell
+            title-class="align_self"
+            value-class="align_self"
+            v-if="info.point_config.ahead_award_point > 0"
+            :border="false"
+            title="提前奖分"
+            :value="`${info.point_config.ahead_award_point} B分/天`"
+          />
 
-          <van-cell :border="false">
-            <template slot="title">
-              <div class="time">
-                <span>审批人</span>
-                <span class="timeExactly">{{ info.reviewer_name }}</span>
-              </div>
-            </template>
-          </van-cell>
-          <van-cell :border="false" v-if="info.review_remark">
-            <template slot="title">
-              <div class="time">
-                <span>审批意见</span>
-                <span class="timeExactly" style="white-space: pre-line;">{{ info.review_remark }}</span>
-              </div>
-            </template>
-          </van-cell>
 
-          <van-cell :border="false">
-            <template slot="title">
-              <div class="time">
-                <span>发布人</span>
-                <span class="timeExactly">{{ info.publisher_name }}</span>
-              </div>
-            </template>
-          </van-cell>
 
-          <van-cell :border="false">
-            <template slot="title">
-              <div class="time">
-                <span>积分种类</span>
-                <span class="timeExactly">{{ info.pt_name }}</span>
-              </div>
-            </template>
-          </van-cell>
 
-          <van-cell :border="false" v-if="info.task_file_list.length != 0">
-            <template slot="title">
-              <div class="time">
-                <span>任务图片</span>
-                <span>
-                  <van-image v-for="(items, index) in info.task_file_list" :key="index" @click="open_image(info.task_file_list)" width="45" height="45" radius="3" :src="items" />
-                </span>
-              </div>
-            </template>
-          </van-cell>
+<!--          <van-cell :border="false">-->
+<!--            <template slot="title">-->
+<!--              <div class="time">-->
+<!--                <span>发布时间</span>-->
+<!--                <span class="timeExactly">{{ info.create_time }}</span>-->
+<!--              </div>-->
+<!--            </template>-->
+<!--          </van-cell>-->
+<!--          <van-cell :border="false">-->
+<!--            <template slot="title">-->
+<!--              <div class="time">-->
+<!--                <span>截止时间</span>-->
+<!--                <span class="timeExactly">{{ info.expire_time }}</span>-->
+<!--                <span style="padding-left: 10px;" class="red" v-show="info.expire_day > 0">逾期{{ info.expire_day }}天</span>-->
+<!--              </div>-->
+<!--            </template>-->
+<!--          </van-cell>-->
+<!--          <van-cell v-if="info.point_config.ahead_award_point * 1 > 0" :border="false">-->
+<!--            <template slot="title">-->
+<!--              <div class="time">-->
+<!--                <span>提前奖分</span>-->
+<!--                <span class="timeExactly">{{ info.point_config.ahead_award_point }}分/天</span>-->
+<!--              </div>-->
+<!--            </template>-->
+<!--          </van-cell>-->
+<!--          <van-cell v-if="info.point_config.timeout_deduction_point * 1 > 0" :border="false">-->
+<!--            <template slot="title">-->
+<!--              <div class="time">-->
+<!--                <span>逾期扣分</span>-->
+<!--                <span class="timeExactly">{{ info.point_config.timeout_deduction_point }}分/天</span>-->
+<!--              </div>-->
+<!--            </template>-->
+<!--          </van-cell>-->
+<!--          <van-cell :border="false">-->
+<!--            <template slot="title">-->
+<!--              <div class="time">-->
+<!--                <span>任务备注</span>-->
+<!--                <span class="timeExactly" style="white-space: pre-line;">{{ info.task_remark }}</span>-->
+<!--              </div>-->
+<!--            </template>-->
+<!--          </van-cell>-->
+
+<!--          <van-cell :border="false">-->
+<!--            <template slot="title">-->
+<!--              <div class="time">-->
+<!--                <span>审批人</span>-->
+<!--                <span class="timeExactly">{{ info.reviewer_name }}</span>-->
+<!--              </div>-->
+<!--            </template>-->
+<!--          </van-cell>-->
+<!--          <van-cell :border="false" v-if="info.review_remark">-->
+<!--            <template slot="title">-->
+<!--              <div class="time">-->
+<!--                <span>审批意见</span>-->
+<!--                <span class="timeExactly" style="white-space: pre-line;">{{ info.review_remark }}</span>-->
+<!--              </div>-->
+<!--            </template>-->
+<!--          </van-cell>-->
+
+<!--          <van-cell :border="false">-->
+<!--            <template slot="title">-->
+<!--              <div class="time">-->
+<!--                <span>发布人</span>-->
+<!--                <span class="timeExactly">{{ info.publisher_name }}</span>-->
+<!--              </div>-->
+<!--            </template>-->
+<!--          </van-cell>-->
+
+<!--          <van-cell :border="false">-->
+<!--            <template slot="title">-->
+<!--              <div class="time">-->
+<!--                <span>积分种类</span>-->
+<!--                <span class="timeExactly">{{ info.pt_name }}</span>-->
+<!--              </div>-->
+<!--            </template>-->
+<!--          </van-cell>-->
+
+<!--          <van-cell :border="false" v-if="info.task_file_list.length != 0">-->
+<!--            <template slot="title">-->
+<!--              <div class="time">-->
+<!--                <span>任务图片</span>-->
+<!--                <span>-->
+<!--                  <van-image v-for="(items, index) in info.task_file_list" :key="index" @click="open_image(info.task_file_list)" width="45" height="45" radius="3" :src="items" />-->
+<!--                </span>-->
+<!--              </div>-->
+<!--            </template>-->
+<!--          </van-cell>-->
         </van-cell-group>
 
-        <van-cell-group class="point" v-if="info.point_config.standard && info.point_config.standard.super_satisfied * 1 > 0">
-          <van-cell v-if="info.point_config.standard" title="评分标准">
+
+
+        <template v-if="info.item_info">
+          <van-row justify="space-around" class="item-title">
+            <van-col span="6" >规则依据</van-col>
+          </van-row>
+          <van-cell-group
+            :border="false"
+            class="task_detail_group"
+            inset
+          >
+            <van-cell
+              title-class="align_self"
+              value-class="align_self"
+              :border="false"
+              title="规则"
+              :value="info.item_info.remark"
+            />
+            <van-cell
+              title-class="align_self"
+              value-class="align_self"
+              :border="false"
+              title="积分"
+              :value="pointRemark"
+            />
+            <van-cell
+              title-class="align_self"
+              value-class="align_self"
+              v-if="info.item_info.has_delete"
+              :border="false"
+              title="规则状态"
+            >
+              <template slot="default">
+                <van-tag type="warning">规则已删除</van-tag>
+              </template>
+            </van-cell>
+            <van-cell
+              title-class="align_self"
+              value-class="align_self"
+              v-if="info.rule_info"
+              :border="false"
+              title="分类"
+              :value="info.rule_info.name"
+            />
+            <van-cell
+              title-class="align_self"
+              value-class="align_self"
+              v-if="info.rule_info && info.rule_info.has_delete"
+              :border="false"
+              title="分类状态"
+            >
+              <template slot="default">
+                <van-tag type="warning">分类已删除</van-tag>
+              </template>
+            </van-cell>
+          </van-cell-group>
+        </template>
+
+        <template v-else-if="info.rule_info">
+          <van-row justify="space-around" class="item-title">
+            <van-col span="6" >分类依据</van-col>
+          </van-row>
+          <van-cell-group
+            :border="false"
+            class="task_detail_group"
+            inset
+          >
+            <van-cell
+              title-class="align_self"
+              value-class="align_self"
+              :border="false"
+              title="分类"
+              :value="info.rule_info.name"
+            />
+            <van-cell
+              title-class="align_self"
+              value-class="align_self"
+              v-if="info.rule_info.has_delete"
+              :border="false"
+              title="分类状态"
+            >
+              <template slot="default">
+                <van-tag type="warning">分类已删除</van-tag>
+              </template>
+            </van-cell>
+          </van-cell-group>
+        </template>
+
+        <van-cell-group
+          class="point"
+          v-if="info.point_config.standard && info.point_config.standard.super_satisfied * 1 > 0"
+          inset
+        >
+          <van-cell
+            title-class="align_self"
+            value-class="align_self"
+            v-if="info.point_config.standard"
+            title="评分标准"
+          >
             <template slot="label">
               <van-grid slot="label" :border="false">
                 <van-grid-item text="超预期">
@@ -195,6 +383,7 @@
             </van-slider>
           </div>
         </van-panel>
+
         <div class="task">
           <van-row>
             <van-col span="16">
@@ -204,8 +393,8 @@
               </van-tabs>
             </van-col>
             <van-col span="8" style="background:#fff;border-bottom:0.02rem #efefef solid;">
-              <div v-if="active == 0 && info.employee_id == $userInfo().id && info.status < 3" @click="remberOne" class="rember">+记一条</div>
-              <div v-if="active != 0 && isShowJf" @click="noteone" class="rember">记分</div>
+              <div v-if="active === 0 && canUpdate" @click="remberOne" class="rember">+记一条</div>
+              <div v-if="active !== 0 && isShowJf" @click="noteone" class="rember">记分</div>
             </van-col>
           </van-row>
           <div ref="scoringNotice" style="clear: both;">
@@ -217,7 +406,7 @@
           <van-cell-group
             v-if="info.process !== null && info.process.list !== null"
             v-for="(item, index) in info.process.list"
-            :key="index"
+            :key="'record' + index"
             v-show="active == 0 && item.point == 0"
             :border="false"
           >
@@ -257,7 +446,7 @@
           <van-cell-group
             v-if="info.process !== null && info.process.list !== null"
             v-for="(item, index) in info.process.list"
-            :key="index"
+            :key="'point' + index"
             v-show="info.process.list !== null && active != 0 && item.point != 0"
             :border="false"
           >
@@ -297,7 +486,6 @@
           <van-cell-group style="background: none;" v-show="active != 0 && point_list.length == 0">
             <noTask src="static/images/noTask.png" detail_text="还没有记分记录去记一条吧" />
           </van-cell-group>
-
         </div>
 
         <div v-if="text_list.length != 0 || point_list.length != 0" style="height: 2rem;"></div>
@@ -307,7 +495,7 @@
       <div style="padding:0.32rem;width: 90%;position: fixed;bottom: 0;" v-if="info.reviewer_id == $userInfo().id && info.status == 2&&!isShowSp">
         <van-button block type="info" @click="go_approval">去审批</van-button>
       </div>
-      <div style="padding:0.32rem;width: 90%;position: fixed;bottom: 0;" v-if="info.employee_id == $userInfo().id && info.status == 1&&!isShowSp">
+      <div style="padding:0.4rem;width: 90%;position: fixed;bottom: 0; background-color: white;" v-if="canUpdate&&!isShowSp">
         <van-button block type="info" @click="complete_task(info)">完成</van-button>
       </div>
     </div>
@@ -335,11 +523,12 @@ export default {
   // 数据
   data () {
     return {
+      userInfo:this.$userInfo(),
       The_current_account: false,
       active: 0,
       numberslider: 0,
       active1: 'running',
-      title: '工作详情',
+      title: '任务详情',
       filter: {
         page: 1,
         type: 'all',
@@ -369,7 +558,11 @@ export default {
         status_mark: '',
         task_file_list: [],
         task_name: '',
-        task_remark: ''
+        task_remark: '',
+        rule_id:0,
+        rule_info:{},
+        item_id:0,
+        item_info:{}
       },
       process: [],
       checked: false,
@@ -403,6 +596,7 @@ export default {
   },
   activated() {
   	if (this.$route.query.task_id) {
+      this.info.id = this.$route.query.task_id
   	  this.getList()
   	}
     if(this.$route.query.isHome){
@@ -434,7 +628,7 @@ export default {
     },
 
     sheet_select (action, index) {
-      if (action.name == '编辑任务') {
+      if (action.name == '更新任务') {
         if (this.$route.query.isJx) {
           // 编辑 从上一个页面传过来一些参数
           this.$router.push({
@@ -446,7 +640,8 @@ export default {
             }
           })
         } else {
-          this.$router.push({ name: 'compile_task', query: { info: JSON.stringify(this.info) } })
+          this.$router.push({name:'WorkEdit',params:{workId:this.$route.query.task_id.toString()}})
+          // this.$router.push({ name: 'compile_task', query: { info: JSON.stringify(this.info) } })
         }
       }
       if (action.name == '撤销任务') {
@@ -537,10 +732,10 @@ export default {
       // 这里比较复杂,因为团队绩效的工作详情跟我的发布的工作详情都调用这个页面
       if (data.status == 1) {
         if (data.pt_id != 1) {
-          this.actions.push({ name: '编辑任务' })
+          this.actions.push({ name: '更新任务' })
           this.actions.push({ name: '删除任务' })
         } else if (data.pt_id == 1 && this.$route.query.isJx) {
-          this.actions.push({ name: '编辑任务' })
+          this.actions.push({ name: '更新任务' })
           this.actions.push({ name: '删除任务' })
         } else {
           this.actions.push({ name: '删除任务' })
@@ -550,16 +745,16 @@ export default {
       }
     },
     keepTheScore(data){
-      if(data.status > 2){
+      if(![1,2,6].includes(data.status)){
         return false
       }
-      if(this.$userInfo().id == data.reviewer_id){
+      if(this.userInfo.id === data.reviewer_id){
         return true
       }
       let info=this.$getEmployeeMapItem(data.employee_id)
       if(info){
         return info.employee_detail.superior_list.some(x =>{
-          if(this.$userInfo().id == x.id){
+          if(this.userInfo.id === x.id){
             return true
           }
         })
@@ -632,6 +827,15 @@ export default {
       })
     }
   },
+  computed:{
+    canUpdate(){
+      return this.info.employee_id === this.userInfo.id && [1,6].includes(this.info.status)
+    },
+    pointRemark(){
+      if (!(this.info && this.info.item_info)) return ''
+      return this.info.item_info.range_type === 1 ? `${this.info.item_info.min_point} ${this.$getTypesName(this.info.item_info.pt_id)}` : `${this.info.item_info.min_point} -- ${this.info.item_info.max_point} ${this.$getTypesName(this.info.item_info.pt_id)}`
+    }
+  },
   mounted () {
     this.getLocalStorage()
   },
@@ -892,4 +1096,19 @@ export default {
   -webkit-transform: scale(0.5);
   transform: scale(0.5);
 }
+.item-title{
+  text-align: center;
+  margin-top: 10px;
+  font-size: 0.25rem;
+  line-height: 0.5rem;
+  color: #969799;
+}
+.sub-title{
+  font-size: 0.25rem;
+  line-height: 0.25rem;
+  color: #969799;
+}
+.align_self{
+  align-self: center;
+}
 </style>

+ 188 - 43
src/point/view/task/task_detail_a.vue

@@ -10,7 +10,10 @@
     <div class="body_com has_header">
       <scroller v-if="info.point_config">
 
-        <van-cell-group class="task_detail_list_box">
+        <van-cell-group
+          class="task_detail_list_box"
+          inset
+        >
           <van-cell v-show="info.status == 1||info.status == 4" :title="info.owner_name+`悬赏的${$getTypesName(info.pt_id)}任务`">
             <template slot="label">
               <span class="orange">{{info.status_mark}}</span>
@@ -20,52 +23,177 @@
               <userImage v-show="info.receiver_id == 0" class="fl"  :img_url="info.owner_img_url" :user_name="info.owner_name"  style="margin-right: 0.2rem"></userImage>
             </template>
             <template slot="right-icon">
-              <span class="point red" v-if="info.point_config.base_point> 0">+{{info.point_config.base_point}}{{info.pt_name}}</span>
+              <span class="point red" v-if="info.point_config.base_point > 0">+{{info.point_config.base_point}}{{info.pt_name}}</span>
               <span class="point green" v-if="info.point_config.base_point< 0">{{info.point_config.base_point}}{{info.pt_name}}</span>
             </template>
           </van-cell>
 
-          <van-cell v-show="info.status == 2||info.status == 3" :title="info.receiver_name+`领取的${$getTypesName(info.pt_id)}任务`" title-class="head" label-class="sign">
-            <template slot="label">
-              <span class="orange">{{info.status_mark}}</span>
-            </template>
-            <template slot="icon">
-              <userImage v-show="info.receiver_id != 0" class="fl"  :img_url="info.receiver_img_url" :user_name="info.receiver_name"  style="margin-right: 0.2rem"></userImage>
-              <userImage v-show="info.receiver_id == 0" class="fl"  :img_url="info.owner_img_url" :user_name="info.owner_name"  style="margin-right: 0.2rem"></userImage>
-            </template>
-            <template slot="right-icon">
-             <span class="point red" v-if="info.point_config.base_point> 0">+{{info.point_config.base_point}}{{$getTypesName(info.pt_id)}}</span>
-             <span class="point green" v-if="info.point_config.base_point< 0">{{info.point_config.base_point}}{{$getTypesName(info.pt_id)}}</span>
-            </template>
-          </van-cell>
-
-          <van-cell :border="false" :title="info.task_name" title-class="task_name" style="margin-top:0.24rem;"></van-cell>
-          <van-cell :border="false" title="任务备注" v-if="info.task_remark != ''" title-class="title fontColorC task_detail" value-class="text-left" :value="info.task_remark"></van-cell>
-          <van-cell :border="false" title="任务类型" title-class="title fontColorC" value-class="text-left">{{info.type_mark}}</van-cell>
-          <van-cell :border="false" title="积分类型" title-class="title fontColorC" value-class="text-left">{{$getTypesName(info.pt_id)}}</van-cell>
-          <van-cell :border="false" title="发布时间" title-class="title fontColorC" value-class="text-left">{{info.create_time}}</van-cell>
-          <van-cell :border="false" title="截止时间" title-class="title fontColorC" value-class="text-left">{{info.end_time}}</van-cell>
-          <van-cell :border="false" title="审批人" title-class="title fontColorC" value-class="text-left" >{{info.reviewer_name}}</van-cell>
-          <van-cell :border="false" title="发布人" title-class="title fontColorC" value-class="text-left" >{{info.owner_name}}</van-cell>
-
-
-<!--          <van-cell :border="false" title="提前奖分" title-class="title fontColorC task_delayrecord" value-class="text-left" :value="info.point_config.ahead_award_point+'分/天'" v-if="info.point_config.ahead_award_point"></van-cell>
-          <van-cell :border="false" title="逾期扣分" title-class="title fontColorC task_delayrecord" value-class="text-left" :value="info.point_config.timeout_deduction_point+'分/天'" v-if="info.point_config.timeout_deduction_point"></van-cell> -->
-
-
-          <van-cell v-if="info.department_info.length > 0" title="可见范围" title-class="title fontColorC task_delayrecord" value-class="text-left">
-            <template  slot="default">
-               <span v-for="(items,index) in info.department_info" :key="index">
-                  {{items.name}}
+          <van-cell
+            :border="false"
+            title="任务内容"
+            :value="info.task_name"
+            title-class="align_self"
+            value-class="align_self"
+          />
+          <van-cell
+            :border="false"
+            v-if="info.receiver_id !== 0"
+            :title="info.status === 3 ? '完成人' : '领取人'"
+            :value="info.receiver_name"
+            title-class="align_self"
+            value-class="align_self"
+          />
+          <van-cell
+            :border="false"
+            v-if="info.task_remark"
+            title="任务备注"
+            :value="info.task_remark"
+            title-class="align_self"
+            value-class="align_self"
+          />
+          <van-cell
+            :border="false"
+            v-if="info.point_config"
+            title="任务积分"
+            :value="info.point_config.base_point + $getTypesName(info.pt_id)"
+            title-class="align_self"
+            value-class="align_self"
+          />
+          <van-cell
+            :border="false"
+            title="发布时间"
+            :value="info.create_time"
+            title-class="align_self"
+            value-class="align_self"
+          />
+          <van-cell
+            :border="false"
+            title="截止时间"
+            :value="info.end_time"
+            title-class="align_self"
+            value-class="align_self"
+          />
+          <van-cell
+            :border="false"
+            v-if="info.point_config"
+            title="逾期扣分"
+            :value="`${info.point_config.timeout_deduction_point}/分`"
+            title-class="align_self"
+            value-class="align_self"
+          />
+          <van-cell
+            :border="false"
+            v-if="info.point_config && info.point_config.ahead_award_point"
+            title="提前奖分"
+            :value="`${info.point_config.ahead_award_point}/分`"
+            title-class="align_self"
+            value-class="align_self"
+          />
+          <van-cell
+            :border="false"
+            v-if="info.department_info"
+            title="可见范围"
+            title-class="align_self"
+            value-class="align_self"
+          >
+            <template slot="default">
+              <template v-if="info.department_info.length > 0">
+                <span
+                  v-for="(item,index) in info.department_info"
+                  :key="index"
+                >
+                  {{item.name}}&nbsp;
                 </span>
+              </template>
+              <span v-else>全公司可见</span>
             </template>
           </van-cell>
-          <van-cell title="图片" title-class="title fontColorC task_img" value-class="text-left" v-show="info.task_file_list.length > 0">
+          <van-cell
+            :border="false"
+            v-if="info.reviewer_name"
+            title="审批人"
+            :value="info.reviewer_name"
+            title-class="align_self"
+            value-class="align_self"
+          />
+          <van-cell
+            :border="false"
+            title="任务类型"
+            :value="info.source_type_mark"
+            title-class="align_self"
+            value-class="align_self"
+          />
+          <van-cell
+            title="图片"
+            title-class="title fontColorC task_img align_self"
+            value-class="text-left align_self"
+            v-show="info.task_file_list.length > 0"
+          >
             <template slot="default">
               <van-image @click="open_img(index)" style="margin-right: 0.1rem" v-for="(item,index) in info.task_file_list" :key="index" :src="item" width="50" height="50" radius="5" type="contain"  />
             </template>
           </van-cell>
         </van-cell-group>
+
+        <template v-if="info.item_info">
+          <van-row justify="space-around" class="item-title">
+            <van-col span="6" >规则依据</van-col>
+          </van-row>
+          <van-cell-group inset>
+            <van-cell
+              :border="false"
+              title="规则"
+              :value="info.item_info.remark"
+              title-class="align_self"
+              value-class="align_self"
+            >
+              <template slot="default">
+                {{info.item_info.remark}}
+                <van-tag v-if="info.item_info.has_delete" type="warning" size="medium">已删除</van-tag>
+              </template>
+            </van-cell>
+            <van-cell
+              :border="false"
+              title="积分"
+              :value="pointRemark"
+              title-class="align_self"
+              value-class="align_self"
+            />
+            <van-cell
+              v-if="info.rule_info"
+              :border="false"
+              title="分类"
+              :value="info.rule_info.name"
+              title-class="align_self"
+              value-class="align_self"
+            >
+              <template slot="default">
+                {{info.rule_info.name}}
+                <van-tag v-if="info.rule_info.has_delete" type="warning" size="medium">已删除</van-tag>
+              </template>
+            </van-cell>
+          </van-cell-group>
+        </template>
+        <template v-else-if="info.rule_info">
+          <van-row justify="space-around" class="item-title">
+            <van-col span="6" >分类依据</van-col>
+          </van-row>
+          <van-cell-group inset>
+            <van-cell
+              :border="false"
+              title="分类"
+              title-class="align_self"
+              value-class="align_self"
+            >
+              <template slot="default">
+                {{info.rule_info.name}}
+                <van-tag v-if="info.rule_info.has_delete" type="warning" size="medium">已删除</van-tag>
+              </template>
+            </van-cell>
+          </van-cell-group>
+        </template>
+
+
         <div class="confirm_buttom" style="padding: 0.32rem" v-show="info.status == '1' && shoe_btn && user_id != info.owner_id && info.reviewer_id != user_id && !isCreator">
           <van-button type="info" block @click="receive_tasks">领取任务</van-button>
         </div>
@@ -95,7 +223,7 @@ export default {
       The_current_account: false,
       actions: [],
       sheet_show: false,
-      title: '任务详情',
+      title: '悬赏信息',
       info: {
         point_config:{},
         department_info:[],
@@ -108,17 +236,24 @@ export default {
       isCreator: this.$userInfo().is_creator,
     }
   },
+  computed:{
+    pointRemark(){
+      if (!(this.info && this.info.item_info)) return ''
+      return this.info.item_info.range_type === 1 ? `${this.info.item_info.min_point} ${this.$getTypesName(this.info.item_info.pt_id)}` : `${this.info.item_info.min_point} -- ${this.info.item_info.max_point} ${this.$getTypesName(this.info.item_info.pt_id)}`
+    }
+  },
   // 方法
   methods: {
     // 删除
     sheet_select (action) {
-      if (action.name == '编辑任务') {
-        this.$router.push({name: 'compile_temp_task', query: {info: JSON.stringify(this.info)}})
+      if (action.name == '更新悬赏') {
+        // this.$router.push({name: 'compile_temp_task', query: {info: JSON.stringify(this.info)}})
+        this.$router.push({name: 'TaskEdit', params: {taskId: this.$route.query.task_id.toString()}})
       }
-      if (action.name == '删除任务') {
+      if (action.name == '删除悬赏') {
         this.$dialog.confirm({
-          title: '删除任务',
-          message: '删除此任务将会删除其相关记录和积分数据,确认删除吗?'
+          title: '删除悬赏',
+          message: '删除此悬赏将会删除其相关记录和积分数据,确认删除吗?'
         }).then(() => {
           this.delete_task()
         })
@@ -170,9 +305,9 @@ export default {
           self.info = res.data.data
           self.shoe_btn = moment(this.time) < moment(this.info.expire_time)
           if (self.info.status == 1 && self.info.status_mark == '待领取') {
-            self.actions = [{name: '编辑任务'}, { name: '删除任务' }]
+            self.actions = [{name: '更新悬赏'}, { name: '删除悬赏' }]
           } else {
-            self.actions = [{ name: '删除任务' }]
+            self.actions = [{ name: '删除悬赏' }]
           }
         } else {
           self.$toast(res.data.msg)
@@ -258,4 +393,14 @@ export default {
 .task_detail_box .task_detail_list_box{
   padding:0.32rem 0;
 }
+.item-title{
+  text-align: center;
+  margin-top: 10px;
+  font-size: 0.25rem;
+  line-height: 0.5rem;
+  color: #969799;
+}
+.align_self{
+  align-self: center;
+}
 </style>

+ 225 - 30
src/point/view/task/temp_task.vue

@@ -15,12 +15,73 @@
               :imgs_max="3"
               images
               :imgs.sync="data.file_list"
-            ></Mtextarea>
+            />
           </van-cell>
         </van-cell-group>
         <van-cell-group class="point-field">
+          <van-cell title="积分类型" required>
+            <template slot="right-icon">
+              <van-radio-group v-model="data.pt_id" direction="horizontal" class="radio_button">
+                <van-radio class="list" :class="{ changeRadio: item.id === data.pt_id }" v-if="item.code !== 'JX'" :name="item.id" v-for="(item, index) in pts" :key="index">
+                  {{ item.name }}
+                </van-radio>
+              </van-radio-group>
+<!--              <smallTip icon="question-o" position="30%">-->
+<!--                <p style="margin: 0; line-height: 0.6rem">A分:物质分,与钱直接挂钩</p>-->
+<!--                <p style="margin: 0; line-height: 0.6rem">B分:福利分,与福利待遇挂钩</p>-->
+<!--                <p style="margin: 0; line-height: 0.6rem">绩效分:工作分,与绩效考核挂钩</p>-->
+<!--              </smallTip>-->
+            </template>
+          </van-cell>
+          <van-cell title="指定规则">
+            <template slot="right-icon">
+              <van-radio-group
+                v-model="data.rule_type"
+                direction="horizontal"
+                class="radio_button"
+              >
+                <van-radio class="list" :name="0" >
+                  <span class="rule_type_span">不指定</span>
+                </van-radio>
+                <van-radio class="list" :name="1" >
+                  <span class="rule_type_span">分类</span>
+                </van-radio>
+                <van-radio class="list" :name="2" >
+                  <span class="rule_type_span">规则</span>
+                </van-radio>
+              </van-radio-group>
+            </template>
+          </van-cell>
+<!--     选择分类     -->
+          <CategorySelectorCell
+            v-if="data.rule_type === 1"
+            title="细则分类"
+            v-model="rules"
+            required
+            :pt-id="data.pt_id"
+            :multi="false"
+            scope
+          />
+
+
+          <!--选择规则  -->
+          <RuleCategorySelectorCell
+            v-if="data.rule_type === 2"
+            :pt-id="data.pt_id"
+            required
+            name="请选择积分规则"
+            title="积分规则"
+            v-model="rule_items"
+            scope
+            :multi="false"
+          >
+            <template slot="label">
+              <span style="color: red">{{ruleItemLabel}}</span>
+            </template>
+          </RuleCategorySelectorCell>
+
           <van-cell title="任务积分" style="padding:0 0.32rem; padding-top:0.16rem;" :border="false" required />
-          <NumberInput v-model="data.base_point" v-validate="'required'" :chosePoint="false" :min="0" :max="100000"></NumberInput>
+          <NumberInput v-model="data.base_point" v-validate="'required'" :min="minPoint" :max="maxPoint"/>
         </van-cell-group>
 
         <van-cell-group>
@@ -34,20 +95,6 @@
             v-model="reviewer"
             :multi="false"
           ></EmployeeSelectorCell>
-          <van-cell title="任务类型" required>
-            <template slot="right-icon">
-              <van-radio-group v-model="data.pt_id" direction="horizontal" class="radio_button">
-                <van-radio class="list" :class="{ changeRadio: item.id === data.pt_id }" v-if="item.code != 'JX'" :name="item.id" v-for="(item, index) in $getTypes" :key="index">
-                  {{ item.name }}
-                </van-radio>
-              </van-radio-group>
-              <smallTip icon="question-o" position="30%">
-                <p style="margin: 0; line-height: 0.6rem">A分:物质分,与钱直接挂钩</p>
-                <p style="margin: 0; line-height: 0.6rem">B分:福利分,与福利待遇挂钩</p>
-                <p style="margin: 0; line-height: 0.6rem">绩效分:工作分,与绩效考核挂钩</p>
-              </smallTip>
-            </template>
-          </van-cell>
           <van-cell title="重复周期"  @click="show_task_cycle_popup = true">
               <template>
                 <span v-if="data.task_cycle == 0">不重复</span>
@@ -60,6 +107,13 @@
           <van-cell :value="'每天' + task_expire_day_text" is-link @click="show_task_expire_day = true" title="截止时间" v-if="data.task_cycle == 1" />
           <van-cell :value="'每' + task_expire_day_text" is-link @click="show_task_expire_day = true" title="截止时间" v-if="data.task_cycle == 2" />
           <van-cell :value="'每月' + task_expire_day_text" is-link @click="show_task_expire_day = true" title="截止时间" v-if="data.task_cycle == 3" />
+          <van-cell title="有效日期" v-if="data.task_cycle !== 0" @click="showScheduleExpireDate = true" :value="data.schedule_expire_date" :center="true">
+            <template #right-icon >
+              <van-icon color="#A4A5A7"  name="arrow" v-if="!data.schedule_expire_date" />
+              <van-icon color="#A4A5A7"  name="close" v-else @click.stop="clearScheduleExpireDate" style="margin-left: 10px" />
+            </template>
+          </van-cell>
+
           <van-field v-model="data.ahead_award_point" type="digit">
             <template slot="label">
               <div class="flex-box-ce">
@@ -254,12 +308,25 @@
         @confirm="task_expire_dayonChange"
       />
     </van-popup>
+
+
+    <van-calendar
+      title="有效日期"
+      color="#26A2FF"
+      v-model="showScheduleExpireDate"
+      :show-confirm="false"
+      :default-date="scheduleExpireDate"
+      @confirm="scheduleExpireDateConfirm"
+    />
+
+
   </div>
 </template>
 <script>
 import DeptSelectorCell from '@/components/DeptSelectorCell';
 import DateTimeCell from '@/components/DateTimeCell';
-
+import RuleCategorySelectorCell from '@/components/RuleCategorySelectorCell1'
+import CategorySelectorCell from '@/components/CategorySelectorCell'
 import NumberInput from '@/components/NumberInput';
 import Vue from 'vue';
 import moment from 'moment'
@@ -277,6 +344,10 @@ Vue.use(calendar)
 export default {
   data() {
     const reviewer = [this.$userInfo()];
+    let pts = this.$getTypes;
+    let ptB = pts.filter(pt => pt.code === 'BF');
+    ptB = ptB ? ptB[0] : null;
+
     return {
       isNeed: !this.$getCache('isAndroid'),
       bar_height: 0,
@@ -344,12 +415,30 @@ export default {
         '31号'
       ],
       reviewer: reviewer,
+      pts: pts,
+      rule_items:[],
+      rules:[],
       data: {
+        rule_type:0,
+        rule_id:0,
+        item_id:0,
+        rule_item:{
+          id:0,
+          remark:"",
+          cycle_type: 0,
+          is_attendance: 0,
+          max_point: 0,
+          min_point: 0,
+          prize_type: 0,
+          pt_id: 0,
+          range_type: 0,
+          rule_id: 0,
+        },
         task_type: 1,
-        pt_id: 0,
+        pt_id: ptB ? ptB.id : 0,
         task_name: '',
         task_remark: '',
-        base_point: 0,
+        base_point: 1,
         expire_time: '',
         file_list: [],
         reviewer_id: this.$userInfo().id,
@@ -359,7 +448,8 @@ export default {
         ahead_award_point_limit: '',
         dept_ids: [],
         task_cycle: 0,
-        task_expire_day: 1
+        task_expire_day: 1,
+        schedule_expire_date:''
       },
       title: '发布悬赏任务',
       post_data: {},
@@ -373,6 +463,8 @@ export default {
       show_timeout_deduction_point_popup: false,
       show_task_remark_popup: false,
       flexDialog:false,
+      showScheduleExpireDate:false,
+      scheduleExpireDate:null
     };
   },
   components: {
@@ -381,12 +473,15 @@ export default {
     DateTimeCell,
     DeptSelectorCell,
     smallTip,
-    NumberInput
+    NumberInput,
+    RuleCategorySelectorCell,
+    CategorySelectorCell,
   },
   watch: {
     'data.task_cycle': function(val) {
       this.data.task_expire_day = 1;
       this.task_expire_day = 0;
+      this.scheduleExpireDate = null;
       if (this.data.task_cycle == 1) {
         this.task_expire_day_text = this.columns1[this.data.task_expire_day - 1];
       } else if (this.data.task_cycle == 2) {
@@ -412,6 +507,62 @@ export default {
           this.data.dept_ids.push(val[i].dept_id);
         }
       }
+    },
+    scheduleExpireDate(val){
+      // console.log('悬赏 schedule expire date',val);
+      this.data.schedule_expire_date = val ? moment(val).format('YYYY-MM-DD') : '';
+      // console.log('悬赏',this.data);
+      if (val) this.$toast("重复悬赏将在" + this.data.schedule_expire_date + "停止自动发布")
+    },
+    'data.rule_type'(val){
+      this.initRuleData()
+    },
+    rules(rules){
+      this.data.rule_id = rules.length <= 0 ? 0 : rules[0].id
+    },
+    rule_items(items){
+      this.data.rule_item = items.length <= 0 ? {
+        id:0,
+        remark:"",
+        cycle_type: 0,
+        is_attendance: 0,
+        max_point: 0,
+        min_point: 0,
+        prize_type: 0,
+        pt_id: 0,
+        range_type: 0,
+        rule_id: 0,
+      } : {
+        id:items[0].id,
+        remark:items[0].remark,
+        cycle_type: items[0].cycle_type,
+        is_attendance: items[0].is_attendance,
+        max_point: items[0].max_point,
+        min_point: items[0].min_point,
+        prize_type: items[0].prize_type,
+        pt_id: items[0].pt_id,
+        range_type: items[0].range_type,
+        rule_id: items[0].rule_id,
+      }
+      this.data.rule_id = this.data.rule_item.rule_id
+      this.data.item_id = this.data.rule_item.id
+      this.data.base_point = this.data.rule_item.min_point !== 0 ? this.data.rule_item.min_point : 1
+    },
+    'data.pt_id'(val){
+      if (this.data.rule_type === 2) this.initRuleData()
+    }
+  },
+  computed:{
+    ruleItemLabel(){
+      if (this.data.rule_item.id <= 0) return ''
+      let pt = this.pts.find( t => t.id === this.data.rule_item.pt_id)
+      return this.data.rule_item.range_type === 1 ? `${this.data.rule_item.min_point} ${pt.name}` : `${this.data.rule_item.min_point} - ${this.data.rule_item.max_point} ${pt.name}`
+    },
+    minPoint(){
+      return this.data.rule_type !== 2 ? 1 : (this.data.rule_item.id <= 0 ? 1 : this.data.rule_item.min_point)
+    },
+    maxPoint(){
+      return this.data.rule_type !== 2 ? 100000 : (this.data.rule_item.id <= 0 ? 1 : this.data.rule_item.max_point)
     }
   },
   methods: {
@@ -553,6 +704,9 @@ export default {
       }else if(this.data.task_cycle==3&&this.data.task_expire_day<=moment().format('D')){
       	is=false
       }
+
+      if (!data.schedule_expire_date) delete data.schedule_expire_date;
+
       this.$axiosUser('post', url, data).then(res => {
         if(this.data.task_cycle&&is){
           let str=this.data.task_cycle==1? '您发布的每日重复任务将于明天0点执行自动发布,是否需要立即发布一条任务?':this.data.task_cycle==2? '您发布的每周重复任务将于下周一执行自动发布,是否需要立即发布一条任务?':'您发布的每月重复任务将于下个月1号执行自动发布,是否需要立即发布一条任务?'
@@ -587,6 +741,25 @@ export default {
         this.$toast.clear();
       });
     },
+    initRuleData(){
+      this.data.rule_id = 0
+      this.data.item_id = 0
+      this.data.rule_item = {
+        id:0,
+        remark:"",
+        cycle_type: 0,
+        is_attendance: 0,
+        max_point: 0,
+        min_point: 0,
+        prize_type: 0,
+        pt_id: 0,
+        range_type: 0,
+        rule_id: 0,
+      }
+      this.data.base_point = 1
+      this.rule_items = []
+      this.rules = []
+    },
     initData(){
       this.reviewer = [];
       this.data = {
@@ -594,7 +767,7 @@ export default {
         pt_id: 0,
         task_name: '',
         task_remark: '',
-        base_point: 0,
+        base_point: 1,
         expire_time: '',
         file_list: [],
         reviewer_id: 0,
@@ -604,7 +777,8 @@ export default {
         ahead_award_point_limit: '',
         dept_ids: [],
         task_cycle: 0,
-        task_expire_day: 1
+        task_expire_day: 1,
+        schedule_expire_date: ''
       };
     },
     //执行周期任务
@@ -623,26 +797,43 @@ export default {
     	});
     },
     sava_btn() {
+      // console.log('悬赏 sava_btn',this.data);return;
+      if (this.data.rule_type === 1 && this.data.rule_id <= 0){
+        this.$toast.fail ("请选择规则分类")
+        return
+      }
+      if (this.data.rule_type === 2 && this.data.item_id <= 0){
+        this.$toast.fail('请选择积分规则')
+        return;
+      }
+      if (this.data.base_point <= 0) {
+        this.$toast.fail('积分必须大于0')
+        return;
+      }
       let self = this;
       self.$validator.validate().then(result => {
         if (!result) {
           self.$notify({ type: 'danger', message: self.$validator.errors.items[0].msg });
         } else {
-          if (self.data.base_point == 0) {
-            self.$notify({ type: 'danger', message: '任务积分必须大约0' });
+          if (self.data.base_point === 0) {
+            self.$notify({ type: 'danger', message: '任务积分不能为0' });
           } else {
             self.sub();
           }
         }
+
       });
+    },
+    scheduleExpireDateConfirm(val) {
+      this.showScheduleExpireDate = false;
+      this.scheduleExpireDate = val;
+    },
+    clearScheduleExpireDate() {
+      this.showScheduleExpireDate = false;
+      this.scheduleExpireDate = null;
     }
   },
   created() {
-    for (let i in this.$getTypes) {
-      if (this.$getTypes[i].code == 'BF') {
-        this.data.pt_id = this.$getTypes[i].id;
-      }
-    }
     if (window.plus) {
       this.bar_height = window.plus.navigator.getStatusbarHeight();
       if(!this.$getCache('flexDialog')){
@@ -785,4 +976,8 @@ export default {
 .temp_task_box .small_tip_content p:nth-child(3) {
   display: none;
 }
+.rule_type_span {
+  font-size: 0.25rem;
+  line-height: 0.5rem;
+}
 </style>

+ 37 - 0
src/router/pointRoute.js

@@ -351,6 +351,13 @@ const routes = [
     label: '管理者奖扣',
     need_login: true
   },
+  {
+    path: '/reward_deduction_search',
+    name: 'reward_deduction_search',
+    component: () => import('@/point/view/integral/reward_deduction_search'),
+    label: '奖扣数据查询',
+    need_login: true
+  },
   {
     path: '/reward_deduction_statistics',
     name: 'reward_deduction_statistics',
@@ -471,5 +478,35 @@ const routes = [
     label: '申请结果',
     need_login: true
   },
+  {
+    path: '/dept_rank',
+    name: 'dept_rank',
+    component: () => import('@/point/view/integral/deptRank'),
+    label: '部门排行',
+    need_login: true
+  },
+  {
+    path: '/appeal',
+    name: 'appeal',
+    component: () => import('@/point/view/integral/appealList'),
+    label: '申诉列表',
+    need_login: true
+  },
+  {
+    path:'/work/edit/:workId',
+    name:'WorkEdit',
+    component: () => import('@/point/view/task/WorkEdit'),
+    label: '任务编辑',
+    need_login: true,
+    props:true
+  },
+  {
+    path: '/task/edit/:taskId',
+    name: 'TaskEdit',
+    component: () => import("@/point/view/task/TaskEdit"),
+    label: '悬赏编辑',
+    need_login: true,
+    props: true
+  }
 ]
 export default routes

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

@@ -220,7 +220,7 @@ const user = {
           account_info = JSON.parse(localStorage.getItem('account_info'))
         }
         let nowDate = moment().format("YYYY-MM-DD HH:mm:ss");
-        if(account_info &&account_info.data.localStorageExpire&&moment(nowDate).isBefore(account_info.data.localStorageExpire)){
+        if(account_info && account_info.data && account_info.data.localStorageExpire&&moment(nowDate).isBefore(account_info.data.localStorageExpire)){
           commit('SET_ACCOUNTINFO', account_info.data)
           resolve(account_info)
         }else{

+ 3 - 0
src/utils/helper.js

@@ -0,0 +1,3 @@
+export function specialFilter(inputStr){
+  return inputStr.replace(/[^(\w\d\s\u4e00-\u9fa5+:、,.!@$#%*={}:,。!()【】《》;¥??’”\-\(\)\[\])]/g,"")
+}

+ 3 - 1
src/utils/validator.js

@@ -15,7 +15,9 @@ Vue.use(VeeValidate, {
   events: 'change',
   dictionary: {
     zh_CN
-  }
+  },
+  errorBagName: 'errorBags',      //解决The computed property "fields" is already defined in data的问题
+  fieldsBagName: 'fieldBags',     //解决The computed property "fields" is already defined in data的问题
 })
 
 const dictionary = {

+ 4 - 2
src/view/system/about.vue

@@ -33,9 +33,11 @@ Vue.use(Cell).use(CellGroup).use(Notify)
 export default {
   name: 'about',
   data () {
+    let verTag = process.env.NODE_ENV === 'development' ? 'beta' : '';
     return {
+      verTag : verTag,
       info: {},
-      app_ver: '8.0',
+      app_ver: '8.0' + verTag,
     }
   },
   created () {
@@ -43,7 +45,7 @@ export default {
     let self = this
     if (window.plus) {
       plus.runtime.getProperty(plus.runtime.appid, function (inf) {
-        self.app_ver = inf.version
+        self.app_ver = inf.version + self.verTag
       })
     }
   },

+ 1 - 1
src/view/user/login.vue

@@ -425,7 +425,7 @@ export default {
                 //     console.log("苹果软件用户没有创建公司");
                 //   }
                 // }
-                console.log(res.data.account_site);
+                // console.log(res.data.account_site);
                 this.openUrl2(
                   res.data.account_site,
                   res.data.invitation_wait_count