瀏覽代碼

Merge remote-tracking branch 'origin/dev-security' into dev-security

xiayu3 4 年之前
父節點
當前提交
5a85c7712a

+ 1 - 28
security-protection-platform/src/api/common/index.js

1
import http from '@/http'
1
import http from '@/http'
2
import { keysMappingReverse } from '@/utils/keysMapping'
3
// const mapping = {
4
//   id: 'code'
5
// }
6
const $default = http.$default
2
const $default = http.$default
7
const api = {
3
const api = {
8
  /**
4
  /**
18
    return $default.get('/sp/workEmployee/queryAllOrganize').then((resp) => {
14
    return $default.get('/sp/workEmployee/queryAllOrganize').then((resp) => {
19
      const data = resp.data.data
15
      const data = resp.data.data
20
      if (!Array.isArray(data)) return resp
16
      if (!Array.isArray(data)) return resp
21
      console.log(data)
22
      // eslint-disable-next-line one-var
23
      // const newData = [],
24
      //   map = {},
25
      //   queue = []
26
      // console.log(data)
27
      // data.forEach((item) => {
28
      //   if (item.parentCode === '-1') {
29
      //     const dep = { id: item.code, name: item.name, departments: [] }
30
      //     map[item.code] = newData.length
31
      //     newData.push(dep)
32
      //   } else {
33
      //     queue.push(item)
34
      //   }
35
      // })
36
      // queue.forEach((item) => {
37
      //   if (!(item.parentCode in map)) return
38
      //   const dep = { id: item.code, name: item.name }
39
      //   newData[map[item.parentCode]].departments.push(dep)
40
      // })
41
      // resp.data = newData
42
      // console.log(newData)
43
      // console.log('queryAllOrganize', resp)
17
      // 将平铺的数组变为树形数组
44
      resp.data = nest(data)
18
      resp.data = nest(data)
45
      // resp.data = keysMappingReverse(nest(data), mapping)
46
      return resp
19
      return resp
47
    })
20
    })
48
  },
21
  },

+ 25 - 21
security-protection-platform/src/modules/attendance/report/index.vue

23
            <t-table-column size="sm" prop="userid" label="员工编号"></t-table-column>
23
            <t-table-column size="sm" prop="userid" label="员工编号"></t-table-column>
24
            <t-table-column size="sm" prop="duty" label="职务"></t-table-column>
24
            <t-table-column size="sm" prop="duty" label="职务"></t-table-column>
25
            <t-table-column size="sm" prop="status" label="考勤状态">
25
            <t-table-column size="sm" prop="status" label="考勤状态">
26
              <template v-if="Array.isArray(scope.row.status)" slot-scope="scope">
27
                <span :class="getStatusClass(scope.row.status)">{{ scope.row.status.join('、') }}</span>
26
              <template slot-scope="scope">
27
                <span :class="getStatusClass(scope.row.goToWorkStatus)">{{ scope.row.goToWorkStatus }}</span>
28
                <span :class="getStatusClass(scope.row.goOffWorkStatus)">{{ scope.row.goOffWorkStatus }}</span>
28
              </template>
29
              </template>
29
            </t-table-column>
30
            </t-table-column>
30
          </t-table>
31
          </t-table>
146
      }
147
      }
147
    }
148
    }
148
  },
149
  },
149
  mounted() {
150
  mounted () {
150
    this.getDailyTable()
151
    this.getDailyTable()
151
  },
152
  },
152
  methods: {
153
  methods: {
153
    handleDailyInited() {
154
    handleDailyInited () {
154
      this.getDailyTable()
155
      this.getDailyTable()
155
    },
156
    },
156
    changeTabs(tabName) {
157
    changeTabs (tabName) {
157
      this.tabName = tabName
158
      this.tabName = tabName
158
      this.getMonthTable()
159
      this.getMonthTable()
159
    },
160
    },
176
      this.getMonthTable()
177
      this.getMonthTable()
177
    },
178
    },
178
    // 获得月报表格数据
179
    // 获得月报表格数据
179
    getMonthTable() {
180
    getMonthTable () {
180
      this.loadMonthTable = true
181
      this.loadMonthTable = true
181
      atdapi.getMonthAttendance({params: this.monthlyForm}).then(res => {
182
      atdapi.getMonthAttendance({ params: this.monthlyForm }).then(res => {
182
        let tableData = res.data.data
183
        let tableData = res.data.data
183
        this.monthTableData = []
184
        this.monthTableData = []
184
        tableData.forEach(element => {
185
        tableData.forEach(element => {
190
      })
191
      })
191
    },
192
    },
192
    // 获得日报表格数据
193
    // 获得日报表格数据
193
    getDailyTable() {
194
    getDailyTable () {
194
      this.loadDailyTable = true
195
      this.loadDailyTable = true
195
      atdapi.getDayAttendance({params: this.dailyForm}).then(res => {
196
      atdapi.getDayAttendance({ params: this.dailyForm }).then(res => {
196
        let tableData = res.data.data
197
        let tableData = res.data.data
197
        this.dailyTableData = []
198
        this.dailyTableData = []
198
        tableData.forEach(element => {
199
        tableData.forEach(element => {
204
      })
205
      })
205
    },
206
    },
206
    // 弹窗打开
207
    // 弹窗打开
207
    handleClick(data) {
208
    handleClick (data) {
208
      const { userid, beginDay, endDay } = data
209
      const { userid, beginDay, endDay } = data
209
      if (beginDay == null) {
210
      if (beginDay == null) {
210
        this.$Message.danger('未识别到有效的起止日期')
211
        this.$Message.danger('未识别到有效的起止日期')
223
        this.loadDetail = false
224
        this.loadDetail = false
224
      })
225
      })
225
    },
226
    },
226
    getStatusClass(status) {
227
      return status.join().match(/[(迟到)(早退)(旷工)(未打卡)]/) === null ? '' : 'abnormalState'
227
    getStatusClass (status) {
228
      if (status === '未打卡') {
229
        return 'abnormalState'
230
      }
231
      return ''
228
    }
232
    }
229
  }
233
  }
230
}
234
}
231
</script>
235
</script>
232
<style lang="scss" scoped>
236
<style lang="scss" scoped>
233
.page-main{
237
.page-main {
234
  margin: 20px 20px 16px 20px;
238
  margin: 20px 20px 16px 20px;
235
  .abnormalState{
236
    color: #EDA30F;
239
  .abnormalState {
240
    color: #eda30f;
237
    font-size: 14px;
241
    font-size: 14px;
238
  }
242
  }
239
  .keep-row{
243
  .keep-row {
240
    display: flex;
244
    display: flex;
241
    align-items: center;
245
    align-items: center;
242
  }
246
  }
243
  .search-btn{
247
  .search-btn {
244
    margin-left: auto;
248
    margin-left: auto;
245
    margin-right: 15px;
249
    margin-right: 15px;
246
  }
250
  }
247
  .icon-txt{
251
  .icon-txt {
248
    margin-right: 8px;
252
    margin-right: 8px;
249
  }
253
  }
250
  .export-excel{
254
  .export-excel {
251
    margin-top: 24px;
255
    margin-top: 24px;
252
    display: flex;
256
    display: flex;
253
    align-items: center;
257
    align-items: center;
254
  }
258
  }
255
  .table-detail{
259
  .table-detail {
256
    margin-top: 20px;
260
    margin-top: 20px;
257
  }
261
  }
258
  .pager{
262
  .pager {
259
    margin-right: auto;
263
    margin-right: auto;
260
    margin: 21px 21px 0 0;
264
    margin: 21px 21px 0 0;
261
    float: right;
265
    float: right;

+ 16 - 34
security-protection-platform/src/modules/system/attendance/components/AttendancePanel/index.vue

229
      if (data.length > 0) {
229
      if (data.length > 0) {
230
        data.forEach(item => {
230
        data.forEach(item => {
231
          arr.push({
231
          arr.push({
232
            id: item.id + '',
232
            orgId: item.id + '',
233
            id: item.code,
233
            label: item.name,
234
            label: item.name,
234
            pid: item.parentCode
235
            pid: item.parentCode
235
          })
236
          })
236
          // 如果没有中值 默认选中一个值 这里是一般是公司的考勤
237
          // 如果没有中值 默认选中一个值 这里是默认展示根节点的考勤规则
237
          if (this.treeValue.length === 0) this.handleDeptChange([item.id + ''])
238
          if (this.treeValue.length === 0) this.handleDeptChange([item.id + ''])
238
          this.nextDepartment(item.departments, arr)
239
          this.nextDepartment(item.departments, arr)
239
        })
240
        })
244
      this.loadDepts = true
245
      this.loadDepts = true
245
      commonapi.getDepartments().then(resp => {
246
      commonapi.getDepartments().then(resp => {
246
        const data = []
247
        const data = []
247
        // console.log(resp.data)
248
249
        // resp.data.forEach(item => {
250
        //   const orgId = item.id + ''
251
        //   data.push({
252
        //     id: orgId,
253
        //     label: item.name
254
        //     // disabled: true
255
        //   })
256
        //   item.departments.forEach(dept => {
257
        //     const deptId = dept.id + ''
258
        //     data.push({
259
        //       id: deptId,
260
        //       label: dept.name,
261
        //       pid: orgId
262
        //     })
263
        //     if (this.treeValue.length === 0) this.handleDeptChange([deptId])
264
        //     if (dept.departments.length > 0) {
265
        //       dept.departments.forEach(child => {
266
        //         const childId = child.id + ''
267
        //         data.push({
268
        //           id: childId,
269
        //           label: child.name,
270
        //           pid: deptId
271
        //         })
272
        //         this.handleDeptChange([childId])
273
        //       })
274
        //     }
275
        //   })
276
        // })
277
        // 递归
248
        // 递归 实现tree组件所需部门数据结构
278
        this.nextDepartment(resp.data, data)
249
        this.nextDepartment(resp.data, data)
279
        // 删除pid为"-1"的的pid属性,否则tree渲染的时候没有根节点渲染不出来
250
        // 深拷贝data
251
        const data1 = JSON.parse(JSON.stringify(data))
252
        // 用部门id映射关系代替code与parentCode父子映射关系
280
        data.forEach(item => {
253
        data.forEach(item => {
254
          // 删除pid为"-1"的的pid属性,否则tree渲染的时候没有根节点渲染不出来
281
          if (item.pid === '-1') {
255
          if (item.pid === '-1') {
282
            delete item.pid
256
            delete item.pid
283
          }
257
          }
258
          item.id = item.orgId
259
          data1.some((item1) => {
260
            if (item.pid === item1.id) {
261
              item.pid = item1.orgId
262
            } else {
263
              return false
264
            }
265
          })
284
        })
266
        })
285
        this.treeData = data
267
        this.treeData = data
286
      }).finally(() => {
268
      }).finally(() => {

+ 16 - 19
security-protection-platform/src/modules/system/attendance/components/SchedulePanel/ShiftDialog.vue

5
        <t-input v-model="form.title" style="width:300px"></t-input>
5
        <t-input v-model="form.title" style="width:300px"></t-input>
6
      </t-form-item>
6
      </t-form-item>
7
7
8
      <t-table :resizable="false" :data="form.shifts" class="shift-dialog__table" >
8
      <t-table :resizable="false" :data="form.shifts" class="shift-dialog__table">
9
        <t-table-column v-slot="{ row, $index }" label="班组名称">
9
        <t-table-column v-slot="{ row, $index }" label="班组名称">
10
          <t-form-item :prop="`shifts.${$index}.label`" :rules="{ required: true, message: '', trigger: 'blur' }">
10
          <t-form-item :prop="`shifts.${$index}.label`" :rules="{ required: true, message: '', trigger: 'blur' }">
11
            <t-input v-model="row.label"></t-input>
11
            <t-input v-model="row.label"></t-input>
14
14
15
        <t-table-column v-slot="{ row, $index }" label="考勤时段">
15
        <t-table-column v-slot="{ row, $index }" label="考勤时段">
16
          <t-form-item :prop="`shifts.${$index}.endTime`" :rules="{ required: true, message: '', trigger: 'blur' }">
16
          <t-form-item :prop="`shifts.${$index}.endTime`" :rules="{ required: true, message: '', trigger: 'blur' }">
17
            <time-range-picker
18
              v-model="row"
19
              format="HH:mm"
20
              style="width: 100%"
21
            />
17
            <time-range-picker v-model="row" format="HH:mm" style="width: 100%" />
22
          </t-form-item>
18
          </t-form-item>
23
        </t-table-column>
19
        </t-table-column>
24
20
56
  props: {
52
  props: {
57
    data: {
53
    data: {
58
      type: Object,
54
      type: Object,
59
      default() {
55
      default () {
60
        return {}
56
        return {}
61
      }
57
      }
62
    }
58
    }
63
  },
59
  },
64
  data() {
60
  data () {
65
    return {
61
    return {
66
      visibled: false,
62
      visibled: false,
67
      form: {},
63
      form: {},
75
    }
71
    }
76
  },
72
  },
77
  computed: {
73
  computed: {
78
    title() {
74
    title () {
79
      return this.data.scheduleId == null ? '新增班次' : '编辑班次'
75
      return this.data.scheduleId == null ? '新增班次' : '编辑班次'
80
    }
76
    }
81
  },
77
  },
82
  watch: {
78
  watch: {
83
    data(val) {
79
    data (val) {
84
      this.form = JSON.parse(JSON.stringify(val))
80
      this.form = JSON.parse(JSON.stringify(val))
85
      // this.$refs['form'] && this.$refs['form'].resetFields()
81
      // this.$refs['form'] && this.$refs['form'].resetFields()
86
      this.visibled = true
82
      this.visibled = true
87
    }
83
    }
88
  },
84
  },
89
  methods: {
85
  methods: {
90
    handleDelete(index) {
86
    handleDelete (index) {
91
      this.form.shifts.splice(index, 1)
87
      this.form.shifts.splice(index, 1)
92
    },
88
    },
93
    handleAdd() {
89
    handleAdd () {
94
      this.form.shifts.push(Object.assign({}, shiftTempl))
90
      this.form.shifts.push(Object.assign({}, shiftTempl))
95
    },
91
    },
96
    handleSubmit() {
92
    handleSubmit () {
97
      this.$refs['form'].validate(valid => {
93
      this.$refs['form'].validate(valid => {
98
        if (valid) {
94
        if (valid) {
99
          if (this.form.shifts.length === 0) {
95
          if (this.form.shifts.length === 0) {
104
        }
100
        }
105
      })
101
      })
106
    },
102
    },
107
    submitSchedule() {
103
    submitSchedule () {
108
      this.loadingSubmit = true
104
      this.loadingSubmit = true
109
      sysapi.submitSchedule(this.form).then(resp => {
105
      sysapi.submitSchedule(this.form).then(resp => {
110
        if (resp.data.ScheduleId == null) {
106
        if (resp.data.ScheduleId == null) {
126
122
127
<style lang="scss">
123
<style lang="scss">
128
.shift-dialog__table {
124
.shift-dialog__table {
129
  border: 1px solid #E8E8E8;
125
  border: 1px solid #e8e8e8;
130
  border-radius: 2px;
126
  border-radius: 2px;
131
  td, th {
127
  td,
128
  th {
132
    height: 40px;
129
    height: 40px;
133
    font-weight: normal;
130
    font-weight: normal;
134
  }
131
  }
135
132
136
  thead > tr > th {
133
  thead > tr > th {
137
    background-color: #FAFAFA;
138
    color: rgba(0, 0, 0, 0.65)
134
    background-color: #fafafa;
135
    color: rgba(0, 0, 0, 0.65);
139
  }
136
  }
140
137
141
  .form-group {
138
  .form-group {
147
144
148
  .table__empty-block {
145
  .table__empty-block {
149
    min-height: auto;
146
    min-height: auto;
150
    border-bottom: 1px solid #E8E8E8;
147
    border-bottom: 1px solid #e8e8e8;
151
  }
148
  }
152
149
153
  &-append {
150
  &-append {

+ 23 - 25
security-protection-platform/src/modules/system/attendance/components/SchedulePanel/index.vue

3
    <t-loading v-model="loading" />
3
    <t-loading v-model="loading" />
4
    <t-button color="primary" style="margin-bottom:30px;" @click="handleCreate">新增</t-button>
4
    <t-button color="primary" style="margin-bottom:30px;" @click="handleCreate">新增</t-button>
5
    <div class="schedule-card-block">
5
    <div class="schedule-card-block">
6
      <schedule-card
7
        v-for="item in schedules"
8
        :key="item.scheduleId"
9
        :data="item"
10
        @edit="handleEdit"
11
        @deleted="handleDeleted"
12
      />
6
      <schedule-card v-for="item in schedules" :key="item.scheduleId" :data="item" @edit="handleEdit" @deleted="flushPage()" />
13
      <div v-if="!loading && schedules.length === 0" class="schedule-card-block__empty">点击 “新增” 按钮增加班次</div>
7
      <div v-if="!loading && schedules.length === 0" class="schedule-card-block__empty">点击 “新增” 按钮增加班次</div>
14
    </div>
8
    </div>
15
    <shift-dialog :data="dialogData" @submit="handleScheduleSubmit" />
9
    <shift-dialog :data="dialogData" @submit="flushPage()" />
16
  </div>
10
  </div>
17
</template>
11
</template>
18
12
22
import sysapi from '@/api/system'
16
import sysapi from '@/api/system'
23
export default {
17
export default {
24
  components: { ScheduleCard, ShiftDialog },
18
  components: { ScheduleCard, ShiftDialog },
25
  data() {
19
  inject: ['reload'],
20
  data () {
26
    return {
21
    return {
27
      schedules: [],
22
      schedules: [],
28
      dialogData: {},
23
      dialogData: {},
29
      loading: true
24
      loading: true
30
    }
25
    }
31
  },
26
  },
32
  mounted() {
27
  mounted () {
33
    this.getSchedules()
28
    this.getSchedules()
34
  },
29
  },
35
  methods: {
30
  methods: {
36
    getSchedules() {
31
    flushPage () {
32
      this.getSchedules()
33
      this.reload()
34
    },
35
    getSchedules () {
37
      this.loading = true
36
      this.loading = true
38
      sysapi.getSchedules().then((resp) => {
37
      sysapi.getSchedules().then((resp) => {
39
        this.schedules = resp.data || []
38
        this.schedules = resp.data || []
41
        this.loading = false
40
        this.loading = false
42
      })
41
      })
43
    },
42
    },
44
    handleEdit(item) {
43
    handleEdit (item) {
45
      this.dialogData = Object.assign({}, item)
44
      this.dialogData = Object.assign({}, item)
46
      console.log(item.shifts)
47
    },
45
    },
48
    handleCreate() {
46
    handleCreate () {
49
      this.dialogData = {
47
      this.dialogData = {
50
        title: '',
48
        title: '',
51
        shifts: []
49
        shifts: []
52
      }
50
      }
53
    },
54
    handleDeleted(index) {
55
      this.schedules.splice(index, 1)
56
    },
57
    handleScheduleSubmit(data) {
58
      if (this.dialogData.scheduleId != null) {
59
        const target = this.schedules.find(item => item.scheduleId === this.dialogData.scheduleId)
60
        Object.assign(target, data)
61
      } else {
62
        this.schedules.unshift(data)
63
      }
64
    }
51
    }
52
    // handleDeleted (index) {
53
    //   this.schedules.splice(index, 1)
54
    // },
55
    // handleScheduleSubmit (data) {
56
    //   if (this.dialogData.scheduleId != null) {
57
    //     const target = this.schedules.find(item => item.scheduleId === this.dialogData.scheduleId)
58
    //     Object.assign(target, data)
59
    //   } else {
60
    //     this.schedules.unshift(data)
61
    //   }
62
    // }
65
  }
63
  }
66
}
64
}
67
</script>
65
</script>

+ 14 - 5
security-protection-platform/src/modules/system/attendance/index.vue

4
      <t-tab-panel label="班次时间" panel-id="tab-1">
4
      <t-tab-panel label="班次时间" panel-id="tab-1">
5
        <schedule-panel class="sys-attendance__page" />
5
        <schedule-panel class="sys-attendance__page" />
6
      </t-tab-panel>
6
      </t-tab-panel>
7
      <t-tab-panel label="考勤规则" panel-id="tab-2">
7
      <t-tab-panel v-if="isShow" label="考勤规则" panel-id="tab-2">
8
        <attendance-panel class="sys-attendance__page" />
8
        <attendance-panel class="sys-attendance__page" />
9
      </t-tab-panel>
9
      </t-tab-panel>
10
    </t-tabs>
10
    </t-tabs>
18
18
19
export default {
19
export default {
20
  components: { SchedulePanel, AttendancePanel },
20
  components: { SchedulePanel, AttendancePanel },
21
  data() {
21
  provide () {
22
    return { reload: this.reload }
23
  },
24
  data () {
22
    return {
25
    return {
23
26
      isShow: true
24
    }
27
    }
25
  },
28
  },
26
  mounted() {
29
  mounted () {
27
30
28
  },
31
  },
29
  methods: {
32
  methods: {
30
33
    // 刷新考勤规则组件
34
    reload () {
35
      this.isShow = false
36
      this.$nextTick(() => {
37
        this.isShow = true
38
      })
39
    }
31
  }
40
  }
32
}
41
}
33
</script>
42
</script>

+ 1 - 1
security-protection-platform/src/modules/system/devicemana/components/modal/addDeviceModal.vue

110
    // 当前编辑设备
110
    // 当前编辑设备
111
    currentEditDevice (val) {
111
    currentEditDevice (val) {
112
      this.addDeviceModalForm = val
112
      this.addDeviceModalForm = val
113
      this.imgUrl = val.toolPictureUrl
113
      this.imgUrl = val.imgUrl
114
    }
114
    }
115
  },
115
  },
116
  mounted () {
116
  mounted () {