廖井涛
5 天以前 79b057e22e97e7db70faf25b33a5977b06771810
打印加工单修改,新增用户登录日志
15个文件已修改
2个文件已添加
589 ■■■■■ 已修改文件
north-glass-erp/northglass-erp/src/components/sd/order/PrintSheet4.vue 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
north-glass-erp/northglass-erp/src/lang/ar.js 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
north-glass-erp/northglass-erp/src/lang/en.js 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
north-glass-erp/northglass-erp/src/lang/kr.js 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
north-glass-erp/northglass-erp/src/lang/ru.js 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
north-glass-erp/northglass-erp/src/lang/zh.js 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
north-glass-erp/northglass-erp/src/router/index.js 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
north-glass-erp/northglass-erp/src/views/sd/delivery/CreateDelivery.vue 118 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
north-glass-erp/northglass-erp/src/views/sd/delivery/SelectOrderList.vue 103 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
north-glass-erp/northglass-erp/src/views/system/userLog/UserListLog.vue 235 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
north-glass-erp/northglass-erp/src/views/system/userLog/UserLog.vue 61 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
north-glass-erp/src/main/java/com/example/erp/controller/userInfo/UserController.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
north-glass-erp/src/main/java/com/example/erp/entity/sd/Order.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
north-glass-erp/src/main/java/com/example/erp/mapper/userInfo/UserMapper.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
north-glass-erp/src/main/java/com/example/erp/service/userInfo/UserService.java 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
north-glass-erp/src/main/resources/mapper/sd/DeliveryDetailMapper.xml 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
north-glass-erp/src/main/resources/mapper/userInfo/User.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
north-glass-erp/northglass-erp/src/components/sd/order/PrintSheet4.vue
@@ -156,9 +156,9 @@
      </tr>
      <tr class="title-s">
        <th colspan="2" style="width: 30%;text-align: left;"><span>{{data.order.orderType}}&nbsp;总重量:{{ grossNum.weight }}</span></th>
        <th colspan="2" style="width: 30%;text-align: left;"><span>总重量:{{ grossNum.weight }}</span></th>
        <th colspan="5" style="width: 40%;">
          <h3 >生产任务单(成品)</h3>
          <h3 >生产任务单({{data.order.orderType}})</h3>
        </th>
        <th colspan="2" style="width: 30%;">订单编号:<span>{{ data.order.orderId }}</span>
          <span v-if="company.companyName==='常州市吉利玻璃有限公司'&& data.order.batch!==''">(原{{ data.order.batch }})</span>
north-glass-erp/northglass-erp/src/lang/ar.js
@@ -1333,7 +1333,8 @@
        userPassWord :'تغيير كلمة المرور',
        glassPrice:'玻璃价格',
        glassOptimize:'玻璃优化',
        finishedGlassShelf:'成品料架'
        finishedGlassShelf:'成品料架',
        userLog:'登录日志'
    },
    glassPrice:{
north-glass-erp/northglass-erp/src/lang/en.js
@@ -1333,7 +1333,8 @@
        userPassWord :'User Pass Word',
        glassPrice:'Glass Price',
        glassOptimize:'玻璃优化',
        finishedGlassShelf:'成品料架'
        finishedGlassShelf:'成品料架',
        userLog:'登录日志'
    },
    glassPrice:{
north-glass-erp/northglass-erp/src/lang/kr.js
@@ -1334,7 +1334,8 @@
        userPassWord :'비밀번호 변경',
        glassPrice:'유리 가격',
        glassOptimize:'유리 최적화',
        finishedGlassShelf:'成品料架'
        finishedGlassShelf:'成品料架',
        userLog:'登录日志'
    },
    glassPrice:{
north-glass-erp/northglass-erp/src/lang/ru.js
@@ -1334,7 +1334,8 @@
        userPassWord :'Изменить пароль',
        glassPrice:'Цена стекла.',
        glassOptimize:'玻璃优化',
        finishedGlassShelf:'成品料架'
        finishedGlassShelf:'成品料架',
        userLog:'登录日志'
    },
    glassPrice:{
north-glass-erp/northglass-erp/src/lang/zh.js
@@ -1335,7 +1335,8 @@
        userPassWord :'修改密码',
        glassPrice:'玻璃价格',
        glassOptimize:'玻璃优化',
        finishedGlassShelf:'成品料架'
        finishedGlassShelf:'成品料架',
        userLog:'登录日志'
    },
    glassPrice:{
north-glass-erp/northglass-erp/src/router/index.js
@@ -83,6 +83,23 @@
            }
          ]
        },
        {
          path:'userLog',
          name: 'userLog',
          component: () => import('../views/system/userLog/UserLog.vue'),
          children:[
            {
              path: 'userListLog',
              name: 'userListLog',
              component: () => import('../views/system/userLog/UserListLog.vue'),
            },
            {
              name:'userLog',
              path: '',
              redirect:'/main/userLog/userListLog'
            }
          ]
        },
        {
          path:'glassPrice',
north-glass-erp/northglass-erp/src/views/sd/delivery/CreateDelivery.vue
@@ -19,6 +19,8 @@
import {multiply} from "@/utils/decimal";
import MaterialAddition from "@/views/mm/ingredientStock/MaterialAddition.vue";
import {copyTableCellValue} from "@/hook/copyTableCellValue";
import SelectOrderList from "@/views/sd/delivery/SelectOrderList.vue";
import { ElDialog } from "element-plus";
//语言获取
const { t } = useI18n()
@@ -35,6 +37,19 @@
let otherMoneyVisible = ref(false)
let otherMoney = ref(null)
const dialogSelectOrderVisible = ref(false); // 控制弹窗显示
const currentOrderIds = ref([]); // 已有的订单ID,用于排除
// 初始化已选订单ID(在onMounted中调用)
const initCurrentOrderIds = () => {
  if (produceList && produceList.length > 0) {
    const orderIds = produceList.map(item => item.orderId);
    currentOrderIds.value = [...new Set(orderIds)];
  }else {
    currentOrderIds.value = [];
  }
};
const hasDecimal=(value)=>{
  const regex=/\./ // 定义正则表达式,查找小数点
@@ -209,6 +224,7 @@
        //禁用按钮
        gridOptions.toolbarConfig.buttons[2].disabled  = true
        gridOptions.toolbarConfig.buttons[3].disabled = true
        //gridOptions.toolbarConfig.buttons[4].disabled = false
        //显示复选框
        xGrid.value.showColumn("select")
        gridOptions.loading=false
@@ -245,6 +261,7 @@
        if(titleUploadData.value.deliveryState!==0){
          gridOptions.toolbarConfig.buttons[2].disabled = true
          gridOptions.toolbarConfig.buttons[1].disabled = true
          //gridOptions.toolbarConfig.buttons[4].disabled = true
        }
        if(titleUploadData.value.deliveryState===0){
          gridOptions.toolbarConfig.buttons[3].disabled = true
@@ -370,6 +387,7 @@
      {'code': 'addToExamine', 'name': t('reportingWorks.saveAndReview'),status: 'primary',icon: 'vxe-icon-save'},
      {'code': 'toExamine', 'name': t('basicData.review'),status: 'primary'},
      {'code': 'CounterExamination', 'name': t('basicData.cancelReview'),status: 'primary'},
      //{'code': 'addOtherOrders','name': t('订单添加'),'status': 'primary'}
      //{'code': 'glassShelf', 'name': t('finishedGlassShelf.finishedGlassShelfEmit'),status: 'primary'}
    ],
    /*import: false,
@@ -616,6 +634,13 @@
          })
          break
        }
        case 'addOtherOrders': {
          // 显示弹窗前更新已选订单ID
          initCurrentOrderIds();
          // 显示弹窗
          dialogSelectOrderVisible.value = true;
          break;
        }
      }
    }
  },
@@ -826,7 +851,83 @@
};
// 处理从SelectOrderList选中的订单
const handleSelectedOrders = async (selectedOrders) => {
  if (!selectedOrders || selectedOrders.length === 0) return;
  // 关闭弹窗
  dialogSelectOrderVisible.value = false;
  // 验证选中的订单是否符合条件
  const { customerId, project } = titleUploadData.value;
  const invalidOrders = selectedOrders.filter(order =>
      order.customerId !== parseInt(customerId) || order.project !== project
  );
  if (invalidOrders.length > 0) {
    ElMessage.warning(t('delivery.onlySameCustomerProject'));
    return;
  }
  try {
    // 显示加载状态
    gridOptions.loading = true;
    // 批量查询订单明细(按订单ID)
    const orderIds = selectedOrders.map(order => order.orderId).join('|');
    filterData.value.orderId=orderIds
    request.post("/delivery/getSelectShippingOrderDetails/1/100",filterData.value).then((res) => {
      if (res.code == 200) {
        // 处理返回的明细数据
        const orderDetails = res.data.data || [];
        //合并数据
        mergeData(orderDetails);
      } else {
        ElMessage.warning(res.msg || t('basicData.msg.data获取失败'));
      }
    })
  } catch (error) {
    ElMessage.error(t('basicData.msg.ServerConnectionError'));
    console.error('查询订单明细失败:', error);
  } finally {
    // 关闭加载状态
    gridOptions.loading = false;
  }
};
// 合并数据:判断orderId、orderNumber、boxNo是否相同,相同则累加数量,不同则新增
const mergeData = (newDataList) => {
  // 复制现有数据(避免直接修改响应式源数据)
  const currentList = [...produceList];
  newDataList.forEach(newItem => {
    // 提取新数据的关键比对字段
    const newOrderId = newItem.orderId;
    const newOrderNumber = newItem.orderNumber;
    const newBoxNo = newItem.finishedGoodsInventory?.boxNo || ''; // 处理可能的undefined
    // 在现有数据中查找匹配项(三个字段完全相同)
    const matchedItem = currentList.find(item =>
        item.orderId === newOrderId &&
        item.orderNumber === newOrderNumber &&
        (item.finishedGoodsInventory?.boxNo || '') === newBoxNo
    );
    if (matchedItem) {
      // 找到匹配项:累加数量(确保是数值类型)
      matchedItem.deliveryDetail.quantity = (Number(matchedItem.deliveryDetail.quantity) || 0) +
          (Number(newItem.deliveryDetail.quantity) || 0);
    } else {
      // 未找到匹配项:新增一条数据
      currentList.push(newItem);
    }
  });
  // 更新响应式数据
  produceList = currentList;
  // 刷新表格
  xGrid.value.reloadData(produceList);
};
</script>
@@ -997,6 +1098,23 @@
          @handle-result="handleChildResult2"
      />
    </el-dialog>
    <el-dialog
        v-model="dialogSelectOrderVisible"
        :title="t('订单添加')"
        style="width: 70%;height:75% "
        destroy-on-close
        :close-on-click-modal="false"
        :close-on-press-escape="false">
    >
      <SelectOrderList
          style="width: 100%;height: 600px"
          :customer-id="titleUploadData.customerId"
          :project="titleUploadData.project"
          :exclude-order-ids="currentOrderIds"
          @select-orders="handleSelectedOrders"
      />
    </el-dialog>
  </div>
</template>
north-glass-erp/northglass-erp/src/views/sd/delivery/SelectOrderList.vue
@@ -1,7 +1,7 @@
<script setup>
import {Search} from "@element-plus/icons-vue"
import {useRouter} from "vue-router"
import {reactive, ref} from "vue";
import {onMounted, reactive, ref} from "vue";
import request from "@/utils/request"
import deepClone from "@/utils/deepClone"
import VXETable from "vxe-table";
@@ -18,6 +18,15 @@
const username = userStore.user.userName
const userid = userStore.user.userId
let produceList = ref([])
const props = defineProps({
  customerId: null,
  project: null,
  excludeOrderIds: null
})
const emit = defineEmits(['selectOrders'])
const getTableRow = (row,type) =>{
  switch (type) {
@@ -56,6 +65,9 @@
    quantityAvailable:'',
  },
  customerId: null,  // 新增
  project: null,     // 新增
  excludeOrderIds: []  // 新增
})
let selectDate = ref(["",""])
@@ -68,23 +80,38 @@
})
//第一次调用
request.post(`/delivery/getSelectOrderInventory/1/${total.pageSize}/${orderInfo.selectOrderListDate}`,filterData.value).then((res) => {
  if(res.code==200){
    total.dataTotal = res.data.total.total*1
    total.pageTotal= res.data.total.pageTotal
    orderInfo.selectOrderListDate = res.data.selectDate
    pageNum.value=1
    produceList = deepClone(res.data.data)
    xGrid.value.loadData(produceList)
    gridOptions.loading=false
// 第一次调用,修改为带筛选条件
const fetchOrders = () => {
  // 新增:从props获取筛选条件
  if(props.customerId!==undefined){
    filterData.value.customerId = props.customerId
    filterData.value.project = props.project
    filterData.value.excludeOrderIds = props.excludeOrderIds
    gridOptions.toolbarConfig.buttons[0].visible  = false
  }else{
    ElMessage.warning(res.msg)
    router.push("/login")
    gridOptions.toolbarConfig.buttons[1].visible  = false
  }
})
  request.post(`/delivery/getSelectOrderInventory/${pageNum.value}/${total.pageSize}/${orderInfo.selectOrderListDate}`, filterData.value).then((res) => {
    if(res.code==200){
      total.dataTotal = res.data.total.total*1
      total.pageTotal= res.data.total.pageTotal
      orderInfo.selectOrderListDate = res.data.selectDate
      produceList = deepClone(res.data.data)
      xGrid.value.loadData(produceList)
      gridOptions.loading=false
    }else{
      ElMessage.warning(res.msg)
      router.push("/login")
    }
  })
}
onMounted(() => {
  fetchOrders()
})
const changeFilterEvent = (event, option, $panel,) => {
  // 手动触发筛选
@@ -104,6 +131,16 @@
  }else{
    filterData.value[column.property] = value
  }
  if(props.customerId!==undefined){
    filterData.value.customerId = props.customerId
    filterData.value.project = props.project
    filterData.value.excludeOrderIds = props.excludeOrderIds
    gridOptions.toolbarConfig.buttons[0].visible  = false
  }else{
    gridOptions.toolbarConfig.buttons[1].visible  = false
  }
  request.post(`/delivery/getSelectOrderInventory/1/${total.pageSize}/${orderInfo.selectOrderListDate}`,filterData.value).then((res) => {
    if(res.code==200){
@@ -142,7 +179,7 @@
const changeDate =  ()=>{
  pageNum.value=1
  selectOrderList()
  fetchOrders()
}
//页脚跳转
@@ -150,7 +187,7 @@
  total.pageTotal = pageSize
  pageNum.value=currentPage
  selectOrderList()
  fetchOrders()
}
@@ -215,7 +252,8 @@
  ],//表头按钮
  toolbarConfig: {
    buttons: [
      {'code': 'add', 'name': t('delivery.delivery'),status: 'primary',icon: 'vxe-icon-add'}
      {'code': 'add', 'name': t('delivery.delivery'),status: 'primary',icon: 'vxe-icon-add'},
      {'code': 'update', 'name': t('delivery.delivery'),status: 'primary',icon: 'vxe-icon-add'}
    ],
    /*import: false,
   export: true,
@@ -282,6 +320,37 @@
          router.push({path: '/main/delivery/createDelivery', query: { orderId: order_id }})
          break
        }
        case 'update': {
          const selectRecords = $grid.getCheckboxRecords()
          if (selectRecords.length === 0) {
            ElMessage.warning(t('productStock.unselectedData'))
            return
          }
          // 验证所选订单是否符合条件(虽然已筛选,但二次验证更安全)
          const customerIdArray = selectRecords.map(item => item.customerId)
          const projectArray = selectRecords.map(item => item.project?.trim() || '')
          if(!isAllEqual(customerIdArray)){
            ElMessage.warning(t('delivery.pleaseSelectTheSameCustomerOrder'))
            return
          }
          if(!isAllEqual(projectArray)){
            ElMessage.warning(t('delivery.pleaseSelectTheSameCustomerProject'))
            return
          }
          const simpleOrders = selectRecords.map(order => ({
            orderId: order.orderId,
            customerId: order.customerId,
            project: order.project,
            // 可补充其他需要的主订单字段
          }));
          // 通过事件返回给父组件
          emit('select-orders', simpleOrders);
          break
        }
      }
    }
  }
north-glass-erp/northglass-erp/src/views/system/userLog/UserListLog.vue
New file
@@ -0,0 +1,235 @@
<script setup>
import {onBeforeMount, onMounted, reactive, ref} from "vue"
import {changeFilterEvent,filterChanged} from "@/hook"
import request from "@/utils/request"
import {useRouter,useRoute} from "vue-router"
import {useI18n} from "vue-i18n"
import {ElMessage, ElMessageBox} from "element-plus"
import deepClone from "@/utils/deepClone";
const { t } = useI18n()
const router = useRouter()
const route = useRoute()
const dialogVisible = ref(false)
const dialogVisibleProcess = ref(false)
let roleList = ref([])
//工序
const processValue = ref()
let userRole= ref({
  userId:'',
  roles:[]
})
let processRow = ref({
  process: null,
  userId:null
})
let produceList = ref([])
const xGrid = ref()
const gridOptions = reactive({
  border:  "full",//表格加边框
  keepSource: true,//保持源数据
  align: 'center',//文字居中
  stripe:true,//斑马纹
  rowConfig: {isCurrent: true, isHover: true,height: 30},//鼠标移动或选择高亮
  id: 'userList',
  showFooter: false,//显示脚
  printConfig: {},
  importConfig: {},
  exportConfig: {},
  scrollY:{ enabled: true },//开启虚拟滚动
  showOverflow:true,
  columnConfig: {
    resizable: true,
    useKey: true
  },
  filterConfig: {   //筛选配置项
  },
  customConfig: {
    storage: true
  },
  editConfig: {
    trigger: 'click',
    mode: 'row',
    showStatus: true
  },
  //表头参数
  columns:[
    {type: 'seq', title: t('basicData.Number'), width: 80 ,fixed:"left"},
    {field: 'operator_id',width:120,  title: t('登录名'), sortable: true, filters:[{ data: '' }],slots: { filter: 'num1_filter' },filterMethod:filterChanged},
    {field: 'operator',width:120,  title: t('用户名'), sortable: true, filters:[{ data: '' }],slots: { filter: 'num1_filter' },filterMethod:filterChanged},
    {field: 'format_create_time',width:160,  title: t('登录时间'),sortable: true},
  ],
  //表头按钮
  toolbarConfig: {
    buttons: [
    ],
    zoom: true,
    custom: true
  },
})
onMounted(()=>{
  request.post('/user/getUserLog').then(res=>{
    if(res.code==200){
      produceList = deepClone(res.data.data)
      xGrid.value.loadData(produceList)
      gridOptions.loading=false
    }else{
      ElMessage.warning(res.msg)
      router.push("/login")
    }
  })
})
const getTableRow =  (row,type) => {
  switch (type) {
    case 'edit': {
      userRole.value.roles = []
      dialogVisible.value = true
      row.userRoleList.forEach(item=>{
        userRole.value.roles.push(item.roleId)
      })
      userRole.value.userId = row.id
      break
    }
    case 'delete': {
      request.post(`/userInfo/userDelete/${row.id}`).then((res) => {
        if(res.code==200 && res.data ===true){
          ElMessage.success(t('searchOrder.msgDeleteSuccess'))
          router.push({path:'/main/user/userList',query:{random:Math.random()}})
        }else{
          ElMessage.warning(t('searchOrder.msgDeleteFail'))
        }
      })
      break
    }
    case 'editProcess': {
      dialogVisibleProcess.value = true
      processRow.value.userId = row.id
      break
    }
  }
}
const handleClose = (done) => {
  userRole.value.roles = []
  done()
}
</script>
<template>
  <div  style="width: 100%;height: 100%">
    <div class="main-table">
      <vxe-grid
          height="100%"
          class="mytable-scrollbar"
          ref="xGrid"
          v-bind="gridOptions"
      >
        <template #filter="{ column, $panel }">
          <div>
            <div v-for="(option, index) in column.filters" :key="index">
              <input
                  type="type"
                  v-model="option.data"
                  @keyup.enter.native="$panel.confirmFilter()"
                  @input="changeFilterEvent($event, option, $panel)"/>
            </div>
          </div>
        </template>
        <template #button_slot="{ row }">
          <el-button @click="getTableRow(row,'edit')" link type="primary" size="small">{{ $t('user.setUpRoles') }}</el-button>
          <el-button @click="getTableRow(row,'editProcess')" link type="primary" size="small">{{ $t('user.setProcess') }}</el-button>
          <el-popconfirm @confirm="getTableRow(row,'delete')" :title="$t('searchOrder.deleteConfirm')">
            <template #reference>
              <el-button  link type="primary" size="small">{{ $t('basicData.delete') }}</el-button>
            </template>
          </el-popconfirm>
        </template>
        <template #num1_filter="{ column, $panel }">
          <div>
            <div v-for="(option, index) in column.filters" :key="index">
              <input type="type" v-model="option.data" @keyup.enter.native="$panel.confirmFilter()" @input="changeFilterEvent($event, option, $panel)"/>
            </div>
          </div>
        </template>
      </vxe-grid>
    </div>
    <el-dialog
        v-model="dialogVisible"
        :title="$t('user.roleSelection')"
        width="30%"
        :before-close="handleClose"
    >
      <span>
        <el-radio v-for="(item) in roleList"
                     :label="item.id"
                     v-model="userRole.roles" >
          {{item.role}}
        </el-radio>
      </span>
      <template #footer>
      <span class="dialog-footer">
        <el-button @click="dialogVisible = false">{{ $t('basicData.cancelButtonText') }}</el-button>
        <el-button type="primary" @click="roleUpdate">
          {{ $t('basicData.confirmButtonText') }}
        </el-button>
      </span>
      </template>
    </el-dialog>
    <el-dialog
        v-model="dialogVisibleProcess"
        :title="$t('user.roleSelection')"
        width="30%"
        :before-close="handleClose"
    >
      <el-select v-model="processValue" clearable :placeholder="$t('reportingWorks.selectProcess')" default-value="default_city" style="width: 120px">
        <el-option
            v-for="item in processRow['process']"
            :key="item.id"
            :label="item.basic_name"
            :value="item.basic_name"
        />
      </el-select>
      <template #footer>
      <span class="dialog-footer">
        <el-button @click="dialogVisibleProcess = false">{{ $t('basicData.cancelButtonText') }}</el-button>
        <el-button type="primary" @click="updateProcess">
          {{ $t('basicData.confirmButtonText') }}
        </el-button>
      </span>
      </template>
    </el-dialog>
  </div>
</template>
<style scoped>
.dialog-footer button:first-child {
  margin-right: 10px;
}
.head{
  width: 100%;
  height: 35px;
}
.main-table{
  width: 100%;
  height: calc(100% - 0px);
}
</style>
north-glass-erp/northglass-erp/src/views/system/userLog/UserLog.vue
New file
@@ -0,0 +1,61 @@
<script setup>
import {ArrowLeftBold, ArrowRight, Search} from "@element-plus/icons-vue"
import {useRouter,useRoute,onBeforeRouteUpdate} from "vue-router"
import {useI18n} from "vue-i18n"
const { t } = useI18n()
const router = useRouter()
const route = useRoute()
let indexFlag=$ref(1)
function changeRouter(index){
  indexFlag=index
}
</script>
<template>
  <div id="main-div">
    <div id="div-title">
      <el-breadcrumb :separator-icon="ArrowRight">
        <el-breadcrumb-item @click="changeRouter(1)" :class="indexFlag===1?'indexTag':''" :to="{ path: '/main/userLog/userListLog' }">{{$t('日志首页')}}</el-breadcrumb-item>
        <el-breadcrumb-item v-show="false" />
      </el-breadcrumb>
    </div>
    <div id="main-body">
      <router-view :key="route.fullPath" />
    </div>
  </div>
</template>
<style scoped>
#main-div{
  width: 99%;
  height: 100%;
}
#div-title{
  height: 2%;
  width: 100%;
}
#searchButton{
  margin-top: -5px;
  margin-left: 1rem;
}
#searchButton1{
//margin-left: 10rem;
}
/*main-body样式*/
#main-body{
  width: 100%;
  height: 95%;
  margin-top: 1%;
}
#select{
  margin-left:0.5rem;
}
:deep(.indexTag .el-breadcrumb__inner){
  color: #5CADFE !important;
}
</style>
north-glass-erp/src/main/java/com/example/erp/controller/userInfo/UserController.java
@@ -68,4 +68,10 @@
        return Result.success( userService.updateUserName(object));
    }
    @ApiOperation("用户登录记录")
    @PostMapping("/getUserLog")
    public Result getUserLog(){
        return Result.success( userService.getUserLog());
    }
}
north-glass-erp/src/main/java/com/example/erp/entity/sd/Order.java
@@ -9,6 +9,7 @@
import lombok.Data;
import java.time.LocalDate;
import java.util.List;
@Data
@TableName("sd.`order`")
@@ -105,6 +106,8 @@
    private Integer goodsQuantity;
    @TableField(select = false,exist = false)
    private String timeOut;
    @TableField(select = false,exist = false)
    private List<String> excludeOrderIds;
    @TableField(value = "customer_id")
    private Customer  customer;
north-glass-erp/src/main/java/com/example/erp/mapper/userInfo/UserMapper.java
@@ -8,6 +8,7 @@
import org.apache.ibatis.annotations.Select;
import java.util.List;
import java.util.Map;
@Mapper
@@ -41,4 +42,6 @@
    List<User> findByAddress(String userName);
    String selectOptimizeParmsById(@Param("username") String username);
    List<Map<String, Object>> getUserLog();
}
north-glass-erp/src/main/java/com/example/erp/service/userInfo/UserService.java
@@ -5,11 +5,13 @@
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.example.erp.controller.dto.UserDTO;
import com.example.erp.entity.userInfo.Log;
import com.example.erp.entity.userInfo.Role;
import com.example.erp.entity.userInfo.User;
import com.example.erp.mapper.pp.ProductionSchedulingMapper;
import com.example.erp.mapper.userInfo.*;
import com.example.erp.tools.TokenTools;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
@@ -27,6 +29,9 @@
   private final PermissionRoleMapper permissionRoleMapper;
    private final ProductionSchedulingMapper productionSchedulingMapper;
    @Autowired
    LogService logService;
    public UserService(UserMapper userMapper, RoleMapper roleMapper, PermissionRoleMapper permissionRoleMapper, UserRoleMapper userRoleMapper, ProductionSchedulingMapper productionSchedulingMapper) {
        this.userMapper = userMapper;
@@ -142,6 +147,13 @@
            userDTO.setToken(StpUtil.getTokenValue());
            Boolean userIsAdmin= userRoleMapper.getUserIsAdmin(user.getId());
            userDTO.setPermissions(permissionRoleMapper.getUserEditPermission(user.getId(),userIsAdmin));
            Log log = new Log();
            log.setOperator(user.getUserName());
            log.setOperatorId(userDTO.getUserId());
            log.setContent(userDTO.toString());
            log.setFunction("用户登录");
            logService.saveLog(log);
            return userDTO;
        }else{
            return null;
@@ -208,6 +220,12 @@
        return map;
    }
    public Object getUserLog() {
        Map<String, Object> map = new HashMap<>();
        map.put("data", userMapper.getUserLog());
        return map;
    }
//查询用户优化参数
public String getOptimizeParms(String username) {
north-glass-erp/src/main/resources/mapper/sd/DeliveryDetailMapper.xml
@@ -486,6 +486,7 @@
                and od.perimeter regexp #{orderDetail.perimeter}
            </if>
        </where>
        order by od.order_id,od.order_number
    </select>
    <select id="getSelectShippingOrderDetailsPageTotal">
north-glass-erp/src/main/resources/mapper/userInfo/User.xml
@@ -110,5 +110,10 @@
            SELECT optimize_parms FROM erp_user_info.user WHERE user_name = #{username}
        </select>
    <select id="getUserLog" >
        SELECT operator_id,operator,DATE_FORMAT(create_time, '%Y-%m-%d %H:%i:%s') AS format_create_time
        FROM erp_log.log
        WHERE create_time >= DATE_SUB(NOW(), INTERVAL 1 MONTH) and `function`='用户登录' order by create_time desc limit 0,100
    </select>
</mapper>