fix: 🧩 代码迁移出错

This commit is contained in:
2025-07-15 10:04:39 +08:00
parent eb32b4309e
commit 12fd39b5af
14 changed files with 489 additions and 22 deletions

View File

@@ -15,6 +15,12 @@ export const getOutStockListApi = (params: Record<string, any>) => {
export const getDetailsApi = (id: any) => {
return http.get<any>(`OutStock/GetInfo/${id}`);
};
export const getTaskDetailsApi = (id: any) => {
return http.get<any>(`OutStockTask/GetInfo/${id}`);
//出库单详情列表
export const getTaskDetailsApi = (params: any) => {
return http.post<any>(`OutStockTask/GetInfoByNo`, params);
};
//修改出库箱信息
export const getEditBoxInfoApi = (params: Record<string, any>) => {
return http.post<any>(`OutStock/EditBoxInfo`, params);
};

View File

@@ -1,11 +1,18 @@
import { defineStore } from "pinia";
// import router from "@/routers";
import { getAuthMenuListApi } from "@/api/modules/login";
import { getFlatMenuList, getShowMenuList, getAllBreadcrumbList, setKeeAliveRoute } from "@/utils";
import { getFlatMenuList, getShowMenuList, getAllBreadcrumbList, setKeeAliveRoute, getBtnsAuthList } from "@/utils";
// import { setRouterControl } from "@/utils/routerControl";
import { boxMarkIndexAdd, subscriptionIndexAdd } from "@/utils/routerControl/constant/index";
// const TYPES_NUMBER: any = {
// boxMarkIndexAdd: 6
// };
//setKeeAliveRoute
export const useAuthStore = defineStore({
export const useAuthStore: any = defineStore({
id: "wms-auth",
state: (): Record<string, any> => ({
state: (): any => ({
// 菜单权限列表
authMenuList: [],
// 当前页面的 router name用来做按钮权限筛选
@@ -19,7 +26,9 @@ export const useAuthStore = defineStore({
// 菜单权限列表 ==> 扁平化之后的一维数组菜单,主要用来添加动态路由
flatMenuListGet: state => getFlatMenuList(state.authMenuList),
// 递归处理后的所有面包屑导航列表
breadcrumbListGet: state => getAllBreadcrumbList(state.authMenuList)
breadcrumbListGet: state => getAllBreadcrumbList(state.authMenuList),
//设置按钮权限
btnsAuthList: state => getBtnsAuthList(state.authMenuList)
},
actions: {
// Get AuthMenuList
@@ -40,6 +49,16 @@ export const useAuthStore = defineStore({
}
}
];
// //判断箱唛列表是否有新增按钮
let btnName: any = this.authMenuList[6]?.children[0]?.children[0]?.children[0]?.name;
let btnName1: any = this.authMenuList[6]?.children[1]?.children[0]?.children[0]?.name;
//如果箱唛列表页面有新增按钮就增加该路由!
if (btnName === "boxMarkIndexAdd") {
this.authMenuList[6]?.children[0]?.children.push(boxMarkIndexAdd);
}
if (btnName1 === "subscriptionIndexAdd") {
this.authMenuList[6]?.children[1]?.children.push(subscriptionIndexAdd);
}
},
// Set RouteName
async setRouteName(name: string) {

View File

@@ -307,3 +307,25 @@ export function findItemNested(enumData: any, callValue: any, value: string, chi
if (current[children]) return findItemNested(current[children], callValue, value, children);
}, null);
}
//递归将按钮取出
function recursiveExtractNames(menuList: any) {
let names: any[] = [];
for (let item of menuList) {
if (item.type === 0) {
names.push(item.name);
}
if (item.children && item.children.length > 0) {
names = names.concat(recursiveExtractNames(item.children));
}
}
return names;
}
//按钮权限
export function getBtnsAuthList(menuList: any) {
let length = menuList.length;
if (!length) {
return [];
}
let obj: any = recursiveExtractNames(menuList);
return obj;
}

View File

@@ -5,4 +5,14 @@ import { integerRexg } from "./integerRexg";
import { unitMultipleInputRexg } from "./unitMultipleInputRexg";
import { numberRexg1 } from "./numberRexg1";
import { numberDecimalSeparatorRexg } from "./numberDecimalSeparatorRexg";
export { numberRexg, inputEnterRexg, productRexg, integerRexg, unitMultipleInputRexg, numberRexg1, numberDecimalSeparatorRexg };
import { numberDecimalSeparatorRexg5 } from "./numberDecimalSeparatorRexg5";
export {
numberRexg,
inputEnterRexg,
productRexg,
integerRexg,
unitMultipleInputRexg,
numberRexg1,
numberDecimalSeparatorRexg,
numberDecimalSeparatorRexg5
};

View File

@@ -7,5 +7,6 @@ export const numberDecimalSeparatorRexg = (value: any) => {
value = value.replace(/[^\d.]/g, ""); // 清除"数字"和"."以外的字符 只能输入数字和小数点
value = value.replace(/\.{2,}/g, "."); // 不能连续输入两个及以上小数点
value = value.replace(".", "$#$").replace(/\./g, "").replace("$#$", "."); // 只保留第一个".", 清除多余的"."
return value;
};

View File

@@ -0,0 +1,22 @@
//只允许输入数字和小数点(小数点后面5位)
export const numberDecimalSeparatorRexg5 = (value: any) => {
if (!value) {
return;
}
// 清除"数字"和"."以外的字符,只能输入数字和小数点
value = value.replace(/[^\d.]/g, "");
// 不能连续输入两个及以上小数点
value = value.replace(/\.{2,}/g, ".");
// 只保留第一个".", 清除多余的"."
value = value.replace(".", "$#$").replace(/\./g, "").replace("$#$", ".");
// 限制小数点后最多 5 位
const parts = value.split(".");
if (parts.length > 1 && parts[1].length > 5) {
parts[1] = parts[1].slice(0, 5);
value = parts.join(".");
}
return value;
};

View File

@@ -0,0 +1,22 @@
export const boxMarkIndexAdd = {
id: 938,
pid: 936,
module: 25,
title: "箱唛详情",
name: "boxMarkDetails",
path: "/setUp/boxMark/details",
component: "/setUp/boxMark/details",
icon: "",
redirect: "",
sort: 1,
type: 1,
hidden: true,
closed: false,
disable: false,
children: [],
meta: {
title: "箱唛详情",
icon: "",
isKeepAlive: true
}
};

View File

@@ -0,0 +1,3 @@
import { boxMarkIndexAdd } from "./boxMark";
import { subscriptionIndexAdd } from "./subscription";
export { boxMarkIndexAdd, subscriptionIndexAdd };

View File

@@ -0,0 +1,21 @@
export const subscriptionIndexAdd = {
id: 949,
pid: 947,
module: 25,
title: "订阅详情",
name: "subscriptionDetails",
path: "/setUp/subscription/details",
component: "/setUp/subscription/details",
icon: "",
redirect: "",
sort: 1,
type: 1,
hidden: true,
closed: false,
disable: false,
children: [],
meta: {
title: "订阅详情",
icon: ""
}
};

View File

@@ -0,0 +1,13 @@
import { boxMarkIndexAdd } from "./constant/index";
import { useAuthStore } from "@/stores/modules/auth";
const authStore = useAuthStore();
const ROUTERS: any = {
boxMarkIndexAdd
};
const TYPES_NUMBER: any = {
boxMarkIndexAdd: 6
};
export const setRouterControl = (type: string) => {
let authMenuListIndex = TYPES_NUMBER[type];
authStore.authMenuList[authMenuListIndex].children[0].children.push(ROUTERS[type]);
};

View File

@@ -1,9 +1,41 @@
//明细信息
export const COLUMNS = [
{
label: "",
align: "center",
prop: "indexNumber",
disabled: false,
width: "60px"
},
{
label: "箱号",
prop: "boxBillNo",
disabled: false
disabled: false,
width: "200px"
},
{
label: "长CM",
prop: "boxLength",
disabled: false,
width: "140px"
},
{
label: "宽CM",
prop: "boxWide",
disabled: false,
width: "140px"
},
{
label: "高CM",
prop: "boxHigh",
disabled: false,
width: "140px"
},
{
label: "重量KG",
prop: "boxWeight",
disabled: false,
width: "140px"
},
{
label: "规格型号",
@@ -42,6 +74,7 @@ export const COLUMNS = [
{
label: "出库时间",
prop: "createTime",
disabled: false
disabled: false,
width: "200px"
}
];

View File

@@ -21,12 +21,20 @@
<el-tabs v-model="activeName" class="demo-tabs" id="myElement">
<el-tab-pane label="箱信息" name="outboundTaskListDetails">
<div
:class="datas.isBtn ? 'edit-btn-box1' : 'edit-btn-box'"
@click="handleEditClick"
v-if="authStore.btnsAuthList.includes('outboundTaskListDetailsEdit')"
>
编辑
</div>
<el-table :data="datas.ruleForm.details" style="width: 100%" :height="datas.tableHeight" border>
<el-table-column
:show-overflow-tooltip="true"
:prop="item.prop"
:align="item.align ?? 'center'"
:label="item.label"
:width="item.width ? item.width : ''"
:width="item.width ? item.width : 120"
v-for="(item, index) in datas.columns"
:key="index"
/>
@@ -34,6 +42,52 @@
</el-tab-pane>
</el-tabs>
</div>
<!-- 编辑窗口 -->
<el-dialog v-model="datas.isEdit" title="编辑" width="900" align-center @close="handleDiaLog">
<div>
<div style="display: flex; padding: 10px">
<div style="flex: 2">箱号</div>
<div style="flex: 1; padding-left: 20px">长CM</div>
<div style="flex: 1; padding-left: 20px">宽CM</div>
<div style="flex: 1; padding-left: 20px">高CM</div>
<div style="flex: 1; padding-left: 20px">重量KG</div>
<div style="flex: 4; padding-left: 20px">规格型号</div>
</div>
<div style="max-height: 200px; overflow: auto">
<div v-for="item in datas.editList.details" :key="item.id" style="display: flex; padding: 0 10px 10px">
<el-input v-model="item.boxBillNo" disabled style="flex: 2" />
<el-input
v-model="item.boxLength"
style="flex: 1; padding-left: 20px"
@input="handleInput(item, 'boxLength')"
/>
<el-input
v-model="item.boxWide"
style="flex: 1; padding-left: 20px"
@input="handleInput(item, 'boxWide')"
/>
<el-input
v-model="item.boxHigh"
style="flex: 1; padding-left: 20px"
@input="handleInput(item, 'boxHigh')"
/>
<el-input
v-model="item.boxWeight"
style="flex: 1; padding-left: 20px"
@input="handleInput(item, 'boxWeight')"
/>
<el-input v-model="item.specifications" style="flex: 4; padding-left: 20px" disabled />
</div>
</div>
</div>
<template #footer>
<div class="dialog-footer">
<el-button @click="datas.isEdit = false">取消</el-button>
<el-button type="primary" v-throttle="handleEditCommit"> 确认 </el-button>
</div>
</template>
</el-dialog>
</div>
</template>
@@ -41,8 +95,12 @@
import DetailsSearch from "@/components/DetailsSearch/index.vue";
import { FORMDATA, RULEFORM, COLUMNS } from "./constant/details/index";
import { cloneDeep } from "lodash-es";
import { getTaskDetailsApi } from "@/api/modules/deliveryAndOutbound";
import { getTaskDetailsApi, getEditBoxInfoApi } from "@/api/modules/deliveryAndOutbound";
import { useMsg } from "@/hooks/useMsg";
import { numberDecimalSeparatorRexg5 } from "@/utils/rexg/index";
import { useAuthStore } from "@/stores/modules/auth";
const authStore = useAuthStore();
console.log(authStore, "============authStore=============");
let labelWidth = "107px";
const tableRef = ref<any>(null);
@@ -52,39 +110,95 @@ const datas = reactive<any>({
columns: COLUMNS, //明细信息列表配置项
ruleForm: cloneDeep(RULEFORM), // 表单
formData: cloneDeep(FORMDATA), //表头配置项
tableHeight: 0
tableHeight: 0, //表格高度
isBtn: false, //控制编辑按钮显示
isEdit: false, //控制编辑弹窗
editList: [], //表格编辑数据
pageSize: 1000, //默认请求1000条数据(现在一个单最多300条,需做分页优化,暂无该需求)
pageNo: 1
});
const $route = useRoute();
let activeName = ref<any>("outboundTaskListDetails");
let formActiveName = ref<any>("infoBasic");
//获取详情
const getDetails = async (id: any) => {
if (!id) {
const getDetails = async (billNo: any) => {
if (!billNo) {
return false;
}
const result = await getTaskDetailsApi(id);
console.log("12323");
const result = await getTaskDetailsApi({
billNo,
pageSize: datas.pageSize,
pageNo: datas.pageNo
});
if (result.status === 200) {
const { data } = result;
datas.ruleForm = data;
datas.ruleForm = cloneDeep(data);
datas.isBtn = !datas.ruleForm.details.length;
}
};
getDetails($route.query.id);
getDetails($route.query.billNo);
//动态计算表格高度
const handleResize = () => {
nextTick(() => {
datas.tableHeight = tableRef.value.clientHeight - 280;
datas.tableHeight = tableRef.value.clientHeight - 350;
if (datas.tableHeight <= 92) {
datas.tableHeight = 92;
}
});
};
//限制input输入
const handleInput = (item: any, type: any) => {
item[type] = numberDecimalSeparatorRexg5(item[type]);
};
//窗口关闭
const handleDiaLog = () => {
datas.editList = [];
};
//编辑
const handleEditClick = () => {
if (datas.isBtn) {
return;
}
//赋值
datas.editList = cloneDeep(datas.ruleForm);
//打开编辑窗口
datas.isEdit = true;
};
//编辑确认
const handleEditCommit = async () => {
let params: any = [];
datas.editList.details.forEach((item: any) => {
params.push({
boxHigh: item.boxHigh,
boxLength: item.boxLength,
boxWeight: item.boxWeight,
boxWide: item.boxWide,
outStockBoxDetailsId: item.outStockBoxDetailsId,
outStockId: item.outStockId
});
});
const result = await getEditBoxInfoApi(params);
const { isSuccess, message } = result;
if (result.status === 200) {
if (isSuccess) {
useMsg("success", "数据修改成功 !");
getDetails($route.query.billNo);
datas.isEdit = false;
datas.editList = [];
} else {
useMsg("error", message);
}
} else {
useMsg("error", message);
}
};
onMounted(() => {
handleResize();
});
// 详情
onActivated(() => {
getDetails($route.query.id);
window.addEventListener("resize", handleResize);
});
onDeactivated(() => {
@@ -94,3 +208,52 @@ onBeforeUnmount(() => {
window.removeEventListener("resize", handleResize);
});
</script>
<style scoped lang="scss">
.edit-btn-box {
box-sizing: border-box;
display: flex;
align-items: center;
justify-content: center;
width: 50px;
height: 30px;
margin-right: 12px;
margin-bottom: 12px;
font-size: 12px;
line-height: 1;
color: #ffffff;
cursor: pointer;
background: #4178d5;
border-radius: 6px;
}
.edit-btn-box:hover {
color: #ffffff;
background: #7aa1e2;
border: 1px solid rgb(65 120 213 / 10%);
}
.edit-btn-box1 {
box-sizing: border-box;
display: flex;
align-items: center;
justify-content: center;
width: 50px;
height: 30px;
margin-right: 12px;
margin-bottom: 12px;
font-size: 12px;
line-height: 1;
color: #ffffff;
cursor: not-allowed;
background: #4178d5;
border-radius: 6px;
}
:deep(.el-dialog__body) {
padding: 10px 10px 18px;
font-size: 14px;
/* color: red; */
text-align: center;
}
:deep(.el-dialog__title) {
font-weight: bold;
}
</style>

View File

@@ -126,7 +126,7 @@ const handleToDetail = (row: any) => {
$router.push({
path: "/deliveryAndOutbound/outboundTaskList/details",
query: {
id: row.id
billNo: row.billNo
}
});
};

132
src/views/login/index5.vue Normal file
View File

@@ -0,0 +1,132 @@
<template>
<el-main></el-main>
</template>
<script setup lang="ts">
//useRouter
import { useRoute } from "vue-router";
import { useMsg } from "@/hooks/useMsg";
//登录请求接口
import { loginApi } from "@/api/modules/login";
//全局状态
import { getGlobalStatusApi } from "@/api/modules/global";
//全局仓库
import { getStockApi } from "@/api/modules/global";
//用户信息存储
import { useUserStore } from "@/stores/modules/user";
import { usePathUrl } from "@/hooks/usePathUrl";
//全局状态
import { useStatusStore } from "@/stores/modules/status";
const userStore = useUserStore();
const statusStore = useStatusStore();
// 路由
const $route = useRoute();
const $router = useRouter();
const getGlobalStatus = async () => {
const result = await getGlobalStatusApi();
if (result.status === 200) {
const { data } = result;
//设置全局状态
statusStore.setGlobalStatus(data);
}
};
const getStock = async () => {
const result = await getStockApi();
if (result.status === 200) {
const { data } = result;
data.forEach((item: any) => {
item.code = item.code + "_" + "$" + item.erpOrgCode;
});
//设置全局仓库
userStore.setWarehouse(data);
}
};
const getUcOnline = (phpToken: any, refreshToken: any) => {
let httpUrl = import.meta.env.VITE_SINGLE_URL + "uc/online";
fetch(httpUrl, {
method: "POST",
credentials: "include",
keepalive: true,
headers: {
Authorization: phpToken,
"Refresh-Authorization": refreshToken
}
});
};
const getUcOffline = (redirectUrl: any) => {
let httpUrl = import.meta.env.VITE_SINGLE_URL + "uc/offline";
fetch(httpUrl, {
method: "POST",
credentials: "include",
keepalive: true,
headers: {
Authorization: userStore.phpToken,
"Refresh-Authorization": userStore.refreshToken
}
})
.then((res: any) => {
if (res.status === 200) {
useMsg("success", "退出登录成功 ");
setTimeout(() => {
location.href = redirectUrl;
}, 300);
}
})
.catch(() => {
useMsg("error", "退出登录失败,请稍后再试 ");
});
};
// 设置用户数据
const setUserData = (data: any) => {
// 组装token
let newUserToken = data.tokenInfo.tokenType + " " + data.tokenInfo.token;
let RefreshToken = data.tokenInfo.tokenType + " " + data.tokenInfo.refreshToken;
let phpToken = data.tokenInfo.tokenType + " " + data.tokenInfo.phpToken;
// 设置token
userStore.setToken(newUserToken);
userStore.setRefreshToken(RefreshToken);
userStore.setPhpToken(phpToken);
// 设置用户信息
userStore.setUserInfo(data.userInfo);
// 设置组织id
userStore.setOrgId(data.userInfo.orgId);
getUcOnline(phpToken, RefreshToken);
getGlobalStatus();
getStock();
//跳转
setTimeout(() => {
$router.push({ path: "/" });
}, 500);
};
// 登录
const loginHttp = async (code: any) => {
const result: Record<string, any> = await loginApi({ code: code });
if (result.status === 200) {
setUserData(result.data);
} else {
getUcOffline(usePathUrl());
}
};
// 登录前的判断
const login = () => {
const { code } = $route.query;
// 没有code直接跳转到登录页
if (!code) {
getUcOffline(usePathUrl());
return;
}
// 有code就登录请求
loginHttp(code);
};
login();
</script>
<style lang="scss">
.el-main {
height: 100vh;
}
</style>