LG88888888 3 years ago
parent
commit
2830195111

+ 1 - 1
.env.production

@@ -1,4 +1,4 @@
 NODE_ENV=production
-VUE_APP_API_BASE_URL=https://bootapi.jeecg.com
+VUE_APP_API_BASE_URL=http://127.0.0.1:8080/jeecg-boot
 VUE_APP_CAS_BASE_URL=http://localhost:8888/cas
 VUE_APP_ONLINE_BASE_URL=http://fileview.jeecg.com/onlinePreview

+ 4 - 2
src/api/api.js

@@ -99,7 +99,8 @@ const synchronizationWeixin= (params)=>getAction("/sys/weixin/synchronizationWei
 
 const tbquery= (params)=>getAction("/sys/weixin/list",params);
 //把用户考勤数据同步到平台
-const synchronizationPt= (params)=>getAction("/sys/weixin/synchronizationpt",params);
+const synchronizationPt= (params)=>getAction("/sys/weixin/tpPT",params);
+const U8= (params)=>getAction("/sys/weixin/U8",params);
 // 中转HTTP请求
 export const transitRESTful = {
   get: (url, parameter) => getAction(getTransitURL(url), parameter),
@@ -166,7 +167,8 @@ export {
   pullData,
   synchronizationWeixin,
   tbquery,
-  synchronizationPt
+  synchronizationPt,
+  U8
 }
 
 

+ 197 - 0
src/views/system/Shift.vue

@@ -0,0 +1,197 @@
+<template>
+  <a-card :bordered="false">
+
+    <!-- 查询区域 -->
+    <div class="table-page-search-wrapper">
+      <a-form layout="inline" @keyup.enter.native="searchQuery">
+        <a-row :gutter="24">
+
+          <a-col :xl="6" :lg="7" :md="8" :sm="24">
+            <a-form-item label="名称">
+              <a-input placeholder="请输入名称" v-model="queryParam.name"></a-input>
+            </a-form-item>
+          </a-col>
+          <!-- <a-col :xl="6" :lg="7" :md="8" :sm="24">
+            <a-form-item label="上班时间">
+              <a-input placeholder="请输入上班时间" v-model="queryParam.startDate"></a-input>
+            </a-form-item>
+          </a-col>
+        <template v-if="toggleSearchStatus">
+          <a-col :xl="6" :lg="7" :md="8" :sm="24">
+            <a-form-item label="下班时间">
+              <a-input placeholder="请输入下班时间" v-model="queryParam.endDate"></a-input>
+            </a-form-item>
+          </a-col>
+         
+          </template> -->
+          <a-col :xl="6" :lg="7" :md="8" :sm="24">
+            <span style="float: left;overflow: hidden;" class="table-page-search-submitButtons">
+              <a-button type="primary" @click="searchQuery" icon="search">查询</a-button>
+              <a-button type="primary" @click="searchReset" icon="reload" style="margin-left: 8px">重置</a-button>
+              <a @click="handleToggleSearch" style="margin-left: 8px">
+                {{ toggleSearchStatus ? '收起' : '展开' }}
+                <a-icon :type="toggleSearchStatus ? 'up' : 'down'"/>
+              </a>
+            </span>
+          </a-col>
+
+        </a-row>
+      </a-form>
+    </div>
+
+    <!-- 操作按钮区域 -->
+    <div class="table-operator">
+      <a-button @click="handleAdd" type="primary" icon="plus">新增</a-button>
+      <!-- <a-button type="primary" icon="download" @click="handleExportXls('班次档案')">导出</a-button>
+      <a-upload name="file" :showUploadList="false" :multiple="false" :headers="tokenHeader" :action="importExcelUrl" @change="handleImportExcel">
+        <a-button type="primary" icon="import">导入</a-button>
+      </a-upload> -->
+      <a-dropdown v-if="selectedRowKeys.length > 0">
+        <a-menu slot="overlay">
+          <a-menu-item key="1" @click="batchDel"><a-icon type="delete"/>删除</a-menu-item>
+        </a-menu>
+        <a-button style="margin-left: 8px"> 批量操作 <a-icon type="down" /></a-button>
+      </a-dropdown>
+    </div>
+
+    <!-- table区域-begin -->
+    <div>
+      <div class="ant-alert ant-alert-info" style="margin-bottom: 16px;">
+        <i class="anticon anticon-info-circle ant-alert-icon"></i> 已选择 <a style="font-weight: 600">{{ selectedRowKeys.length }}</a>项
+        <a style="margin-left: 24px" @click="onClearSelected">清空</a>
+      </div>
+
+      <a-table
+        ref="table"
+        size="middle"
+        bordered
+        rowKey="id"
+        :columns="columns"
+        :dataSource="dataSource"
+        :pagination="ipagination"
+        :loading="loading"
+        class="j-table-force-nowrap"
+        :rowSelection="{selectedRowKeys: selectedRowKeys, onChange: onSelectChange}"
+        @change="handleTableChange">
+
+        <span slot="action" slot-scope="text, record">
+          <a @click="handleEdit(record)">编辑</a>
+
+          <a-divider type="vertical" />
+          <a-dropdown>
+            <a class="ant-dropdown-link">更多 <a-icon type="down" /></a>
+            <a-menu slot="overlay">
+              <a-menu-item>
+                <a-popconfirm title="确定删除吗?" @confirm="() => handleDelete(record.id)">
+                  <a>删除</a>
+                </a-popconfirm>
+              </a-menu-item>
+              <!-- <a-menu-item>
+               <a @click="handleAdd2">排班</a>
+               </a-menu-item> -->
+            </a-menu>
+          </a-dropdown>
+        </span>
+
+      </a-table>
+    </div>
+    <!-- table区域-end -->
+
+    <!-- 表单区域 -->
+    <shift-modal ref="modalForm" @ok="modalFormOk"></shift-modal>
+    
+    <user-shift-list-modal modal ref="UserShiftListModal" ></user-shift-list-modal>
+  </a-card>
+</template>
+
+<script>
+  import '@/assets/less/TableExpand.less'
+  import ShiftModal from './modules/ShiftModal'
+  import UserShiftListModal from './modules/UserShiftListModal'
+  
+  import { JeecgListMixin } from '@/mixins/JeecgListMixin'
+import moment from "moment"
+  export default {
+    name: "ShiftList",
+    mixins:[JeecgListMixin],
+    components: {
+      ShiftModal,
+	  UserShiftListModal
+    },
+    data () {
+      return {
+        description: '班次档案管理页面',
+        // 表头
+        columns: [
+          {
+            title: '#',
+            dataIndex: '',
+            key:'rowIndex',
+            width:60,
+            align:"center",
+            customRender:function (t,r,index) {
+              return parseInt(index)+1;
+            }
+           },
+		   {
+            title: '班次名称',
+            align:"center",
+            dataIndex: 'name'
+           },
+		   {
+            title: '上班时间',
+            align:"center",
+            dataIndex: 'startDate',
+            customRender:function(t,r,index){
+              return moment(t).format('HH:mm:ss');
+            }
+           },
+		   {
+            title: '下班时间',
+            align:"center",
+            dataIndex: 'endDate',
+            customRender:function(t,r,index){
+              return moment(t).format('HH:mm:ss');
+            }
+           },
+		   {
+            title: '创建时间',
+            align:"center",
+            dataIndex: 'createTime'
+           },
+		   {
+            title: '创建人',
+            align:"center",
+            dataIndex: 'createBy'
+           },
+          {
+            title: '操作',
+            dataIndex: 'action',
+            align:"center",
+            scopedSlots: { customRender: 'action' },
+          }
+        ],
+		url: {
+          list: "/shift/shift/list",
+          delete: "/shift/shift/delete",
+          deleteBatch: "/shift/shift/deleteBatch",
+          exportXlsUrl: "shift/shift/exportXls",
+          importExcelUrl: "shift/shift/importExcel",
+       },
+    }
+  },
+  computed: {
+    importExcelUrl: function(){
+      return `${window._CONFIG['domianURL']}/${this.url.importExcelUrl}`;
+    }
+  },
+    methods: {
+     handleAdd2:function(){
+       this.$refs.UserShiftListModal.show();
+     }
+    }
+  }
+</script>
+<style scoped>
+  @import '~@assets/less/common.less';
+</style>

+ 11 - 5
src/views/system/UserList.vue

@@ -66,6 +66,7 @@
     <!-- 操作按钮区域 -->
     <div class="table-operator" style="border-top: 5px">
       <a-button @click="handleAdd()" type="primary" icon="plus" v-has="'user:add'" >添加用户</a-button>
+      <a-button @click="shiftAdd()" type="primary" icon="plus"  >排班</a-button>
       <a-button type="primary" icon="download" @click="handleExportXls('用户信息')" v-has='"user:export"'>导出</a-button>
       <a-upload name="file" :showUploadList="false" :multiple="false" :headers="tokenHeader" :action="importExcelUrl" @change="handleImportExcel" v-has='"user:import"'>
         <a-button type="primary" icon="import">导入</a-button>
@@ -164,6 +165,7 @@
     </div>
     <!-- table区域-end -->
 
+  <userShift-modal ref="userShiftModal" ></userShift-modal>
     <user-modal ref="modalForm" @ok="modalFormOk"></user-modal>
 
     <password-modal ref="passwordmodal" @ok="passwordModalOk"></password-modal>
@@ -172,6 +174,7 @@
     <user-recycle-bin-modal :visible.sync="recycleBinVisible" @ok="modalFormOk"/>
 
   </a-card>
+  
 </template>
 
 <script>
@@ -183,7 +186,7 @@
   import JInput from '@/components/jeecg/JInput'
   import UserRecycleBinModal from './modules/UserRecycleBinModal'
   import JSuperQuery from '@/components/jeecg/JSuperQuery'
-
+import UserShiftModal from './modules/UserShiftModal'
   export default {
     name: "UserList",
     mixins: [JeecgListMixin],
@@ -192,7 +195,7 @@
       PasswordModal,
       JInput,
       UserRecycleBinModal,
-      
+      UserShiftModal,
       JSuperQuery
     },
     data() {
@@ -253,10 +256,10 @@
             dataIndex: 'phone'
           },
           {
-            title: '组织',
+            title: '邮箱',
             align: "center",
             width: 120,
-            dataIndex: 'orgText'
+            dataIndex: 'email'
           },
           {
             title: '部门',
@@ -307,7 +310,10 @@
       }
     },
     methods: {
-      
+      shiftAdd(){
+        this.$refs.userShiftModal.visible=true;
+        
+      },
       getAvatarView: function (avatar) {
         return getFileAccessHttpUrl(avatar)
       },

+ 187 - 0
src/views/system/UserShiftList.vue

@@ -0,0 +1,187 @@
+<template>
+  <a-card :bordered="false">
+
+    <!-- 查询区域 -->
+    <div class="table-page-search-wrapper">
+      <a-form layout="inline" @keyup.enter.native="searchQuery">
+        <a-row :gutter="24">
+
+          <a-col :xl="6" :lg="7" :md="8" :sm="24">
+            <a-form-item label="用户姓名">
+              <a-input placeholder="请输入用户姓名" v-model="queryParam.realname"></a-input>
+            </a-form-item>
+          </a-col>
+         
+          <a-col :xl="6" :lg="7" :md="8" :sm="24">
+            <span style="float: left;overflow: hidden;" class="table-page-search-submitButtons">
+              <a-button type="primary" @click="searchQuery" icon="search">查询</a-button>
+              <a-button type="primary" @click="searchReset" icon="reload" style="margin-left: 8px">重置</a-button>
+              <a @click="handleToggleSearch" style="margin-left: 8px">
+                {{ toggleSearchStatus ? '收起' : '展开' }}
+                <a-icon :type="toggleSearchStatus ? 'up' : 'down'" />
+              </a>
+            </span>
+          </a-col>
+
+        </a-row>
+      </a-form>
+    </div>
+<div class="table-operator" style="border-top: 5px">
+      <a-button @click="handleAdd()" type="primary" icon="plus" v-has="'user:add'" >添加用户</a-button>
+    
+    </div>
+    <!-- 操作按钮区域 -->
+    <div class="table-operator">
+      
+    </div>
+
+    <!-- table区域-begin -->
+    <div>
+      <div class="ant-alert ant-alert-info" style="margin-bottom: 16px;">
+        <i class="anticon anticon-info-circle ant-alert-icon"></i> 已选择 <a
+          style="font-weight: 600">{{ selectedRowKeys.length }}</a>项
+        <a style="margin-left: 24px" @click="onClearSelected">清空</a>
+      </div>
+
+      <a-table ref="table" size="middle" bordered rowKey="id" :columns="columns" :dataSource="dataSource"
+        :pagination="ipagination" :loading="loading" class="j-table-force-nowrap"
+        :rowSelection="{selectedRowKeys: selectedRowKeys, onChange: onSelectChange}" @change="handleTableChange">
+          
+        <span slot="action" slot-scope="text, record">
+          <a @click="handleEdit(record)">排班</a>
+
+          <a-divider type="vertical" />
+          <a-dropdown>
+            <a class="ant-dropdown-link">更多
+              <a-icon type="down" />
+            </a>
+            <a-menu slot="overlay">
+             <!-- <a-menu-item>
+                <a-popconfirm title="确定删除吗?" @confirm="() => handleDelete(record.id)">
+                  <a>删除</a>
+                </a-popconfirm>
+              </a-menu-item> -->
+              <a-menu-item >
+              </a-menu-item>
+            </a-menu>
+          </a-dropdown>
+        </span>
+
+      </a-table>
+    </div>
+    <!-- table区域-end -->
+
+    <!-- 表单区域 -->
+    <userShift-modal ref="modalForm" @ok="modalFormOk"></userShift-modal>
+  </a-card>
+</template>
+
+<script>
+  import '@/assets/less/TableExpand.less'
+  import UserShiftModal from './modules/UserShiftModal'
+  import {
+    JeecgListMixin
+  } from '@/mixins/JeecgListMixin'
+import moment from "moment"
+  export default {
+    name: "UserShiftList",
+    mixins: [JeecgListMixin],
+    components: {
+      UserShiftModal
+    },
+    data() {
+      return {
+        description: '员工排班管理页面',
+        // 表头
+       columns: [
+         /*{
+           title: '#',
+           dataIndex: '',
+           key:'rowIndex',
+           width:60,
+           align:"center",
+           customRender:function (t,r,index) {
+             return parseInt(index)+1;
+           }
+         },*/
+         {
+           title: '用户账号',
+           align: "center",
+           dataIndex: 'username',
+           width: 120,
+           sorter: true
+         },
+         {
+           title: '用户姓名',
+           align: "center",
+           width: 100,
+           dataIndex: 'realname',
+         },
+       
+         {
+           title: '性别',
+           align: "center",
+           width: 80,
+           dataIndex: 'sex_dictText',
+           sorter: true
+         },
+         {
+           title: '生日',
+           align: "center",
+           width: 100,
+           dataIndex: 'birthday'
+         },
+         {
+           title: '手机号码',
+           align: "center",
+           width: 120,
+           dataIndex: 'phone'
+         },
+         {
+           title: '邮箱',
+           align: "center",
+           width: 120,
+           dataIndex: 'email'
+         },
+         {
+           title: '部门',
+           align: "center",
+           width: 120,
+           dataIndex: 'orgCodeTxt'
+         },
+        
+         {
+           title: '操作',
+           dataIndex: 'action',
+           scopedSlots: {customRender: 'action'},
+           align: "center",
+           width: 170
+         }
+       
+       ],
+         
+        url: {
+          list: "/sys/user/list",
+          delete: "/userShift/userShift/delete",
+          deleteBatch: "/userShift/userShift/deleteBatch",
+          exportXlsUrl: "userShift/userShift/exportXls",
+          importExcelUrl: "userShift/userShift/importExcel",
+        },
+      }
+    },
+    computed: {
+      importExcelUrl: function() {
+        return `${window._CONFIG['domianURL']}/${this.url.importExcelUrl}`;
+      }
+    },
+    methods: {
+      getAvatarView: function (avatar) {
+        return getFileAccessHttpUrl(avatar)
+      },
+
+    }
+  }
+</script>
+<style scoped>
+  @import '~@assets/less/common.less';
+</style>

+ 191 - 0
src/views/system/modules/ShiftModal.vue

@@ -0,0 +1,191 @@
+<template>
+  <j-modal
+    :title="title"
+    :width="800"
+    :visible="visible"
+    :confirmLoading="confirmLoading"
+    switchFullscreen
+    @ok="handleOk"
+    @cancel="handleCancel"
+    cancelText="关闭">
+    
+    <a-spin :spinning="confirmLoading">
+      <a-form :form="form">
+      
+        <a-form-item
+          :labelCol="labelCol"
+          :wrapperCol="wrapperCol"
+          label="名称">
+          <a-input placeholder="请输入名称" v-decorator="['name', validatorRules.name]" />
+        </a-form-item>
+        <a-form-item
+          :labelCol="labelCol"
+          :wrapperCol="wrapperCol"
+          label="上班时间">
+         
+          <a-time-picker showTime format='HH:mm:ss' v-decorator="[ 'startDate', validatorRules.startDate]" />
+        </a-form-item>
+        <a-form-item
+          :labelCol="labelCol"
+          :wrapperCol="wrapperCol"
+          label="下班时间">
+          <a-time-picker showTime format='HH:mm:ss' v-decorator="[ 'endDate', validatorRules.endDate]" />
+        </a-form-item>
+        
+        <!-- <a-form-item
+          :labelCol="labelCol"
+          :wrapperCol="wrapperCol"
+          label="创建时间">
+          <a-date-picker showTime format='YYYY-MM-DD HH:mm:ss' v-decorator="[ 'createDate', {}]" />
+        </a-form-item>
+        <a-form-item
+          :labelCol="labelCol"
+          :wrapperCol="wrapperCol"
+          label="修改时间">
+          <a-date-picker showTime format='YYYY-MM-DD HH:mm:ss' v-decorator="[ 'updateDate', {}]" />
+        </a-form-item> -->
+       <!-- <a-form-item
+          :labelCol="labelCol"
+          :wrapperCol="wrapperCol"
+          label="删除标记">
+          <a-input placeholder="请输入删除标记" v-decorator="['delFlag', {}]" />
+        </a-form-item> -->
+		
+      </a-form>
+    </a-spin>
+  </j-modal>
+</template>
+
+<script>
+  import { httpAction } from '@/api/manage'
+  import pick from 'lodash.pick'
+  import moment from "moment"
+
+  export default {
+    name: "ShiftModal",
+    data () {
+      return {
+        title:"操作",
+        visible: false,
+        model: {},
+        labelCol: {
+          xs: { span: 24 },
+          sm: { span: 5 },
+        },
+        wrapperCol: {
+          xs: { span: 24 },
+          sm: { span: 16 },
+        },
+
+        confirmLoading: false,
+        form: this.$form.createForm(this),
+        validatorRules:{
+          name:{
+            rules: [{
+              required: true, message: '请输入班次名称!'
+            }]
+          },
+          startDate:{
+            rules: [{
+              required: true, message: '请选择上班时间!'
+            }]
+          },
+          endDate:{
+            rules: [{
+              required: true, message: '请选择下班时间!'
+            }]
+          },
+        },
+        url: {
+          add: "/shift/shift/add",
+          edit: "/shift/shift/edit",
+        },
+      }
+    },
+    created () {
+    },
+    methods: {
+      add () {
+        this.edit({});
+      },
+      edit (record) {
+        this.form.resetFields();
+        this.model = Object.assign({}, record);
+        this.visible = true;
+        this.$nextTick(() => {
+          this.form.setFieldsValue(pick(this.model,'name','delFlag'))
+		  //时间格式化
+          this.form.setFieldsValue({startDate:this.model.startDate?moment(this.model.startDate):null})
+          this.form.setFieldsValue({endDate:this.model.endDate?moment(this.model.endDate):null})
+          // this.form.setFieldsValue({createDate:this.model.createDate?moment(this.model.createDate):null})
+          // this.form.setFieldsValue({updateDate:this.model.updateDate?moment(this.model.updateDate):null})
+        });
+
+      },
+      close () {
+        this.$emit('close');
+        this.visible = false;
+      },
+      handleOk () {
+        const that = this;
+        // if(this.model.name==null||this.model.name==""){
+        //   that.$message.warning("请输入班次名称!");
+        //   return;
+        // }if(this.model.startDate==null||this.model.startDate==""){
+        //   that.$message.warning("请选择上班时间!");
+        //   return;
+        // }if(this.model.endDate==null||this.model.endDate==""){
+        //   that.$message.warning("请选择下班班时间!");
+        //   return;
+        // }
+        // 触发表单验证
+        this.form.validateFields((err, values) => {
+          console.log(err)
+          if (!err) {
+            that.confirmLoading = true;
+            let httpurl = '';
+            let method = '';
+            if(!this.model.id){
+              httpurl+=this.url.add;
+              method = 'post';
+            }else{
+              httpurl+=this.url.edit;
+               method = 'put';
+            }
+            let formData = Object.assign(this.model, values);
+            //时间格式化
+            formData.startDate = formData.startDate?formData.startDate.format('YYYY-MM-DD HH:mm:ss'):null;
+            formData.endDate = formData.endDate?formData.endDate.format('YYYY-MM-DD HH:mm:ss'):null;
+            // formData.createDate = formData.createDate?formData.createDate.format('YYYY-MM-DD HH:mm:ss'):null;
+            // formData.updateDate = formData.updateDate?formData.updateDate.format('YYYY-MM-DD HH:mm:ss'):null;
+            
+            console.log(formData)
+            httpAction(httpurl,formData,method).then((res)=>{
+              if(res.success){
+                that.$message.success(res.message);
+                that.$emit('ok');
+              }else{
+                that.$message.warning(res.message);
+              }
+            }).finally(() => {
+              that.confirmLoading = false;
+              that.close();
+            })
+
+
+
+          }
+        })
+      },
+      handleCancel () {
+        this.close()
+      },
+
+
+    }
+  }
+</script>
+
+<style lang="less" scoped>
+
+</style>

+ 241 - 0
src/views/system/modules/UserShiftListModal.vue

@@ -0,0 +1,241 @@
+<template>
+  <a-drawer
+    :title="title"
+    :maskClosable="true"
+    width=1020
+    placement="right"
+    :closable="true"
+    @close="close"
+    :visible="visible"
+    style="overflow: auto;padding-bottom: 53px;">
+    
+    <div class="table-page-search-wrapper">
+      <a-form layout="inline" @keyup.enter.native="searchQuery">
+        <a-row :gutter="24">
+    
+          <!-- <a-col :md="6" :sm="12">
+            <a-form-item label="账号">
+              <j-input placeholder="输入账号模糊查询" v-model="queryParam.username"></j-input>
+            </a-form-item>
+          </a-col> -->
+    <a-col :md="6" :sm="8">
+      <a-form-item label="真实名字">
+        <a-input placeholder="请输入真实名字" v-model="queryParam.realname"></a-input>
+      </a-form-item>
+    </a-col>
+    
+          <a-col :md="6" :sm="8">
+            <a-form-item label="性别">
+              <a-select v-model="queryParam.sex" placeholder="请选择性别">
+                <a-select-option value="">请选择</a-select-option>
+                <a-select-option value="1">男</a-select-option>
+                <a-select-option value="2">女</a-select-option>
+              </a-select>
+            </a-form-item>
+          </a-col>
+    
+    
+          <!-- <template v-if="toggleSearchStatus"> -->
+            
+    
+            <a-col :md="6" :sm="8">
+              <a-form-item label="手机号码">
+                <a-input placeholder="请输入手机号码查询" v-model="queryParam.phone"></a-input>
+              </a-form-item>
+            </a-col>
+    
+           <!-- <a-col :md="6" :sm="8">
+              <a-form-item label="用户状态">
+                <a-select v-model="queryParam.status" placeholder="请选择">
+                  <a-select-option value="">请选择</a-select-option>
+                  <a-select-option value="1">正常</a-select-option>
+                  <a-select-option value="2">冻结</a-select-option>
+                </a-select>
+              </a-form-item>
+            </a-col> -->
+         <!-- </template> -->
+    
+          <a-col :md="6" :sm="8">
+            <span style="float: left;overflow: hidden;" class="table-page-search-submitButtons">
+              <a-button type="primary" @click="searchQuery" icon="search">查询</a-button>
+              <a-button type="primary" @click="searchReset" icon="reload" style="margin-left: 8px">重置</a-button>
+              
+            </span>
+          </a-col>
+    
+        </a-row>
+      </a-form>
+    </div>
+    
+    <a-table
+      ref="table"
+      size="middle"
+      bordered
+      rowKey="id"
+      :columns="columns"
+      :dataSource="dataSource"
+      :pagination="ipagination"
+      :loading="loading"
+      class="j-table-force-nowrap"
+      :rowSelection="{selectedRowKeys: selectedRowKeys, onChange: onSelectChange}"
+      @change="handleTableChange">
+    <template slot="avatarslot" slot-scope="text, record, index">
+      <div class="anty-img-wrap">
+        <a-avatar shape="square" :src="getAvatarView(record.avatar)" icon="user"/>
+      </div>
+    </template>
+      
+    </a-table>
+    
+
+    <div class="drawer-bootom-button">
+      <a-popconfirm title="确定放弃编辑?" @confirm="close" okText="确定" cancelText="取消">
+        <a-button style="margin-right: .8rem">取消</a-button>
+      </a-popconfirm>
+      <a-button @click="handleSubmit(false)" type="primary" :loading="loading" ghost style="margin-right: 0.8rem">仅保存</a-button>
+      <a-button @click="handleSubmit(true)" type="primary" :loading="loading">保存并关闭</a-button>
+    </div>
+
+    <role-datarule-modal ref="datarule"></role-datarule-modal>
+
+  </a-drawer>
+
+</template>
+<script>
+import '@/assets/less/TableExpand.less'
+import { JeecgListMixin } from '@/mixins/JeecgListMixin'
+import {putAction,getFileAccessHttpUrl} from '@/api/manage';
+import {frozenBatch} from '@/api/api'
+import JInput from '@/components/jeecg/JInput'
+import JSuperQuery from '@/components/jeecg/JSuperQuery'
+  export default {
+    name: "RoleModal",
+    mixins:[JeecgListMixin],
+    components: {
+      JInput,
+      JSuperQuery
+    },
+    data(){
+      return {
+        queryParam: {},
+        recycleBinVisible: false,
+        roleId:"",
+        autoExpandParent: true,
+        checkStrictly: true,
+        title:"员工排班",
+        visible: false,
+        loading: false,
+        selectedKeys:[],
+      columns: [
+        {
+          title: '#',
+          dataIndex: '',
+          key:'rowIndex',
+          width:60,
+          align:"center",
+          customRender:function (t,r,index) {
+            return parseInt(index)+1;
+          }
+        },
+      
+        {
+          title: '用户姓名',
+          align: "center",
+          width: 100,
+          dataIndex: 'realname',
+        },
+        {
+          title: '头像',
+          align: "center",
+          width: 120,
+          dataIndex: 'avatar',
+          scopedSlots: {customRender: "avatarslot"}
+        },
+      
+        {
+          title: '性别',
+          align: "center",
+          width: 80,
+          dataIndex: 'sex_dictText',
+          sorter: true
+        },
+        {
+          title: '手机号码',
+          align: "center",
+          width: 120,
+          dataIndex: 'phone'
+        },
+        {
+          title: '组织',
+          align: "center",
+          width: 120,
+          dataIndex: 'orgText'
+        },
+        {
+          title: '部门',
+          align: "center",
+          width: 120,
+          dataIndex: 'orgCodeTxt'
+        },
+        {
+          title: '入职时间',
+          align: "center",
+          width: 120,
+          dataIndex: 'entryDate'
+        },
+       
+      ],
+      superQueryFieldList: [
+        { type: 'input', value: 'username', text: '用户账号', },
+        { type: 'input', value: 'realname', text: '用户姓名', },
+        { type: 'select', value: 'sex', text: '性别', dictCode: 'sex' },
+      ],
+      url: {
+        list: "/sys/user/list"
+      },
+      }
+    },
+    methods: {
+      importExcelUrl: function(){
+        return `${window._CONFIG['domianURL']}/${this.url.importExcelUrl}`;
+      },
+      getAvatarView: function (avatar) {
+        return getFileAccessHttpUrl(avatar)
+      },
+      
+      
+      show(roleId){
+        this.roleId=roleId
+        this.visible = true;
+      },
+      close () {
+        this.$emit('close');
+        this.visible = false;
+      },
+      
+      handleCancel () {
+        this.close()
+      },
+      handleSubmit(exit) {
+        let that = this;
+        
+      },
+    },
+ 
+  }
+
+</script>
+<style lang="less" scoped>
+  .drawer-bootom-button {
+    position: absolute;
+    bottom: 0;
+    width: 100%;
+    border-top: 1px solid #e8e8e8;
+    padding: 10px 16px;
+    text-align: right;
+    left: 0;
+    background: #fff;
+    border-radius: 0 0 2px 2px;
+  }
+
+</style>

+ 491 - 0
src/views/system/modules/UserShiftModal.vue

@@ -0,0 +1,491 @@
+<template>
+  <j-modal title="排班" :width="1000" :visible="visible" switchFullscreen @cancel="handleCancel" :footer="true">
+
+    <a-spin :spinning="confirmLoading">
+      <div class='month'>
+        <ul>
+          <!--点击会触发pickpre函数,重新刷新当前日期 @click(vue v-on:click缩写) -->
+          <li class='arrow' @click='pickPre(currentYear,currentMonth)'>上个月</li>
+          <li class='year-month'>
+            <span class='choose-year'>{{ currentYear }}年</span>
+            <span class='choose-month'>{{ currentMonth }}月</span>
+          </li>
+          <li class='arrow' @click='pickNext(currentYear,currentMonth)'>下个月</li>
+        </ul>
+        <br>
+      </div>
+      <hr>
+      <div>
+        <a-table bordered :data-source="dataSource" :columns="columns" :scroll="{ y: 440,x:1000 }"
+          :pagination="ipagination" @change="handleTableChange">
+
+          <template v-for='(dayobject,i) in days' :slot="dayobject.day.getDate()" style="color: #ff6b81">
+            <div style="margin-left: 14px;">
+              <p>{{dayobject.day.getDate()}}</p>
+              <div style="margin-left: -1px;">
+                <p v-if='dayobject.day.getDay()==0'>日</p>
+                <p v-else-if='dayobject.day.getDay()==1'>一</p>
+                <p v-else-if='dayobject.day.getDay()==2'>二</p>
+                <p v-else-if='dayobject.day.getDay()==3'>三</p>
+                <p v-else-if='dayobject.day.getDay()==4'>四</p>
+                <p v-else-if='dayobject.day.getDay()==5'>五</p>
+                <p v-else-if='dayobject.day.getDay()==6'>六</p>
+              </div>
+            </div>
+          </template>
+
+        </a-table>
+      </div>
+
+      </a-calendar>
+      <a-modal v-model="visibles" title="班次" @ok="shiftOk()">
+        <div class="table-page-search-wrapper">
+          <a-form layout="inline">
+            <a-row :gutter="24">
+
+              <a-col :xl="10" :lg="10" :md="8" :sm="24">
+                <a-form-item label="班次名称">
+                  <a-select v-model="shiftname" placeholder="请选择班次">
+                    <a-select-option value="">请选择</a-select-option>
+                    <a-select-option v-for="(item,index) in shiftlist" :value="item.id">{{item.name}}</a-select-option>
+                  </a-select>
+                </a-form-item>
+              </a-col>
+
+            </a-row>
+          </a-form>
+        </div>
+      </a-modal>
+
+    </a-spin>
+  </j-modal>
+</template>
+
+<script>
+  import {
+    httpAction,
+    getFileAccessHttpUrl,
+    getAction,
+    deleteAction
+  } from '@/api/manage'
+  import pick from 'lodash.pick'
+  import moment from "moment"
+  import {
+    JeecgListMixin
+  } from '@/mixins/JeecgListMixin'
+  import '@/assets/less/TableExpand.less'
+
+  export default {
+    name: "UserShiftModal",
+    mixins: [JeecgListMixin],
+    data() {
+      return {
+        dataSource: [],
+        columns: [],
+        queryParam: {
+          shiftDate: moment(new Date()).format('YYYY-MM-DD HH:mm:ss')
+        },
+       
+        currentMonth: new Date().getMonth(),
+        currentYear: new Date().getYear(),
+        days: [],
+        visibles: false,
+        shiftDate: null,
+        show: 1,
+        id: null,
+        shiftname: "",
+        username: "",
+        deptlist: null,
+        shiftlist: null,
+        title: "操作",
+        visible: false,
+        key: null,
+        index: null,
+        vs: false,
+        model: {},
+        listData: [],
+        confirmLoading: false,
+        form: this.$form.createForm(this),
+        validatorRules: {},
+        url: {
+          add: "/userShift/userShift/addUserShift",
+          userShift: "/userShift/userShift/queryByUser",
+          shift: "/shift/shift/list",
+          list: "/userShift/userShift/queryMothByUser",
+          moth: "/userShift/userShift/queryMothByUser",
+          deptlist: "/sys/sysDepart/listAll",
+          delUserShift: '/userShift/userShift/delete'
+        },
+      }
+    },
+    created() {
+     // this.getListData(null)
+      this.initData(null)
+      this.queryShift()
+    },
+    methods: {
+      CustomCell(record, index) {
+        return {
+          on: {
+            mouseenter: (event) => {
+              record.setExecutorVisible = true;
+              console.log("悬浮" + record.setExecutorVisible);
+
+            },
+            mouseleave: (event) => {
+
+              record.setExecutorVisible = false;
+              console.log("离开");
+            },
+            click: (event) => {
+
+              this.visibles = true;
+              this.index = index;
+
+            }
+          },
+
+        }
+      },
+      executePersonCustomCell(record, index) {
+        return {
+          on: {
+            mouseenter: (event) => {
+              record.setExecutorVisible = true;
+              console.log("悬浮" + record.setExecutorVisible);
+
+            },
+            mouseleave: (event) => {
+
+              record.setExecutorVisible = false;
+              console.log("离开");
+            },
+            click: (event) => {
+              this.key = event.target.cellIndex;
+              this.shiftDate = this.currentYear + "-" + this.currentMonth + "-" + this.key + " 00:00:000";
+              this.visibles = true;
+              this.index = index;
+            }
+          },
+
+        }
+      },
+
+
+      pickPre: function(year, month) {
+        var d = new Date(this.formatDate(year, month, 1))
+        d.setDate(0)
+        this.initData(this.formatDate(d.getFullYear(), d.getMonth() + 1, 1))
+        this.queryParam.shiftDate=this.formatDate(d.getFullYear(), d.getMonth() + 1, 1) + " 00:00:000";
+        this.$options.methods.searchQuery.call(this)
+      },
+
+      pickNext: function(year, month) {
+        var d = new Date(this.formatDate(year, month + 1, 1))
+        this.initData(this.formatDate(d.getFullYear(), d.getMonth() + 1, 1))
+    this.queryParam.shiftDate=this.formatDate(d.getFullYear(), d.getMonth() + 1, 1) + " 00:00:000";
+     this.$options.methods.searchQuery.call(this)
+      },
+
+      initData: function(cur) {
+        this.columns = [];
+        var date
+        if (cur) {
+          date = new Date(cur)
+        } else {
+          var now = new Date()
+          var d = new Date(this.formatDate(now.getFullYear(), now.getMonth(), 1))
+          d.setDate(35)
+          date = new Date(this.formatDate(d.getFullYear(), d.getMonth() + 1, 1))
+        }
+        this.currentDay = date.getDate()
+        this.currentYear = date.getFullYear()
+        this.currentMonth = date.getMonth() + 1
+        this.currentWeek = date.getDay() // 1...6,0
+
+        var str = this.formatDate(
+          this.currentYear,
+          this.currentMonth,
+          this.currentDay
+        )
+        this.days.length = 0
+        var moth = new Date(str);
+        moth.setDate(28)
+
+        moth.setMonth(moth.getMonth() + 1);
+        moth.setDate(0);
+        this.columns.push({
+          title: '名称',
+          dataIndex: 'realname',
+          width: '120px'
+        })
+        for (var i = 1; i <= moth.getDate(); i++) {
+          var d = new Date(this.formatDate(this.currentYear, this.currentMonth, i))
+          var dayobjectSelf = {
+            width: '70px',
+            slots: {
+              title: d.getDate()
+            },
+            dataIndex: "a" + d.getDate(),
+            customCell: this.executePersonCustomCell
+          } // 用一个对象包装Date对象  以便为以后预定功能添加属性
+          var dat = {};
+          dat.day = d;
+          this.days.push(dat)
+          this.columns.push(dayobjectSelf) // 将日期放入data 中的days数组 供页面渲染使用
+        }
+      },
+
+      // 返回 类似 2016-01-02 格式的字符串
+      formatDate: function(year, month, day) {
+        var y = year
+        if (month > 12) {
+          y = y + 1;
+          month = 1;
+        };
+        var m = month
+        if (m < 10) m = '0' + m
+        var d = day
+        if (d < 10) d = '0' + d
+        return y + '-' + m + '-' + d
+      },
+
+      delUserShift(e) {
+        this.vs = true;
+        console.log(e)
+        deleteAction(this.url.delUserShift, {
+          id: e
+        }).then((res) => {
+          if (res.success) {
+            this.$message.success(res.message);
+
+          } else {
+            this.$message.warning(res.message);
+          }
+        }).finally(() => {
+          this.vs = false;
+          this.getListData(moment(this.queryParam.entryDate).format('YYYY-MM-DD HH:mm:ss'));
+        })
+      },
+     
+
+      shiftOk() {
+        if (this.shiftname == null || this.shiftname == "") {
+          this.$message.warning("请选择班次!");
+          return;
+        }
+
+        for (var i = 0; i < this.shiftlist.length; i++) {
+          if (this.shiftname == this.shiftlist[i].id) {
+            httpAction(this.url.add, {
+              userId: this.dataSource[this.index].id,
+              shiftId: this.shiftname,
+              shiftDate: this.shiftDate
+            }, "post").then((res) => {
+              if (res.success) {
+
+              }
+            })
+            if (this.key == 1) {
+              this.dataSource[this.index].a1 = this.shiftlist[i].name;
+            } else if (this.key == 2) {
+              this.dataSource[this.index].a2 = this.shiftlist[i].name;
+            } else if (this.key == 3) {
+              this.dataSource[this.index].a3 = this.shiftlist[i].name;
+            } else if (this.key == 4) {
+              this.dataSource[this.index].a4 = this.shiftlist[i].name;
+            } else if (this.key == 5) {
+              this.dataSource[this.index].a5 = this.shiftlist[i].name;
+            } else if (this.key == 6) {
+              this.dataSource[this.index].a6 = this.shiftlist[i].name;
+            } else if (this.key == 7) {
+              this.dataSource[this.index].a7 = this.shiftlist[i].name;
+            } else if (this.key == 8) {
+              this.dataSource[this.index].a8 = this.shiftlist[i].name;
+            } else if (this.key == 9) {
+              this.dataSource[this.index].a9 = this.shiftlist[i].name;
+            } else if (this.key == 10) {
+              this.dataSource[this.index].a10 = this.shiftlist[i].name;
+            } else if (this.key == 11) {
+              this.dataSource[this.index].a11 = this.shiftlist[i].name;
+            } else if (this.key == 12) {
+              this.dataSource[this.index].a12 = this.shiftlist[i].name;
+            } else if (this.key == 13) {
+              this.dataSource[this.index].a13 = this.shiftlist[i].name;
+            } else if (this.key == 14) {
+              this.dataSource[this.index].a14 = this.shiftlist[i].name;
+            } else if (this.key == 15) {
+              this.dataSource[this.index].a15 = this.shiftlist[i].name;
+            } else if (this.key == 16) {
+              this.dataSource[this.index].a16 = this.shiftlist[i].name;
+            } else if (this.key == 17) {
+              this.dataSource[this.index].a17 = this.shiftlist[i].name;
+            } else if (this.key == 18) {
+              this.dataSource[this.index].a18 = this.shiftlist[i].name;
+            } else if (this.key == 19) {
+              this.dataSource[this.index].a19 = this.shiftlist[i].name;
+            } else if (this.key == 20) {
+              this.dataSource[this.index].a20 = this.shiftlist[i].name;
+            } else if (this.key == 21) {
+              this.dataSource[this.index].a21 = this.shiftlist[i].name;
+            } else if (this.key == 22) {
+              this.dataSource[this.index].a22 = this.shiftlist[i].name;
+            } else if (this.key == 23) {
+              this.dataSource[this.index].a23 = this.shiftlist[i].name;
+            } else if (this.key == 24) {
+              this.dataSource[this.index].a24 = this.shiftlist[i].name;
+            } else if (this.key == 25) {
+              this.dataSource[this.index].a25 = this.shiftlist[i].name;
+            } else if (this.key == 26) {
+              this.dataSource[this.index].a26 = this.shiftlist[i].name;
+            } else if (this.key == 27) {
+              this.dataSource[this.index].a27 = this.shiftlist[i].name;
+            } else if (this.key == 28) {
+              this.dataSource[this.index].a28 = this.shiftlist[i].name;
+            } else if (this.key == 29) {
+              this.dataSource[this.index].a29 = this.shiftlist[i].name;
+            } else if (this.key == 30) {
+              this.dataSource[this.index].a30 = this.shiftlist[i].name;
+            } else if (this.key == 31) {
+              this.dataSource[this.index].a31 = this.shiftlist[i].name;
+            }
+
+            this.dataSource[this.index].shfitid = this.shiftlist[i].id;
+          }
+        }
+
+        this.visibles = false;
+      },
+     
+      close() {
+        this.selectedRowKeys = [];
+        this.queryParam = {};
+        this.shiftname = "";
+        this.id = null;
+        this.$emit('close');
+        this.visible = false;
+      },
+      queryShift() {
+        httpAction(this.url.shift, "", "get").then((res) => {
+          if (res.success) {
+            this.shiftlist = res.result.records;
+          }
+        }).finally(() => {
+
+        })
+
+      },
+
+      handleCancel() {
+        this.close()
+      },
+
+
+    }
+  }
+</script>
+
+<style lang="less" scoped>
+  .month {
+    width: 100%;
+    color: #333333;
+    background: #ffffff;
+  }
+
+  .month ul {
+    margin: 0;
+    padding: 0;
+    display: flex;
+    justify-content: space-between;
+    height: 35px;
+    list-style-type: none;
+  }
+
+  .year-month {
+    display: flex;
+    align-items: center;
+    justify-content: space-around;
+    margin-top: 10px;
+  }
+
+  .choose-month {
+    text-align: center;
+    font-size: 12px;
+  }
+
+  .arrow {
+    padding: 15px;
+    color: #999999;
+  }
+
+  .month ul li {
+    font-size: 12px;
+    text-transform: uppercase;
+    letter-spacing: 3px;
+  }
+
+
+  .weekdays {
+    margin: 0;
+    padding: 10px;
+    display: flex;
+    flex-wrap: wrap;
+    color: #999;
+    justify-content: space-around;
+    background: #ffffff;
+  }
+
+  .weekdays li {
+    display: inline-block;
+    width: 13.6%;
+    text-align: center;
+  }
+
+  .days {
+    padding: 10px;
+    background: #ffffff;
+    margin: 0;
+    display: flex;
+    flex-wrap: wrap;
+  }
+
+  .ts {
+    padding: 20px;
+    background: #ffffff;
+    margin: 0;
+    display: flex;
+    flex-wrap: wrap;
+  }
+
+  .days li {
+    list-style-type: none;
+    display: inline-block;
+    width: 14.2%;
+    text-align: center;
+    padding-bottom: 4px;
+    padding-top: 5px;
+    font-size: 13px;
+    color: #000;
+    height: 40px;
+  }
+
+  .days li .active {
+    padding: 8px 10px;
+    border-radius: 5%;
+    background: #00b8ec;
+    color: #fff;
+
+  }
+
+  .days li .other-month {
+    padding: 5px;
+    color: gainsboro;
+  }
+
+  .days li:hover .act {
+    padding: 6px 10px;
+    border-radius: 50%;
+    background: #e1e1e1;
+    color: #fff;
+  }
+</style>

+ 52 - 25
src/views/system/synchronization.vue

@@ -37,10 +37,10 @@
     <!-- 操作按钮区域 -->
      <div class="table-operator" style="border-top: 5px">
       <a-button @click="pulldata()" type="primary" icon="plus" >拉取</a-button>
-      <a-button @click="pulldata()" type="primary" icon="plus" >同步U8</a-button>
-      <a-button @click="synchronizationWeixin()" type="primary" icon="plus" >同步企业微信</a-button>
+      <a-button @click="Udate()" type="primary" icon="plus" >U8</a-button>
+      <a-button @click="synchronizationWeixin()" type="primary" icon="plus" >企业微信</a-button>
       <a-dropdown   :visible="show">
-        <a-button @click="synchronizationPt()" type="primary" icon="plus" >同步中间平台</a-button>
+        <a-button @click="synchronizationPt()" type="primary" icon="plus" >平台</a-button>
         <a-menu slot="overlay">
           <a-menu-item >
           <a-month-picker placeholder="请选择日期"  v-model="date"/>
@@ -127,7 +127,7 @@
   import PasswordModal from './modules/PasswordModal'
   import {putAction,getFileAccessHttpUrl} from '@/api/manage';
   import {frozenBatch} from '@/api/api'
-  import {pullData,synchronizationWeixin,tbquery,synchronizationPt} from '@/api/api'
+  import {pullData,synchronizationWeixin,tbquery,synchronizationPt,U8} from '@/api/api'
   import {JeecgListMixin} from '@/mixins/JeecgListMixin'
   import JInput from '@/components/jeecg/JInput'
   import UserRecycleBinModal from './modules/UserRecycleBinModal'
@@ -263,6 +263,27 @@
      this.querylist();
    },
     methods: {
+      Udate(){
+        if(this.selectedRowKeys.length<1){
+          this.$message.warning('请选择需要同步的数据!');
+          return false;
+        }if(this.selectedRowKeys[0]!=1&&this.selectedRowKeys[0]!=3&&this.selectedRowKeys[0]!=5){
+         this.$message.warning('该数据不能同步U8或拉取U8数据!');
+         return false;
+       }
+       this.spinning=true;
+       U8({dataType:this.selectedRowKeys[0]}).then(res=>{
+         console.log(res);
+         if(res.msg=="ok"){
+           this.$message.success('同步成功!');
+         }else{
+           this.$message.warning(res.msg);
+         }
+          this.querylist();
+          this.spinning=false;
+        }) 
+       
+      },
       querylist:function(){
         tbquery({}).then(res=>{
           this.data=res;
@@ -274,21 +295,25 @@
          this.$message.warning('请选择需要同步的数据!');
          return false;
        }
-       if(this.selectedRowKeys[0]==1){
-         this.$message.warning('该数据不能同步到平台!');
-         return false;
-       }
-       this.show=true;
-       if(this.date==null){
-         this.$message.warning('请选择需要同步的日期!');
-         return false; 
-       }
+       // if(this.selectedRowKeys[0]==1){
+       //   this.$message.warning('该数据不能同步到平台!');
+       //   return false;
+       // }
+       // this.show=true;
+       // if(this.date==null){
+       //   this.$message.warning('请选择需要同步的日期!');
+       //   return false; 
+       // }
        
-        this.spinning=true;
-       var datetime=this.formats(this.date);
-       synchronizationPt({date:datetime,id:this.selectedRowKeys[0],type:0,typeGo:2}).then(res=>{
+         this.spinning=true;
+       // var datetime=this.formats(this.date);
+       synchronizationPt({dataType:this.selectedRowKeys[0]}).then(res=>{
          console.log(res);
-          this.$message.warning('同步成功'+res.count+'条,同步失败'+res.errCount+'条');
+         if(res.msg=="ok"){
+           this.$message.success('同步成功!');
+         }else{
+           this.$message.warning(res.msg);
+         }
           this.querylist();
           this.spinning=false;
         }) 
@@ -321,7 +346,11 @@
         }
        this.spinning=true;
         synchronizationWeixin({id:this.selectedRowKeys[0],type:0,typeGo:0}).then(res=>{
-           this.$message.warning(res.msg);
+           if(res.msg=="ok"){
+             this.$message.success('同步成功!');
+           }else{
+             this.$message.warning(res.msg);
+           }
            this.querylist();
            this.spinning=false;
          }) 
@@ -329,13 +358,11 @@
       pulldata:function(){
           this.spinning=true;
       pullData({}).then(res=>{
-        if(res.errCode=="0"){
-          this.$message.success('拉取数据成功'
-          +res.userCount+"条,拉取数据失败"+res.userErrCount+"条");
-          
-        }else{
-          this.$message.warning("拉取数据失败");
-        }
+       if(res.msg=="ok"){
+         this.$message.success('拉取数据成功!');
+       }else{
+         this.$message.warning(res.msg);
+       }
          this.spinning=false;
         
        })