3 Commits a5976b9e1d ... d228afe825

Tác giả SHA1 Thông báo Ngày
  walter d228afe825 ws 11 tháng trước cách đây
  walter 7b18d05ebf 复核详情 11 tháng trước cách đây
  walter 05b73a6494 复核详情 11 tháng trước cách đây
2 tập tin đã thay đổi với 289 bổ sung5 xóa
  1. 232 0
      src/api/wsService.js
  2. 57 5
      src/views/workbench/integral_review.vue

+ 232 - 0
src/api/wsService.js

@@ -0,0 +1,232 @@
+
+import {getToken,generateUUID} from "@/api/auth";
+
+const url = 'wss://' + process.env.VUE_APP_WEBSCOKET + '/ws2/'
+class WsService {
+    constructor(url){
+        this.url = url
+        this.authStatus = false
+        this.businessCallback = null
+        this.wsClient = null
+        this.initInterval()
+        this.initWebSocket()
+    }
+
+    initInterval(){
+        this.interval = 3000
+    }
+
+    initWebSocket(){
+        this.wsClient = new WebSocket(this.url)
+        this.initInterval()
+        this.wsClient.onmessage = (e) => {
+            let msg = JSON.parse(e.data)
+            if(msg.type === 'ping') this.wsClient.send("wsService check")
+            if(msg.type === 'auth' && msg.code === 1) this.authStatus = true
+
+            if (typeof this.businessCallback === 'function') {
+                this.businessCallback(msg)
+                this.businessCallback = null
+            }
+        }
+        this.wsClient.onopen = () => {
+            this.log('websocket open')
+            this.userAuth()
+        }
+        this.wsClient.onerror = (event) => {
+            this.log('websocket error',event)
+        }
+        this.wsClient.onclose = (e) => {
+            this.log('websocket close',e)
+            this.authStatus = false
+            if (this.interval > 0){
+                let intervalId = setInterval(function () {
+                    this.log("interval start")
+                    if (this.wsClient.readyState === WebSocket.OPEN) {
+                        this.log("interval close")
+                        clearInterval(intervalId)
+                    } else {
+                        this.log("interval initWebSocket")
+                        this.initWebSocket()
+                    }
+                }.bind(this),this.interval)
+            }
+        }
+    }
+
+    getAuthStatus(){
+        return this.authStatus
+    }
+
+    getUrl(){
+        return this.url
+    }
+
+    setCallback(fun){
+        if (typeof fun === 'function') this.businessCallback = fun
+    }
+
+    getReadyState(){
+        return this.wsClient.readyState
+    }
+
+    userAuth(){
+
+        let token = getToken()
+        let uuid = generateUUID()
+        if (!token || !uuid || !this.wsClient) return
+
+        this.wsClient.send(JSON.stringify({type:'auth',token:token,machine:uuid}))
+    }
+
+
+
+    send(data,fun){
+        if (this.wsClient.readyState !== WebSocket.OPEN) return
+        this.businessCallback = typeof fun === 'function' ? fun : null
+
+        this.wsClient.send(typeof data === 'string' ? data : JSON.stringify(data))
+    }
+
+
+    close(){
+        this.wsClient.close()
+    }
+
+    closeForce(){
+        this.interval = 0
+        this.wsClient.close()
+    }
+
+    log(message,...args){
+        if (process.env.NODE_ENV === 'development') console.log(message,...args)
+    }
+
+}
+
+
+class WsClient{
+    constructor(url){
+        this.url = url
+        this.authStatus = false
+        this.businessCallback = null
+        this.errorCallback = null
+        this.closeCallback = null
+        this.userAuthCallback = null
+        this.wsClient = null
+    }
+
+    initWebSocket(userAuthCallback,businessCallback,errorCallback,closeCallback){
+        if (this.wsClient) {
+            this.wsClient.close()
+            this.authStatus = false
+            this.businessCallback = null
+            this.businessFun = null
+            this.errorCallback = null
+            this.closeCallback = null
+            this.userAuthCallback = null
+            this.wsClient = null
+        }
+
+        this.wsClient = new WebSocket(this.url)
+        if (typeof userAuthCallback === 'function') this.userAuthCallback = userAuthCallback
+        if (typeof businessCallback === 'function') this.businessCallback = businessCallback
+        if (typeof errorCallback === 'function') this.errorCallback = errorCallback
+        if (typeof closeCallback === 'function') this.closeCallback = closeCallback
+        this.wsClient.onmessage = (e) => {
+            let msg = JSON.parse(e.data)
+            if(msg.type === 'ping') this.wsClient.send("WsClient check")
+            if(msg.type === 'auth' && msg.code === 1) {
+                this.authStatus = true
+                if (typeof this.userAuthCallback === 'function') {
+                    this.userAuthCallback(msg)
+                    this.userAuthCallback = null
+                }
+            }
+            /*一次性回调*/
+            if (typeof this.businessCallback === 'function') {
+
+                this.businessCallback(msg)
+                this.businessCallback = null
+            }
+            /*长期回调*/
+            if (typeof this.businessFun === 'function') this.businessFun(msg)
+        }
+        this.wsClient.onopen = () => {
+            this.log('WsClient open')
+            this.userAuth()
+        }
+        this.wsClient.onerror = (event) => {
+            this.log('WsClient error',event)
+            if (typeof this.errorCallback === 'function') {
+                this.errorCallback(event)
+                this.errorCallback = null
+            }
+        }
+        this.wsClient.onclose = (e) => {
+            this.log('WsClient close',e)
+            this.authStatus = false
+            if (typeof this.closeCallback === 'function') {
+                this.closeCallback(e)
+                this.closeCallback = null
+            }
+        }
+    }
+
+    setErrorCallback(fun){
+        this.errorCallback = typeof fun === 'function' ? fun : null
+        return this
+    }
+
+    setCloseCallback(fun){
+        this.closeCallback = typeof fun === 'function' ? fun : null
+        return this
+    }
+
+    setUserAuthCallback(fun){
+        this.userAuthCallback = typeof fun === 'function' ? fun : null
+        return this
+    }
+
+    setBusinessFun(fun){
+        this.businessFun = typeof fun === 'function' ? fun : null
+        return this
+    }
+
+    getAuthStatus(){
+        return this.authStatus
+    }
+
+    userAuth(){
+        let token = getToken()
+        let uuid = generateUUID()
+        if (!token || !uuid || !this.wsClient) return
+
+        this.send(JSON.stringify({type:'auth',token:token,machine:uuid}))
+    }
+
+
+
+    send(data,businessCallback){
+        if (this.wsClient.readyState !== WebSocket.OPEN) return
+        this.businessCallback = typeof businessCallback === 'function' ? businessCallback : null
+
+        this.wsClient.send(typeof data === 'string' ? data : JSON.stringify(data))
+    }
+
+    close(){
+        if (this.wsClient) this.wsClient.close()
+    }
+
+
+    log(message,...args){
+        if (process.env.NODE_ENV === 'development') console.log(message,...args)
+    }
+
+}
+
+export const wsClient = new WsClient(url)
+
+
+
+

+ 57 - 5
src/views/workbench/integral_review.vue

@@ -216,12 +216,14 @@
               <template #prepend>积分</template>
             </el-input>
           </el-col>
-          <el-col :span="event_review_point > 0 ? 14 : 19" >
+          <el-col :span="event_review_point > 0 ? 18 : 24" >
             <el-input :size=" event_review_point > 0 ? 'small' : 'medium'" v-model="currentItem.comment" maxlength="50" show-word-limit  clearable >
               <template #prepend>备注</template>
             </el-input>
           </el-col>
-          <el-col :span="event_review_point > 0 ? 4 : 5">
+        </el-row>
+        <el-row type="flex" justify="end" style="margin-bottom: 10px;">
+          <el-col :span="6" style="text-align: end">
             <el-button-group>
               <el-button :size=" event_review_point > 0 ? 'small' : 'medium'" type="warning" @click="disagree" :disabled="loading">驳回</el-button>
               <el-button :size=" event_review_point > 0 ? 'small' : 'medium'" type="primary" :disabled="!websocketAuth" :loading="loading" @click="agree">通过</el-button>
@@ -231,12 +233,14 @@
         <el-descriptions
             :column="1"
             border
-            :label-style="{textAlign:'center'}"
+            :label-style="{textAlign:'center',width:'100px'}"
             :content-style="{textAlign: 'center'}"
         >
+          <el-descriptions-item label="来源" v-if="currentItem.source_type_mark">{{currentItem.source_type_mark}}</el-descriptions-item>
           <el-descriptions-item label="姓名">{{currentItem.employee_name}}&nbsp;{{currentItem.dept}}</el-descriptions-item>
+          <el-descriptions-item label="记录人" v-if="currentItem.recorder_name">{{currentItem.recorder_name}}</el-descriptions-item>
           <el-descriptions-item label="积分">{{currentItem.point_mark}}&nbsp;{{$getTypsName(currentItem.pt_id)}}</el-descriptions-item>
-          <el-descriptions-item label="内容">{{currentItem.remark}}</el-descriptions-item>
+          <el-descriptions-item label="内容">{{currentItem.remark.customize}}</el-descriptions-item>
           <el-descriptions-item label="事件时间">{{currentItem.event_time}}</el-descriptions-item>
           <el-descriptions-item label="创建时间">{{currentItem.create_time}}</el-descriptions-item>
           <el-descriptions-item label="附件" v-if="currentItem.files && currentItem.files.length > 0">
@@ -248,6 +252,19 @@
                 :preview-src-list="currentItem.files"
             />
           </el-descriptions-item>
+          <el-descriptions-item label="完成时间" v-if="currentItem.complete_task.time">{{currentItem.complete_task.time || ''}}</el-descriptions-item>
+          <el-descriptions-item label="完成备注" v-if="currentItem.complete_task.remark">{{currentItem.complete_task.remark || ''}}</el-descriptions-item>
+          <el-descriptions-item label="任务附件" v-if="currentItem.complete_task && currentItem.complete_task.files && currentItem.complete_task.files.length > 0">
+            <el-image
+                v-for="(img,index) in currentItem.complete_task.files"
+                style="width: 80px; height: 80px;margin: 0 5px;"
+                :key="index"
+                :src="img"
+                :preview-src-list="currentItem.complete_task.files"
+            />
+          </el-descriptions-item>
+          <el-descriptions-item label="细则分类" v-if="currentItem.rule_list">{{currentItem.rule_list}}</el-descriptions-item>
+          <el-descriptions-item label="细则" v-if="currentItem.rule_item.remark">{{currentItem.rule_item.remark}}</el-descriptions-item>
         </el-descriptions>
 <!--        <template v-if="currentItem?.dc_remark?.flow?.length > 0">-->
         <template v-if="currentItem.dc_remark && currentItem.dc_remark.flow">
@@ -409,7 +426,34 @@ export default {
       currentItem:null,
       batchComment:'',
       batchPoint:0,
-      batchResult:[]
+      batchResult:[],
+      eventTypeRemark:{
+        1:'任务奖分',
+        2:'任务扣分',
+        3:'奖扣奖分',
+        4:'奖扣扣分',
+        5:'申请奖分',
+        6:'申请扣分',
+        7:'绩效任务包奖分',
+        8:'绩效任务包扣分',
+        9:'考勤系统奖分',
+        10:'考勤系统扣分',
+        11:'系统奖分',
+        12:'系统扣分',
+        13:'奖分任务扣分',
+        14:'扣分任务扣分',
+        15:'奖扣分任务比例扣分',
+        16:'奖扣分任务次数扣分',
+        17:'自动积分',
+        18:'导入积分奖分',
+        19:'导入积分扣分',
+        20:'A分转B分奖分',
+        21:'A分转B分扣分',
+        22:'钉钉报告(日志)奖分',
+        23:'钉钉报告(日志)扣分',
+        24:'任务提前完成奖分',
+        25:'任务逾期扣分',
+      }
     }
   },
   methods:{
@@ -528,6 +572,14 @@ export default {
             if (res.data.code !== 1) return
             this.currentItem.dc_remark = res.data.data.dc_remark
             this.currentItem.files = res.data.data.files
+            this.currentItem.rule_id = res.data.data.rule_id
+            this.currentItem.rule_item = res.data.data.rule_item
+            this.currentItem.rule_item_id = res.data.data.rule_item_id
+            this.currentItem.rule_list = res.data.data.rule_list
+            this.currentItem.remark = res.data.data.remark
+            this.currentItem.source_type_mark = res.data.data.source_type_mark
+            this.currentItem.recorder_name = res.data.data.recorder_name
+            this.currentItem.complete_task = res.data.data.complete_task
           })
           .finally(() => {
             this.loading = false