From c866c43016f12a9db80095d9e5fd7bbc3dcaeb66 Mon Sep 17 00:00:00 2001
From: heshaofeng <heshaofeng@hnkhzn.com>
Date: 星期四, 19 三月 2026 15:45:30 +0800
Subject: [PATCH] 1

---
 项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_Model/Models/System/Sys_User.cs                    |    2 
 项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_SystemService/Sys_UserService.cs                   |  126 +++++++++
 项目代码/WIDESEA_WMSClient/src/views/inbound/inboundOrder.vue                                 |    6 
 项目代码/WIDESEA_WMSClient/src/router/index.js                                                |    8 
 项目代码/WIDESEA_WMSClient/src/views/Login.vue                                                |   36 ++
 项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_SystemService/WIDESEA_SystemService.csproj         |    1 
 项目代码/WIDESEA_WMSClient/src/views/ChangePassword.vue                                       |  334 +++++++++++++++++++++++++
 项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_Core/Extensions/SqlsugarSetup.cs                   |    2 
 项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_IBasicService/IPasswordPolicyConfigService.cs      |   20 +
 项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_Core/HttpContextUser/AspNetUser.cs                 |    2 
 /dev/null                                                                                 |    0 
 项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_InboundService/InboundOrderService.cs              |   37 ++
 项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_OutboundService/OutboundOrderService.cs            |   42 ++
 项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_BasicService/PasswordPolicyConfigService.cs        |   44 +++
 项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_OutboundService/OutboundService.cs                 |   12 
 项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_TaskInfoService/TaskService.cs                     |    8 
 项目代码/WIDESEA_WMSClient/src/views/record/stockQuantityChangeRecord.vue                     |    8 
 项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_Model/Models/Config/PasswordPolicyConfig.cs        |   26 ++
 项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_ISystemService/ISys_UserService.cs                 |    2 
 项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/System/Sys_UserController.cs |   15 +
 20 files changed, 689 insertions(+), 42 deletions(-)

diff --git "a/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/router/index.js" "b/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/router/index.js"
index a42f273..14c0452 100644
--- "a/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/router/index.js"
+++ "b/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/router/index.js"
@@ -38,6 +38,14 @@
       }
   }, 
   {
+    path: '/change-password',
+    name: 'ChangePassword',
+    component: () => import('@/views/ChangePassword.vue'),
+    meta:{
+        anonymous:true
+      }
+  }, 
+  {
     path: '/bigdata',
     name: 'bigdata',
     component: () => import('@/views/charts/bigdata.vue'),
diff --git "a/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/views/ChangePassword.vue" "b/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/views/ChangePassword.vue"
new file mode 100644
index 0000000..bcff40f
--- /dev/null
+++ "b/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/views/ChangePassword.vue"
@@ -0,0 +1,334 @@
+<template>
+  <div class="login-container">
+    <div class="project-name">WMS</div>
+    <div class="login-form">
+      <div class="form-user" @keypress="changePwdPress">
+        <div class="login-text">
+          <div>淇敼瀵嗙爜</div>
+        </div>
+        <div class="login-text-small">CHANGE PASSWORD</div>
+        
+        <!-- 鏂板锛氱敤鎴峰悕杈撳叆妗� -->
+        <div class="item">
+          <div class="input-icon el-icon-user"></div>
+          <input 
+            type="text" 
+            v-focus 
+            v-model="pwdForm.userName" 
+            placeholder="璇疯緭鍏ョ敤鎴峰悕" 
+          />
+        </div>
+        
+        <!-- 鏃у瘑鐮� -->
+        <div class="item">
+          <div class="input-icon el-icon-lock"></div>
+          <input 
+            type="password" 
+            v-model="pwdForm.oldPwd" 
+            placeholder="璇疯緭鍏ユ棫瀵嗙爜" 
+          />
+        </div>
+        
+        <!-- 鏂板瘑鐮� -->
+        <div class="item">
+          <div class="input-icon el-icon-key"></div>
+          <input 
+            type="password" 
+            v-model="pwdForm.newPwd" 
+            placeholder="璇疯緭鍏ユ柊瀵嗙爜" 
+          />
+        </div>
+        
+        <!-- 纭鏂板瘑鐮� -->
+        <div class="item">
+          <div class="input-icon el-icon-key"></div>
+          <input 
+            type="password" 
+            v-model="pwdForm.confirmPassword" 
+            placeholder="璇风‘璁ゆ柊瀵嗙爜" 
+          />
+        </div>
+      </div>
+      
+      <!-- 鎻愪氦鎸夐挳 -->
+      <div class="loging-btn">
+        <el-button 
+          size="large" 
+          :loading="loading" 
+          color="#3a6cd1" 
+          :dark="true" 
+          @click="changePassword" 
+          long
+        >
+          <span v-if="!loading">纭淇敼</span>
+          <span v-else>姝e湪淇敼...</span>
+        </el-button>
+      </div>
+      
+      <!-- 杩斿洖鎸夐挳 -->
+      <div class="back-login-btn">
+        <el-button 
+          size="large" 
+          type="text" 
+          @click="goBack"
+        >
+          杩斿洖
+        </el-button>
+      </div>
+    </div>
+
+    <img class="login-bg" src="/static/login_bg.png" />
+  </div>
+</template>
+
+<script>
+import {
+  defineComponent,
+  ref,
+  reactive,
+  getCurrentInstance,
+} from "vue";
+import { useRouter, useRoute } from "vue-router";
+import store from "../store/index";
+import http from "@/../src/api/http.js";
+
+export default defineComponent({
+  setup(props, context) {
+    const loading = ref(false);
+    const router = useRouter();
+    
+    // 瀵嗙爜琛ㄥ崟锛堜繚鐣欏師鏈夐粯璁ゅ�硷紝鏂板鐢ㄦ埛鍚嶅弻鍚戠粦瀹氾級
+    const pwdForm = reactive({
+      userName: store.state.userInfo?.userName || "", // 浠嶄繚鐣欎粠store鍙栧�硷紝鍙墜鍔ㄤ慨鏀�
+      oldPwd: "",
+      newPwd: "",
+      confirmPassword: "",
+    });
+
+    // 鍏ㄥ眬鎻愮ず
+    let appContext = getCurrentInstance().appContext;
+    let $message = appContext.config.globalProperties.$message;
+
+    // 鍥炶溅瑙﹀彂
+    const changePwdPress = (e) => {
+      if (e.keyCode === 13) {
+        changePassword();
+      }
+    };
+
+    // 杩斿洖涓婁竴椤�
+    const goBack = () => {
+      router.go(-1);
+    };
+
+    // 琛ㄥ崟鏍¢獙锛堟柊澧烇細鐢ㄦ埛鍚嶉潪绌烘牎楠岋級
+    const validateForm = () => {
+      if (!pwdForm.userName) return $message.error("璇疯緭鍏ョ敤鎴峰悕"); // 鏂板
+      if (!pwdForm.oldPwd) return $message.error("璇疯緭鍏ユ棫瀵嗙爜");
+      if (!pwdForm.newPwd) return $message.error("璇疯緭鍏ユ柊瀵嗙爜");
+      if (pwdForm.newPwd.length < 6) {
+         $message.error("鏂板瘑鐮侀暱搴︿笉鑳藉皬浜�6浣�");
+        return false;
+      }
+      if (pwdForm.newPwd !== pwdForm.confirmPassword) {
+        $message.error("涓ゆ杈撳叆鐨勬柊瀵嗙爜涓嶄竴鑷�");
+        return false;
+      }
+      if (pwdForm.oldPwd === pwdForm.newPwd) {
+        $message.error("鏂板瘑鐮佷笉鑳戒笌鏃у瘑鐮佺浉鍚�");
+        return false;
+      }
+      return true;
+    };
+
+    // 淇敼瀵嗙爜锛堥�昏緫涓嶅彉锛寀serName宸插湪琛ㄥ崟涓級
+    const changePassword = () => {
+      if (!validateForm()) return;
+
+      loading.value = true;
+      http.post("/api/User/ModifyUserNamePwd", {
+        userName: pwdForm.userName,
+        newPwd: pwdForm.newPwd,
+        oldPwd: pwdForm.oldPwd
+      }, "姝e湪淇敼瀵嗙爜....").then((result) => {
+        loading.value = false;
+        if (!result.status) return $message.error(result.message);
+        
+        $message.success("瀵嗙爜淇敼鎴愬姛锛岃閲嶆柊鐧诲綍");
+        store.commit("clearUserInfo", "");
+        setTimeout(() => router.push("/login"), 1500);
+      }).catch((err) => {
+        loading.value = false;
+        $message.error("淇敼瀵嗙爜澶辫触锛岃鑱旂郴绠$悊鍛�");
+      });
+    };
+
+    return {
+      loading,
+      pwdForm,
+      changePassword,
+      changePwdPress,
+      goBack,
+    };
+  },
+  directives: {
+    focus: {
+      inserted: function (el) {
+        el.focus();
+      },
+    },
+  },
+});
+</script>
+
+<style lang="less" scoped>
+// 瀹屽叏澶嶇敤浣犵櫥褰曢〉鐨勬牱寮忥紝鍙柊澧炲皯閲忔寜閽牱寮�
+.login-container {
+  display: flex;
+  width: 100%;
+  height: 100%;
+  background: rgb(246, 247, 252);
+  justify-content: flex-end;
+  align-items: center;
+}
+
+.login-form {
+  align-items: center;
+  width: 50%;
+  display: flex;
+  flex-direction: column;
+  z-index: 999;
+
+  .form-user {
+    .item {
+      border-radius: 5px;
+      border: 1px solid #ececec;
+      display: flex;
+      margin-bottom: 30px;
+      background: #ffff;
+      height: 45px;
+      padding-left: 20px;
+      align-items: center;
+
+      .input-icon {
+        color: #7a7a7a;
+        padding-right: 20px;
+        display: flex;
+        align-items: center;
+      }
+    }
+  }
+
+  input:-webkit-autofill {
+    box-shadow: 0 0 0px 1000px white inset;
+    -webkit-box-shadow: 0 0 0px 1000px white inset !important;
+  }
+
+  input {
+    background: white;
+    display: block;
+    box-sizing: border-box;
+    width: 100%;
+    min-width: 0;
+    margin: 0;
+    padding: 0;
+    color: #323233;
+    text-align: left;
+    border: 0;
+    outline: none;
+    font-size: 16px;
+    height: 100%;
+    line-height: normal;
+  }
+}
+
+.form-user,
+.loging-btn {
+  width: 400px;
+}
+
+.loging-btn {
+  box-shadow: 2px 4px 11px #a4c2ff;
+  margin-top: 10px;
+
+  button {
+    padding: 21px;
+    font-size: 14px !important;
+    width: 100%;
+  }
+}
+
+// 浠呮柊澧烇細杩斿洖鎸夐挳鏍峰紡
+.back-login-btn {
+  width: 400px;
+  margin-top: 15px;
+  text-align: center;
+
+  button {
+    font-size: 13px;
+    color: #3a6cd1;
+    padding: 0;
+
+    &:hover {
+      color: #1850c1;
+    }
+  }
+}
+
+.login-text {
+  font-weight: bolder;
+  font-size: 20px;
+  letter-spacing: 2px;
+  position: relative;
+  display: flex;
+}
+
+.login-text-small {
+  margin-bottom: 20px;
+  font-size: 13px;
+  color: #7d7c7c;
+}
+
+.login-bg {
+  left: 0;
+  position: absolute;
+  height: 100%;
+  width: 50%;
+  z-index: 0;
+}
+
+.project-name {
+  position: absolute;
+  top: 40px;
+  left: 40px;
+  z-index: 9999;
+  font-weight: bolder;
+  background-image: linear-gradient(to right, #1850c1, #9c009c);
+  -webkit-background-clip: text;
+  color: transparent;
+  font-size: 25px;
+}
+
+// 鍝嶅簲寮忛�傞厤锛堝鐢ㄤ綘鐨勯�昏緫锛�
+@media screen and (max-width: 700px) {
+  .login-bg,
+  .project-name {
+    display: none;
+  }
+
+  .login-container {
+    padding: 2rem;
+    justify-content: center;
+  }
+
+  .login-form {
+    width: 100%;
+  }
+
+  .form-user,
+  .loging-btn,
+  .back-login-btn {
+    width: 100%;
+  }
+}
+</style>
\ No newline at end of file
diff --git "a/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/views/Login.vue" "b/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/views/Login.vue"
index c342358..527ecfe 100644
--- "a/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/views/Login.vue"
+++ "b/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/views/Login.vue"
@@ -26,14 +26,17 @@
             <el-option v-for="item in stationOptions" :key="item.value" :label="item.label" :value="item.value" />
           </el-select>
         </div>
-
-
-        
       </div>
       <div class="loging-btn">
         <el-button size="large" :loading="loading" color="#3a6cd1" :dark="true" @click="login" long>
           <span v-if="!loading">鐧诲綍</span>
           <span v-else>姝e湪鐧诲綍...</span>
+        </el-button>
+      </div>
+      <!-- 鏂板锛氫慨鏀瑰瘑鐮佹寜閽紙鏍峰紡涓庣櫥褰曢〉缁熶竴锛� -->
+      <div class="change-pwd-btn">
+        <el-button size="large" type="text" @click="goChangePassword" long>
+          <span style="color: #3a6cd1; font-size: 13px;">淇敼瀵嗙爜</span>
         </el-button>
       </div>
     </div>
@@ -104,6 +107,11 @@
     let $message = appContext.config.globalProperties.$message;
     let router = useRouter();
 
+    // 鏂板锛氳烦杞埌淇敼瀵嗙爜椤甸潰
+    const goChangePassword = () => {
+      router.push({ path: "/change-password" });
+    };
+
     const login = () => {
       if (!userInfo.userName) return $message.error("璇疯緭鍏ョ敤鎴峰悕");
       if (!userInfo.password) return $message.error("璇疯緭鍏ュ瘑鐮�");
@@ -122,7 +130,7 @@
           getVierificationCode();
           return $message.error(result.message);
         }
-        $message.success("鐧诲綍鎴愬姛,姝e湪璺宠浆!");
+        $message.success(result.message);
         store.commit("setUserInfo", result.data);
 
         router.push({ path: "/" });
@@ -147,6 +155,7 @@
       stationOptions,
       stationValue,
       handleStationChange,
+      goChangePassword // 鏂板锛氭毚闇茶烦杞柟娉�
     };
   },
   directives: {
@@ -264,6 +273,22 @@
     padding: 21px;
     font-size: 14px !important;
     width: 100%;
+  }
+}
+
+// 鏂板锛氫慨鏀瑰瘑鐮佹寜閽牱寮忥紙涓庣櫥褰曢〉椋庢牸缁熶竴锛�
+.change-pwd-btn {
+  width: 400px;
+  margin-top: 15px;
+  text-align: center;
+
+  button {
+    font-size: 13px;
+    padding: 0;
+
+    &:hover {
+      color: #1850c1 !important;
+    }
   }
 }
 
@@ -517,7 +542,8 @@
   }
 
   .form-user,
-  .loging-btn {
+  .loging-btn,
+  .change-pwd-btn { // 鏂板锛氬搷搴斿紡閫傞厤淇敼瀵嗙爜鎸夐挳
     width: 100%;
   }
 }
diff --git "a/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/views/inbound/inboundOrder.vue" "b/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/views/inbound/inboundOrder.vue"
index 27ae659..0cfb062 100644
--- "a/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/views/inbound/inboundOrder.vue"
+++ "b/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/views/inbound/inboundOrder.vue"
@@ -23,6 +23,9 @@
       inboundOrderNo: "",
       upperOrderNo: "",
       remark: "",
+      orderStatus: "",
+      warehouseId: "",
+      supplierId: "",
     });
     const editFormOptions = ref([
       [
@@ -33,7 +36,6 @@
           type: "select",
           dataKey: "inOrderType",
           data: [],
-          hidden: true
         },
         {
           field: "inboundOrderNo",
@@ -326,6 +328,8 @@
           type: "string",
           width: 90,
           align: "left",
+          edit: { type: "" },
+          required: true,
         },
         {
           field: "orderDetailStatus",
diff --git "a/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/views/record/stockQuantityChangeRecord.vue" "b/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/views/record/stockQuantityChangeRecord.vue"
index 455d8e3..aedcef1 100644
--- "a/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/views/record/stockQuantityChangeRecord.vue"
+++ "b/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/views/record/stockQuantityChangeRecord.vue"
@@ -41,6 +41,7 @@
         { title: "鍑哄簱鍘熸潯鐮�", field: "originalSerilNumber", type: "like" },
         { title: "鎷嗗寘鏂版潯鐮�", field: "newSerilNumber", type: "like" },
         { title: "鎵规鍙�", field: "batchNo", type: "like" },
+        { title: "浠撳簱鍙�", field: "warehouseCode", type: "like" },
       ],
     ]);
     const columns = ref([
@@ -163,6 +164,13 @@
         align: "left",
       },
       {
+        field: "warehouseCode",
+        title: "浠撳簱",
+        type: "string",
+        width: 100,
+        align: "left",
+      },
+      {
         field: "creater",
         title: "鍒涘缓浜�",
         type: "string",
diff --git "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_BasicService/PasswordPolicyConfigService.cs" "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_BasicService/PasswordPolicyConfigService.cs"
new file mode 100644
index 0000000..addd7b2
--- /dev/null
+++ "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_BasicService/PasswordPolicyConfigService.cs"
@@ -0,0 +1,44 @@
+锘縰sing System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using WIDESEA_Core.BaseRepository;
+using WIDESEA_Core.BaseServices;
+using WIDESEA_Core.Helper;
+using WIDESEA_IBasicService;
+using WIDESEA_Model.Models.Config;
+
+namespace WIDESEA_BasicService
+{
+    public class PasswordPolicyConfigService : ServiceBase<PasswordPolicyConfig, IRepository<PasswordPolicyConfig>>, IPasswordPolicyConfigService
+    {
+        public PasswordPolicyConfigService(IRepository<PasswordPolicyConfig> BaseDal) : base(BaseDal)
+        {
+        }
+
+        /// <summary>
+        /// 鑾峰彇瀵嗙爜绛栫暐閰嶇疆锛堜粠AppSettings璇诲彇锛�
+        /// </summary>
+        public PasswordPolicyConfig GetConfigValue(string key = "")
+        {
+            try
+            {
+                // 浠巃ppsettings.json鐨凱asswordPolicy鑺傜偣璇诲彇閰嶇疆
+                var config = new PasswordPolicyConfig
+                {
+                    EnablePasswordExpire = AppSettings.Get(new[] { "PasswordPolicy", "EnablePasswordExpire" }).ObjToBool(),
+                    PasswordExpireDays = AppSettings.Get(new[] { "PasswordPolicy", "PasswordExpireDays" }).ObjToInt(90),
+                    RemindBeforeExpireDays = AppSettings.Get(new[] { "PasswordPolicy", "RemindBeforeExpireDays" }).ObjToInt(7)
+                };
+                return config;
+            }
+            catch
+            {
+                // 璇诲彇澶辫触杩斿洖榛樿閰嶇疆
+                return new PasswordPolicyConfig();
+            }
+        }
+    }
+}
+
diff --git "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_Core/Extensions/SqlsugarSetup.cs" "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_Core/Extensions/SqlsugarSetup.cs"
index b985f1f..67aa76e 100644
--- "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_Core/Extensions/SqlsugarSetup.cs"
+++ "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_Core/Extensions/SqlsugarSetup.cs"
@@ -1,4 +1,4 @@
-锘縰sing Microsoft.Extensions.Caching.Memory;
+using Microsoft.Extensions.Caching.Memory;
 using Microsoft.Extensions.DependencyInjection;
 using SqlSugar;
 using StackExchange.Profiling;
diff --git "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_Core/HttpContextUser/AspNetUser.cs" "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_Core/HttpContextUser/AspNetUser.cs"
index da7b185..2342b0e 100644
--- "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_Core/HttpContextUser/AspNetUser.cs"
+++ "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_Core/HttpContextUser/AspNetUser.cs"
@@ -184,5 +184,7 @@
         public string UserTrueName { get; set; }
 
         public string HeadImageUrl { get; set; }
+
+        public DateTime? PwdLastModifyTime { get; set; }
     }
 }
diff --git "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_IBasicService/IPasswordPolicyConfigService.cs" "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_IBasicService/IPasswordPolicyConfigService.cs"
new file mode 100644
index 0000000..81d249f
--- /dev/null
+++ "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_IBasicService/IPasswordPolicyConfigService.cs"
@@ -0,0 +1,20 @@
+锘縰sing System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using WIDESEA_Core.BaseServices;
+using WIDESEA_Model.Models.Config;
+
+namespace WIDESEA_IBasicService
+{
+    public interface IPasswordPolicyConfigService : IService<PasswordPolicyConfig>
+    {
+        /// <summary>
+        /// 鑾峰彇瀵嗙爜绛栫暐閰嶇疆
+        /// </summary>
+        /// <param name="key">棰勭暀閿�硷紙閫傞厤鍘熸湁鏂规硶绛惧悕锛�</param>
+        /// <returns>瀵嗙爜绛栫暐閰嶇疆</returns>
+        PasswordPolicyConfig GetConfigValue(string key = "");
+    }
+}
diff --git "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_ISystemService/ISys_UserService.cs" "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_ISystemService/ISys_UserService.cs"
index 0692b26..0130e6e 100644
--- "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_ISystemService/ISys_UserService.cs"
+++ "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_ISystemService/ISys_UserService.cs"
@@ -22,5 +22,7 @@
 
         WebResponseContent ModifyPwd(string oldPwd, string newPwd);
         WebResponseContent ModifyUserPwd(string password, string userName);
+
+        WebResponseContent ModifyUserNamePwd(string oldPassword, string userName,string newPassword);
     }
 }
diff --git "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_InboundService/InboundOrderService.cs" "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_InboundService/InboundOrderService.cs"
index b099aa3..418c05f 100644
--- "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_InboundService/InboundOrderService.cs"
+++ "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_InboundService/InboundOrderService.cs"
@@ -705,9 +705,10 @@
             {
                 _unitOfWorkManage.BeginTran();
 
-                // 鏅鸿兘璇嗗埆杈撳叆绫诲瀷
+              
                 string palletCode = null;
                 string barcode = null;
+                int stockStatus = 0; 
 
                 // 1. 鍏堝皾璇曟寜鎵樼洏鍙锋煡璇�
                 var stockByPallet = _stockRepository.Db.Queryable<Dt_StockInfo>()
@@ -720,10 +721,17 @@
                 {
                     // 璇嗗埆涓烘墭鐩樺彿
                     palletCode = code;
-                    var task =_taskRepository.Db.Queryable<Dt_Task>().Where(t => t.PalletCode == palletCode).ToList();
-                    if(task!=null && task.Any())
+                    stockStatus = stockByPallet.StockStatus; 
+
+                    var task = _taskRepository.Db.Queryable<Dt_Task>().Where(t => t.PalletCode == palletCode).ToList();
+                    if (task != null && task.Any())
                     {
                         return WebResponseContent.Instance.Error($"鎵樼洏鍙� {palletCode} 瀛樺湪鏈畬鎴愮殑浠诲姟锛屾棤娉曟挙閿�");
+                    }
+
+                    if (stockStatus == StockStatusEmun.鍏ュ簱纭.ObjToInt())
+                    {
+                        return WebResponseContent.Instance.Error($"鎵樼洏鍙� {palletCode} 澶勪簬鍏ュ簱纭鐘舵�侊紝绂佹鏁存墭鐩樻挙閿�锛岃鍗曠嫭鎾ら攢鏉$爜");
                     }
                 }
                 else
@@ -734,13 +742,14 @@
                     {
                         var stockInfo = _stockRepository
                             .Db.Queryable<Dt_StockInfo>()
-                            .Where(s => s.Id == detail.StockId&& (s.StockStatus == (int)StockStatusEmun.缁勭洏鏆傚瓨 || s.StockStatus == StockStatusEmun.鍏ュ簱纭.ObjToInt()))
+                            .Where(s => s.Id == detail.StockId && (s.StockStatus == (int)StockStatusEmun.缁勭洏鏆傚瓨 || s.StockStatus == StockStatusEmun.鍏ュ簱纭.ObjToInt()))
                             .First();
 
                         if (stockInfo != null)
                         {
                             barcode = code;
                             palletCode = stockInfo.PalletCode;
+                            stockStatus = stockInfo.StockStatus; 
                         }
                     }
                     else
@@ -773,6 +782,16 @@
                         return WebResponseContent.Instance.Error($"鎵樼洏 {palletCode} 涓嬫湭鎵惧埌鏉$爜 {barcode} 鐨勬槑缁嗚褰�");
                     }
 
+                    if (stockStatus == StockStatusEmun.鍏ュ簱纭.ObjToInt())
+                    {
+                        var totalDetails = stock.Details?.Count ?? 0;
+                        if (totalDetails <= 1)
+                        {
+                            _unitOfWorkManage.RollbackTran();
+                            return WebResponseContent.Instance.Error($"鎵樼洏 {palletCode} 澶勪簬鍏ュ簱纭鐘舵�侊紝褰撳墠浠呭墿浣欐渶鍚�1鏉℃槑缁嗭紝绂佹鎾ら攢锛堝繀椤讳繚鐣欒嚦灏�1鏉″簱瀛樻槑缁嗭級");
+                        }
+                    }
+
                     ResetInboundOrderStatus(new List<string> { targetDetail.OrderNo }, new List<string> { targetDetail.Barcode });
                     _stockDetailRepository.DeleteData(targetDetail);
 
@@ -782,10 +801,13 @@
 
                     if (!remainingDetails.Any())
                     {
-                        ResetInboundOrderStatus(stock.Details.Select(d => d.OrderNo).Distinct().ToList());
-                        _stockRepository.DeleteData(stock);
+                        if (stockStatus == (int)StockStatusEmun.缁勭洏鏆傚瓨)
+                        {
+                            ResetInboundOrderStatus(stock.Details.Select(d => d.OrderNo).Distinct().ToList());
+                            _stockRepository.DeleteData(stock);
+                        }
                         _unitOfWorkManage.CommitTran();
-                        return WebResponseContent.Instance.OK($"鏉$爜 {barcode} 鎾ら攢鎴愬姛锛屾墭鐩樻棤鍓╀綑鏄庣粏锛屽凡鍒犻櫎鎵樼洏骞堕噸缃叧鑱斿叆搴撳崟鐘舵��");
+                        return WebResponseContent.Instance.OK($"鏉$爜 {barcode} 鎾ら攢鎴愬姛锛屾墭鐩樻棤鍓╀綑鏄庣粏锛屽凡閲嶇疆鍏宠仈鍏ュ簱鍗曠姸鎬�");
                     }
 
                     _unitOfWorkManage.CommitTran();
@@ -793,7 +815,6 @@
                 }
                 else
                 {
-                    // ===== 鎾ら攢鏁翠釜鎵樼洏 =====
                     var stock = _stockRepository.Db.Queryable<Dt_StockInfo>()
                         .Includes(o => o.Details)
                         .First(x => x.PalletCode == palletCode
diff --git "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_Model/Models/Config/PasswordPolicyConfig.cs" "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_Model/Models/Config/PasswordPolicyConfig.cs"
new file mode 100644
index 0000000..e210bfa
--- /dev/null
+++ "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_Model/Models/Config/PasswordPolicyConfig.cs"
@@ -0,0 +1,26 @@
+锘縰sing System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace WIDESEA_Model.Models.Config
+{
+    public class PasswordPolicyConfig
+    {
+        /// <summary>
+        /// 鏄惁鍚敤瀵嗙爜杩囨湡绛栫暐
+        /// </summary>
+        public bool EnablePasswordExpire { get; set; } = true;
+
+        /// <summary>
+        /// 瀵嗙爜鏈夋晥鏈燂紙澶╋級
+        /// </summary>
+        public int PasswordExpireDays { get; set; } = 90;
+
+        /// <summary>
+        /// 鎻愬墠鎻愰啋澶╂暟
+        /// </summary>
+        public int RemindBeforeExpireDays { get; set; } = 7;
+    }
+}
diff --git "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_Model/Models/System/Sys_User.cs" "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_Model/Models/System/Sys_User.cs"
index 99c6a1e..cf44294 100644
--- "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_Model/Models/System/Sys_User.cs"
+++ "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_Model/Models/System/Sys_User.cs"
@@ -103,7 +103,7 @@
         /// <summary>
         /// 鏈�鍚庡瘑鐮佷慨鏀规椂闂�
         /// </summary>
-        [SugarColumn(IsNullable = true, IsOnlyIgnoreInsert = true, ColumnDescription = "鏈�鍚庡瘑鐮佷慨鏀规椂闂�")]
+        [SugarColumn(IsNullable = true, ColumnDescription = "鏈�鍚庡瘑鐮佷慨鏀规椂闂�")]
         public DateTime? LastModifyPwdDate { get; set; }
 
         /// <summary>
diff --git "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_OutboundService/OutboundOrderService.cs" "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_OutboundService/OutboundOrderService.cs"
index 630dd2c..3b3035a 100644
--- "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_OutboundService/OutboundOrderService.cs"
+++ "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_OutboundService/OutboundOrderService.cs"
@@ -146,24 +146,24 @@
                             BarcodeQty = item.OrderQuantity,
                             BarcodeUnit = item.Unit,
                         };
-                        var issueoStockResult = await _materialUnitService.ConvertFromToStockAsync(item.MaterielCode, item.BarcodeUnit, item.BarcodeQty);
-                        outboundOrderDetail.Unit = issueoStockResult.Unit;
-                        outboundOrderDetail.OrderQuantity = issueoStockResult.Quantity;
-                        var moveissueoStockResult = await _materialUnitService.ConvertFromToStockAsync(item.MaterielCode, item.BarcodeUnit, item.BarcodeMoveQty);
-                        outboundOrderDetail.MoveQty = moveissueoStockResult.Quantity;
+                        var unitConvertResult = await ConvertUnitAsync(item.MaterielCode, item.BarcodeUnit, item.BarcodeQty, item.BarcodeMoveQty);
+                        outboundOrderDetail.Unit = unitConvertResult.Unit;
+                        outboundOrderDetail.OrderQuantity = unitConvertResult.OrderQuantity;
+                        outboundOrderDetail.MoveQty = unitConvertResult.MoveQty;
 
                         outboundOrderDetail.MaterielName = materielInfos.FirstOrDefault(x => x.MaterielCode == item.MaterielCode)?.MaterielName ?? "";
                         outboundOrderDetails.Add(outboundOrderDetail);
                     }
                     else
                     {
+                        var unitConvertResult = await ConvertUnitAsync(item.MaterielCode, item.BarcodeUnit, item.BarcodeQty, item.BarcodeMoveQty);
                         #region 閿佸畾鐘舵�佷笅闈炴暟閲忓瓧娈典竴鑷存�ф牎楠�
                         if (outboundOrderDetail.LockQuantity != 0)
                         {
                             var isFieldChanged = !string.Equals(outboundOrderDetail.MaterielCode, item.MaterielCode)
                                 || !string.Equals(outboundOrderDetail.SupplyCode, item.SupplyCode)
                                 || !string.Equals(outboundOrderDetail.BatchNo, item.BatchNo)
-                                || !string.Equals(outboundOrderDetail.Unit, item.Unit)
+                                || !string.Equals(outboundOrderDetail.Unit, unitConvertResult.Unit)
                                 || !string.Equals(outboundOrderDetail.WarehouseCode, item.WarehouseCode)
                                 || !string.Equals(outboundOrderDetail.lineNo, item.lineNo)
                                 ;
@@ -203,12 +203,9 @@
                             outboundOrderDetail.BarcodeMoveQty = item.MoveQty;
                             outboundOrderDetail.BarcodeQty = item.OrderQuantity;
                             outboundOrderDetail.BarcodeUnit = item.Unit;
-
-                            var issueoStockResult = await _materialUnitService.ConvertFromToStockAsync(item.MaterielCode, item.BarcodeUnit, item.BarcodeQty);
-                            outboundOrderDetail.Unit = issueoStockResult.Unit;
-                            outboundOrderDetail.OrderQuantity = issueoStockResult.Quantity;
-                            var moveissueoStockResult = await _materialUnitService.ConvertFromToStockAsync(item.MaterielCode, item.BarcodeUnit, item.BarcodeMoveQty);
-                            outboundOrderDetail.MoveQty = moveissueoStockResult.Quantity;
+                            outboundOrderDetail.Unit = unitConvertResult.Unit;
+                            outboundOrderDetail.OrderQuantity = unitConvertResult.OrderQuantity;
+                            outboundOrderDetail.MoveQty = unitConvertResult.MoveQty;
                         }
                         else
                         {
@@ -510,5 +507,26 @@
 
             return new PageGridData<Dt_OutboundOrder>(totalCount, data);
         }
+
+
+        private async Task<UnitConvertResult> ConvertUnitAsync(string materielCode, string barcodeUnit, decimal barcodeQty, decimal barcodeMoveQty)
+        {
+            var issueoStockResult = await _materialUnitService.ConvertFromToStockAsync(materielCode, barcodeUnit, barcodeQty);
+            var moveissueoStockResult = await _materialUnitService.ConvertFromToStockAsync(materielCode, barcodeUnit, barcodeMoveQty);
+
+            return new UnitConvertResult
+            {
+                Unit = issueoStockResult.Unit,
+                OrderQuantity = issueoStockResult.Quantity,
+                MoveQty = moveissueoStockResult.Quantity
+            };
+        }
+
+        private class UnitConvertResult
+        {
+            public string Unit { get; set; }
+            public decimal OrderQuantity { get; set; }
+            public decimal MoveQty { get; set; }
+        }
     }
 }
diff --git "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_OutboundService/OutboundService.cs" "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_OutboundService/OutboundService.cs"
index 4d08558..74efebe 100644
--- "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_OutboundService/OutboundService.cs"
+++ "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_OutboundService/OutboundService.cs"
@@ -1988,6 +1988,7 @@
                 Creater = stockDetail.Creater,
                 CreateDate = stockDetail.CreateDate,
                 WarehouseCode = stockDetail.WarehouseCode,
+                ValidDate = stockDetail.ValidDate,
                 Remark = $"鍑哄簱瀹屾垚鍒犻櫎锛屾潯鐮侊細{request.Barcode}锛屽師鏁伴噺锛歿stockDetail.StockQuantity}锛屽嚭搴撴暟閲忥細{actualOutboundQuantity}锛屾搷浣滆�咃細{request.Operator}"
             };
             _stockDetailHistoryRepository.AddData(historyRecord);
@@ -2485,11 +2486,14 @@
                     x.Barcode == request.Barcode &&
                  
                     (x.OperateType == "鍑哄簱瀹屾垚" || x.OperateType == "鎷嗗寘-鍘熷璁板綍"));
-                if (historyDetail == null)
+
+                if(historyDetail != null)
                 {
-                    response.Success = false;
-                    response.Message = $"鏉$爜 {request.Barcode} 宸叉媶鍖咃紝鏃犳硶鎾ら攢";
-                    return WebResponseContent.Instance.Error(response.Message);
+                    double minutesDiff = (DateTime.Now - historyDetail.InsertTime).TotalMinutes;
+                    if (minutesDiff >= 30)
+                    {
+                        return WebResponseContent.Instance.Error($"鏉$爜{request.Barcode}宸叉棤娉曟挙閿�");
+                    }
                 }
 
                 Dt_OutStockLockInfo lockInfo = _outboundLockInfoRepository.QueryFirst(x =>
diff --git "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_SystemService/Sys_UserService.cs" "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_SystemService/Sys_UserService.cs"
index cea2a5f..8c5b533 100644
--- "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_SystemService/Sys_UserService.cs"
+++ "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_SystemService/Sys_UserService.cs"
@@ -18,6 +18,8 @@
 using MailKit.Search;
 using OrderByType = SqlSugar.OrderByType;
 using System.Drawing.Printing;
+using WIDESEA_Model.Models.Config;
+using WIDESEA_IBasicService;
 //using WIDESEA_Core.HostedService;
 
 namespace WIDESEA_SystemService
@@ -28,24 +30,29 @@
         private readonly ICacheService _cacheService;
         private readonly ISys_MenuService _menuService;
         private readonly ISys_RoleService _roleService;
+        private readonly IPasswordPolicyConfigService _passwordPolicyConfigService;
 
         public IRepository<Sys_User> Repository => BaseDal;
 
-        public Sys_UserService(IRepository<Sys_User> repository, IUnitOfWorkManage unitOfWorkManage, ICacheService cacheService, ISys_MenuService menuService, ISys_RoleService roleService) : base(repository)
+        public Sys_UserService(IRepository<Sys_User> repository, IUnitOfWorkManage unitOfWorkManage, ICacheService cacheService, ISys_MenuService menuService, ISys_RoleService roleService, IPasswordPolicyConfigService passwordPolicyConfigService) : base(repository)
         {
             _unitOfWorkManage = unitOfWorkManage;
             _cacheService = cacheService;
             _menuService = menuService;
             _roleService = roleService;
+            _passwordPolicyConfigService = passwordPolicyConfigService;
         }
 
         public WebResponseContent Login(LoginInfo loginInfo)
         {
             WebResponseContent content = new WebResponseContent();
+            PasswordPolicyConfig passwordPolicy = null;
+            string token = null;
             try
             {
                 //BaseDal.QueryFirst(x => x.UserName == loginInfo.UserName);
-
+                passwordPolicy = _passwordPolicyConfigService.GetConfigValue("") ?? new PasswordPolicyConfig();
+            
                 string msg = string.Empty;
 
                 #region 涓存椂浣跨敤
@@ -59,9 +66,51 @@
                 }
                 #endregion
 
-                UserInfo user = BaseDal.QueryFirst(x => x.UserName == loginInfo.UserName && x.UserPwd == loginInfo.Password, x => new UserInfo { HeadImageUrl = x.HeadImageUrl, RoleId = x.RoleId, TenantId = x.TenantId, UserId = x.UserId, UserName = x.UserName, UserTrueName = x.UserTrueName });
+                UserInfo user = BaseDal.QueryFirst(x => x.UserName == loginInfo.UserName && x.UserPwd == loginInfo.Password, x => new UserInfo { HeadImageUrl = x.HeadImageUrl, RoleId = x.RoleId, TenantId = x.TenantId, UserId = x.UserId, UserName = x.UserName, UserTrueName = x.UserTrueName,PwdLastModifyTime = x.LastModifyPwdDate });
                 if (user != null)
                 {
+                    // 3. 瀵嗙爜杩囨湡绛栫暐妫�鏌ワ紙浠呭惎鐢ㄦ椂鎵ц锛�
+                    if (passwordPolicy.EnablePasswordExpire)
+                    {
+                        DateTime pwdModifyTime = user.PwdLastModifyTime ?? DateTime.Now.AddYears(-1);
+                        TimeSpan passwordAge = DateTime.Now - pwdModifyTime;
+                        int daysToExpire = passwordPolicy.PasswordExpireDays - (int)passwordAge.TotalDays;
+
+                        // 瀵嗙爜宸茶繃鏈燂紝寮哄埗鏀瑰瘑
+                        if (daysToExpire <= 0)
+                        {
+                            return WebResponseContent.Instance.Error(
+                                "鎮ㄧ殑瀵嗙爜宸茶繃鏈燂紝璇峰厛淇敼瀵嗙爜鍚庡啀鐧诲綍",
+                                data: new { needChangePwd = true, userId = user.UserId });
+                        }
+
+                        // 瀵嗙爜鍗冲皢杩囨湡锛岀櫥褰曟垚鍔熷苟鎻愰啋
+                        if (daysToExpire <= passwordPolicy.RemindBeforeExpireDays)
+                        {
+                            token = JwtHelper.IssueJwt(new TokenModelJwt()
+                            {
+                                UserId = user.UserId,
+                                RoleId = user.RoleId,
+                                UserName = user.UserName,
+                                TenantId = user.TenantId,
+                            });
+                            App.User.UpdateToke(token, user.UserId);
+
+                            content = WebResponseContent.Instance.OK(
+                                message: $"鎮ㄧ殑瀵嗙爜灏嗗湪{daysToExpire}澶╁悗杩囨湡锛岃鍙婃椂淇敼",
+                                data: new
+                                {
+                                    token,
+                                    userName = user.UserName,
+                                    img = user.HeadImageUrl,
+                                    UserTrueName = user.UserTrueName,
+                                    needChangePwd = false,
+                                    pwdWillExpire = true,
+                                    daysToExpire = daysToExpire
+                                });
+                            return content;
+                        }
+                    }
                     object obj = _menuService.GetMenuActionList(user.RoleId);
                     if (obj is not IEnumerable<object> list)
                     {
@@ -72,7 +121,7 @@
                         return WebResponseContent.Instance.Error("鏃犵櫥褰曟潈闄�");
                     }
 
-                    string token = JwtHelper.IssueJwt(new TokenModelJwt()
+                     token = JwtHelper.IssueJwt(new TokenModelJwt()
                     {
                         UserId = user.UserId,
                         RoleId = user.RoleId,
@@ -84,7 +133,12 @@
                     //if (PermissionDataHostService.UserRoles.FirstOrDefault(x => x.UserId == user.UserId) == null)
                     //    PermissionDataHostService.UserRoles.AddRange(PermissionDataHostService.GetUserRoles(Db, user.UserId));
 
-                    content = WebResponseContent.Instance.OK(data: new { token, userName = user.UserName, img = user.HeadImageUrl, user.UserTrueName });
+                    content = WebResponseContent.Instance.OK(message: "鐧诲叆鎴愬姛,姝e湪璺宠浆椤甸潰", data: new { token, userName = user.UserName, img = user.HeadImageUrl, user.UserTrueName, needChangePwd = false,
+                        pwdWillExpire = false,
+                        daysToExpire = passwordPolicy.EnablePasswordExpire
+                    ? passwordPolicy.PasswordExpireDays - (int)(DateTime.Now - (user.PwdLastModifyTime ?? DateTime.Now)).TotalDays
+                    : 0
+                    });
                 }
                 else
                 {
@@ -151,6 +205,9 @@
             string pwd = "123456";
             string uesrName = saveModel.MainData[nameof(Sys_User.UserName).FirstLetterToLower()].ToString();
             saveModel.MainData[nameof(Sys_User.UserPwd).FirstLetterToLower()] = pwd.EncryptDES(AppSecret.User);
+
+            string pwdModifyTimeField = nameof(Sys_User.LastModifyPwdDate).FirstLetterToLower();
+            saveModel.MainData[pwdModifyTimeField] = DateTime.Now;
 
             WebResponseContent content = base.AddData(saveModel);
             if (content.Status)
@@ -244,6 +301,7 @@
                 Sys_User user = BaseDal.QueryFirst(x => x.UserName == userName);
                 if (user == null) return WebResponseContent.Instance.Error("鐢ㄦ埛涓嶅瓨鍦�");
                 user.UserPwd = password.EncryptDES(AppSecret.User);
+                user.LastModifyPwdDate = DateTime.Now;
                 BaseDal.UpdateData(user);
                 if (App.User.UserId == user.UserId)
                 {
@@ -265,5 +323,63 @@
             }
             return content;
         }
+
+        public WebResponseContent ModifyUserNamePwd(string userName,string oldPwd, string password)
+        {
+            WebResponseContent content = new WebResponseContent();
+            string message = "";
+            // 鍘婚櫎棣栧熬绌烘牸锛岀┖鍊煎鐞�
+            oldPwd = oldPwd?.Trim();
+            password = password?.Trim();
+            userName = userName?.Trim();
+
+            try
+            {
+                // 1. 鍩虹鍙傛暟鏍¢獙
+                if (string.IsNullOrEmpty(userName)) return WebResponseContent.Instance.Error("鐢ㄦ埛鍚嶄笉鑳戒负绌�");
+                if (string.IsNullOrEmpty(oldPwd)) return WebResponseContent.Instance.Error("鏃у瘑鐮佷笉鑳戒负绌�");
+                if (string.IsNullOrEmpty(password)) return WebResponseContent.Instance.Error("鏂板瘑鐮佷笉鑳戒负绌�");
+                if (oldPwd == password) return WebResponseContent.Instance.Error("鏂板瘑鐮佷笉鑳戒笌鏃у瘑鐮佺浉鍚�");
+                if (password.Length < 6) return WebResponseContent.Instance.Error("鏂板瘑鐮侀暱搴︿笉鑳藉皯浜�6浣�");
+
+                // 2. 鑾峰彇鐢ㄦ埛淇℃伅
+                Sys_User user = BaseDal.QueryFirst(x => x.UserName == userName);
+                if (user == null) return WebResponseContent.Instance.Error("鐢ㄦ埛涓嶅瓨鍦�");
+
+                // 3. 鏍¢獙鏃у瘑鐮侊紙瑙e瘑鍚庡姣旓級
+                string decryptedOldPwd = user.UserPwd.DecryptDES(AppSecret.User); // 瑙e瘑鏁版嵁搴撲腑鐨勫瘑鐮�
+                if (decryptedOldPwd != oldPwd) // 瀵规瘮鍘熷鏃у瘑鐮�
+                {
+                    return WebResponseContent.Instance.Error("鏃у瘑鐮佽緭鍏ラ敊璇�");
+                }
+
+                // 4. 鏇存柊瀵嗙爜鍙婄浉鍏充俊鎭�
+                user.UserPwd = password.EncryptDES(AppSecret.User); // 鍔犲瘑鏂板瘑鐮�
+                user.LastModifyPwdDate = DateTime.Now;
+                BaseDal.UpdateData(user);
+
+                // 5. 濡傛灉鏄綋鍓嶇櫥褰曠敤鎴凤紝閲嶆柊鐢熸垚JWT Token骞舵洿鏂扮紦瀛�
+                if (App.User.UserId == user.UserId)
+                {
+                    string token = JwtHelper.IssueJwt(new TokenModelJwt()
+                    {
+                        UserId = user.UserId,
+                        RoleId = user.RoleId,
+                        UserName = user.UserName,
+                        TenantId = user.TenantId,
+                    });
+                    _cacheService.AddOrUpdate(user.UserId.ToString(), token);
+                }
+
+                // 6. 杩斿洖鎴愬姛缁撴灉
+                return content.OK("瀵嗙爜淇敼鎴愬姛");
+            }
+            catch (Exception ex)
+            {
+                message = ex.Message; // 璁板綍寮傚父淇℃伅锛堝缓璁ˉ鍏呮棩蹇楁鏋惰褰曪級
+                content.Error("鏈嶅姟鍣ㄥ嚭浜嗙偣闂,璇风◢鍚庡啀璇�");
+            }
+            return content;
+        }
     }
 }
diff --git "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_SystemService/WIDESEA_SystemService.csproj" "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_SystemService/WIDESEA_SystemService.csproj"
index 37aa4de..0071d3d 100644
--- "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_SystemService/WIDESEA_SystemService.csproj"
+++ "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_SystemService/WIDESEA_SystemService.csproj"
@@ -7,6 +7,7 @@
   </PropertyGroup>
 
   <ItemGroup>
+    <ProjectReference Include="..\WIDESEA_IBasicService\WIDESEA_IBasicService.csproj" />
     <ProjectReference Include="..\WIDESEA_ISystemService\WIDESEA_ISystemService.csproj" />
   </ItemGroup>
 
diff --git "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_TaskInfoService/TaskService.cs" "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_TaskInfoService/TaskService.cs"
index 9b4439a..71e24f6 100644
--- "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_TaskInfoService/TaskService.cs"
+++ "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_TaskInfoService/TaskService.cs"
@@ -604,7 +604,7 @@
                         .Where(x => x.OrderNo == stockLockInfo.OrderNo)
                         .Includes(x => x.Details)
                         .First();
-
+                    string Operator = outboundOrder.Modifier;
                     if (outboundOrder != null)
                     {
                         var allocatInfo =_allocateMaterialInfo.Db.Queryable<Dt_AllocateMaterialInfo>().Where(x => x.OrderNo == outboundOrder.OrderNo).ToList();
@@ -629,7 +629,7 @@
                         }
 
                         // 7. 鍥炶皟MES
-                        string Operator = outboundOrder.Modifier;
+                        
                         HttpResponseResult<MesResponseDTO> httpResponseResult = new HttpResponseResult<MesResponseDTO>();
                         string reqCode = Guid.NewGuid().ToString();
                         string reqTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
@@ -1022,8 +1022,8 @@
                     await Db.Deleteable(task).ExecuteCommandAsync();
                 }
                 Dt_OutboundOrder outboundOrder = _outboundOrderService.Db.Queryable<Dt_OutboundOrder>().Where(x => x.OrderNo == stockInfo.Details.FirstOrDefault().OrderNo).Includes(x=>x.Details).First();
-                
 
+                string Operator = outboundOrder.Modifier;
                 if (outboundOrder != null)
                 {
                     foreach (var item in stockInfo.Details.Where(x => x.OrderNo == outboundOrder.OrderNo).ToList())
@@ -1045,7 +1045,7 @@
                         _outboundOrderService.UpdateData(outboundOrder);
                     }
                 }
-                string Operator = outboundOrder.Modifier;
+               
                 ///鍥炶皟MES
                 HttpResponseResult<MesResponseDTO> httpResponseResult = new HttpResponseResult<MesResponseDTO>();
                 string reqCode = Guid.NewGuid().ToString();
diff --git "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/System/Sys_UserController.cs" "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/System/Sys_UserController.cs"
index 0d42fac..9a7c608 100644
--- "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/System/Sys_UserController.cs"
+++ "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/System/Sys_UserController.cs"
@@ -83,10 +83,16 @@
             return Service.GetCurrentUserInfo();
         }
 
-        [HttpPost, Route("modifyPwd")]
+        [HttpPost, Route("modifyPwd"), AllowAnonymous]
         public IActionResult ModifyPwd(string oldPwd, string newPwd)
         {
             return Json(Service.ModifyPwd(oldPwd, newPwd));
+        }
+
+        [HttpPost, Route("ModifyUserNamePwd"), AllowAnonymous]
+        public IActionResult ModifyUserNamePwd([FromBody] ModifyUserNamePwd modifyUserName)
+        {
+            return Json(Service.ModifyUserNamePwd(modifyUserName.userName, modifyUserName.oldPwd, modifyUserName.newPwd));
         }
 
         [HttpGet, Route("getVierificationCode"), AllowAnonymous]
@@ -154,4 +160,11 @@
         public string name { get; set; }
         public string pwd { get; set; }
     }
+
+    public class ModifyUserNamePwd
+    {
+        public string userName { get; set; }
+        public string oldPwd { get; set; }
+        public string newPwd { get; set; }
+    }
 }
diff --git "a/\351\241\271\347\233\256\350\265\204\346\226\231/\346\216\245\345\217\243\346\226\207\346\241\243/~$S\346\216\245\345\217\243\345\257\271\346\216\245\346\226\207\346\241\243_V1.04.doc" "b/\351\241\271\347\233\256\350\265\204\346\226\231/\346\216\245\345\217\243\346\226\207\346\241\243/~$S\346\216\245\345\217\243\345\257\271\346\216\245\346\226\207\346\241\243_V1.04.doc"
deleted file mode 100644
index fcd42e3..0000000
--- "a/\351\241\271\347\233\256\350\265\204\346\226\231/\346\216\245\345\217\243\346\226\207\346\241\243/~$S\346\216\245\345\217\243\345\257\271\346\216\245\346\226\207\346\241\243_V1.04.doc"
+++ /dev/null
Binary files differ

--
Gitblit v1.9.3