fix: 第一版普遍修复完成。

This commit is contained in:
c
2026-03-21 15:56:53 +08:00
parent d88701f4ee
commit cc87985576
17 changed files with 218 additions and 93 deletions

View File

@@ -1,5 +1,5 @@
# 线上环境接口地址 # 线上环境接口地址
VITE_API_URL = "/pro" VITE_API_URL = "/api"
# 静态文件获取根路径 # 静态文件获取根路径
VITE_PUBLIC_PATH = "/" VITE_PUBLIC_PATH = "/"

View File

@@ -1,5 +1,5 @@
{ {
"name": "teek-design-vue3-template", "name": "erp-frontend",
"version": "2.0.0", "version": "2.0.0",
"private": true, "private": true,
"description": "牛安后台管理系统", "description": "牛安后台管理系统",

View File

@@ -21,7 +21,7 @@ export const UserService = {
}, },
checkIsLogined() { checkIsLogined() {
return get("/open/check-login"); return get("/auth/check-login");
}, },
/** /**
@@ -29,12 +29,12 @@ export const UserService = {
* 用于前端页面刷新后检测当前token是否有效 * 用于前端页面刷新后检测当前token是否有效
*/ */
checkLogin() { checkLogin() {
return get("/open/check-login"); return get("/auth/check-login");
}, },
// 获取用户信息 // 获取用户信息
getUserInfo() { getUserInfo() {
return get("/auth/getUserInfo"); return get("/auth/check-login");
}, },
getDynamicRouter() { getDynamicRouter() {

View File

@@ -2,6 +2,7 @@ import { useUserStore } from "@/pinia";
import axios from "axios"; import axios from "axios";
import type { AxiosInstance, AxiosResponse, InternalAxiosRequestConfig } from "axios"; import type { AxiosInstance, AxiosResponse, InternalAxiosRequestConfig } from "axios";
import { ElMessage } from "element-plus"; import { ElMessage } from "element-plus";
import { $t } from "@/common/languages";
// 创建 axios 实例 // 创建 axios 实例
const service: AxiosInstance = axios.create({ const service: AxiosInstance = axios.create({
@@ -24,7 +25,7 @@ service.interceptors.request.use(
return config; return config;
}, },
error => { error => {
ElMessage.error("请求发送失败"); ElMessage.error($t("_http.request_failed"));
return Promise.reject(error); return Promise.reject(error);
} }
); );
@@ -38,31 +39,34 @@ service.interceptors.response.use(
// 通常 code === 0 表示成功 // 通常 code === 0 表示成功
if (res.code === 0) { if (res.code === 0) {
return res as any; // 直接返回业务数据 return res as any; // 直接返回业务数据
} else if (res.code === 3) {
ElMessage.error(res.msg || $t("_http.invalid_credentials"));
return Promise.reject(new Error(res.msg || $t("_http.invalid_credentials")));
} else { } else {
ElMessage.error(res.msg || "请求失败"); ElMessage.error(res.msg || $t("_http.request_error"));
return Promise.reject(new Error(res.msg || "Error")); return Promise.reject(new Error(res.msg || "Error"));
} }
}, },
error => { error => {
// 处理网络错误或 HTTP 状态码非 2xx 的情况 // 处理网络错误或 HTTP 状态码非 2xx 的情况
let message = "网络异常"; let message = $t("_http.network_error");
const { isLogined } = storeToRefs(useUserStore()); const { isLogined } = storeToRefs(useUserStore());
if (error.response) { if (error.response) {
const status = error.response.status; const status = error.response.status;
switch (status) { switch (status) {
case 401: case 401:
message = "未登录或会话已过期,请重新登录"; message = $t("_http.unauthorized");
isLogined.value = false; isLogined.value = false;
useRouter().push("/login"); useRouter().push("/login");
break; break;
case 403: case 403:
message = "权限不足"; message = $t("_http.forbidden");
break; break;
case 500: case 500:
message = "服务器内部错误"; message = $t("_http.server_error");
break; break;
default: default:
message = `请求失败 ( $ {status})`; message = $t("_http.request_failed_status", { status });
} }
} }
ElMessage.error(message); ElMessage.error(message);

View File

@@ -729,6 +729,12 @@ export default {
generate_order_error: "Generate Failed", generate_order_error: "Generate Failed",
vendor_priority_tip: "Priority", vendor_priority_tip: "Priority",
}, },
purchase_plan_item: {
input_partNumber: "Please enter part number",
input_purchaseCount: "Please enter plan count",
input_price: "Please enter price",
input_currentCount: "Please enter current count",
},
purchaseorder: { purchaseorder: {
delete_message: "Delete Order", delete_message: "Delete Order",
part_number_not_exists: "Part number does not exist", part_number_not_exists: "Part number does not exist",
@@ -917,9 +923,11 @@ export default {
tableTitle: "Purchase Details", tableTitle: "Purchase Details",
templateFileName: "Purchase Plan Template", templateFileName: "Purchase Plan Template",
}, },
purchaseorder: { purchase_order: {
add: "Add Purchase Order", add: "Add Purchase Order",
edit: "Edit Purchase Order", edit: "Edit Purchase Order",
inbound: "Purchase Inbound",
qrcode: "Print QR Code",
showItem: "Order Items", showItem: "Order Items",
baseTitle: "Purchase Order Basic Info", baseTitle: "Purchase Order Basic Info",
tableTitle: "Order Details", tableTitle: "Order Details",
@@ -1235,5 +1243,16 @@ export default {
_status: { _status: {
in_progress: "In Progress", in_progress: "In Progress",
completed: "Completed", completed: "Completed",
receipting: "Receipting",
},
_http: {
request_failed: "Request failed",
invalid_credentials: "Invalid username or password",
request_error: "Request error",
network_error: "Network error",
unauthorized: "Not logged in or session expired, please log in again",
forbidden: "Permission denied",
server_error: "Server internal error",
request_failed_status: "Request failed ({status})",
}, },
}; };

View File

@@ -760,6 +760,12 @@ export default {
generate_order_error: "生成采购订单失败", generate_order_error: "生成采购订单失败",
vendor_priority_tip: "优先", vendor_priority_tip: "优先",
}, },
purchase_plan_item: {
input_partNumber: "请输入物料编号",
input_purchaseCount: "请输入计划数量",
input_price: "请输入单价",
input_currentCount: "请输入本次采购数量",
},
purchase_order: { purchase_order: {
delete_message: "删除采购订单", delete_message: "删除采购订单",
input_vendorName: "请选择供应商", input_vendorName: "请选择供应商",
@@ -1008,6 +1014,9 @@ export default {
add: "新建采购计划", add: "新建采购计划",
edit: "编辑采购计划", edit: "编辑采购计划",
generateOrder: "生成采购订单", generateOrder: "生成采购订单",
showItem: "采购明细",
baseTitle: "采购计划基本信息",
tableTitle: "采购明细",
model: "型号", model: "型号",
defaultVendor: "默认供应商", defaultVendor: "默认供应商",
demandQuantity: "需求量", demandQuantity: "需求量",
@@ -1023,6 +1032,7 @@ export default {
edit: "编辑采购订单", edit: "编辑采购订单",
inbound: "采购入库", inbound: "采购入库",
qrcode: "二维码打印", qrcode: "二维码打印",
showItem: "采购明细",
baseTitle: "采购订单基本信息", baseTitle: "采购订单基本信息",
tableTitle: "采购明细", tableTitle: "采购明细",
templateFileName: "采购订单模板", templateFileName: "采购订单模板",
@@ -1337,5 +1347,16 @@ export default {
_status: { _status: {
in_progress: "入库中", in_progress: "入库中",
completed: "已完成", completed: "已完成",
receipting: "入库中",
},
_http: {
request_failed: "请求发送失败",
invalid_credentials: "用户名或密码错误",
request_error: "请求失败",
network_error: "网络异常",
unauthorized: "未登录或会话已过期,请重新登录",
forbidden: "权限不足",
server_error: "服务器内部错误",
request_failed_status: "请求失败 ({status})",
}, },
}; };

View File

@@ -218,6 +218,7 @@ watch(visible, newVal => {
width="450px" width="450px"
:close-on-click-modal="false" :close-on-click-modal="false"
:close-on-press-escape="false" :close-on-press-escape="false"
:lock-scroll="false"
> >
<div v-loading="loading" class="qrcode-container"> <div v-loading="loading" class="qrcode-container">
<div v-if="props.qrCodeList.length > 0" class="qrcode-list-container"> <div v-if="props.qrCodeList.length > 0" class="qrcode-list-container">

View File

@@ -59,33 +59,34 @@ export const useUserStore = defineStore(
}; };
const getUserInfo = async () => { const getUserInfo = async () => {
// 模拟获取用户信息 return await UserService.getUserInfo().then(res => {
// return await UserService.getUserInfo().then(res => { setRoles(res.data.roles);
// setRoles(res.data.roles); setUserInfo(res.data.userInfo);
// setUserInfo(res.data); return res.data.userInfo;
// return res.data; });
// return {};
// const userInfo = await new Promise<UserInfo>(resolve => {
// setTimeout(() => {
// resolve({
// userId: "v10001",
// username: "Admin",
// sex: "保密",
// signature: "这个人很懒,什么都没有写",
// email: "1234567890@qq.com",
// phone: "1234567890",
// avatar: "https://cdn.jsdelivr.net/gh/Kele-Bingtang/static/user/avatar1.png",
// roles: ["admin"],
// job: "开发工程师",
// dept: "Teek 云科技技术部 - 智能全栈科",
// registerTime: "2022-10-01 19:07:27",
// });
// }, 500);
// }); // });
const userInfo = await new Promise<UserInfo>(resolve => { // setUserInfo(userInfo);
setTimeout(() => { // return userInfo;
resolve({
userId: "v10001",
username: "Admin",
sex: "保密",
signature: "这个人很懒,什么都没有写",
email: "1234567890@qq.com",
phone: "1234567890",
avatar: "https://cdn.jsdelivr.net/gh/Kele-Bingtang/static/user/avatar1.png",
roles: ["admin"],
job: "开发工程师",
dept: "Teek 云科技技术部 - 智能全栈科",
registerTime: "2022-10-01 19:07:27",
});
}, 500);
});
setUserInfo(userInfo);
return userInfo;
}; };
/** /**

View File

@@ -53,16 +53,16 @@ const login = () => {
loading.value = true; loading.value = true;
try { try {
// 执行登录 // 执行登录
await userStore.login({ ...loginForm }); const result = await userStore.login({ ...loginForm });
// if (!result) { if (!result) {
// ElNotification({ ElNotification({
// title: getTimeState(), title: getTimeState(),
// message: "登录失败,用户名或密码错误", message: "登录失败,用户名或密码错误",
// type: "success", type: "success",
// duration: 3000, duration: 3000,
// }); });
// return; return;
// } }
// 跳转到首页或者 URL 携带的 redirect 页(优先级高) // 跳转到首页或者 URL 携带的 redirect 页(优先级高)
let path = HOME_URL; let path = HOME_URL;

View File

@@ -130,7 +130,7 @@ const operateButtonClick = (eventName: string, row: any) => {
const mappingConfig: FieldMappingConfig = { const mappingConfig: FieldMappingConfig = {
partNumber: { partNumber: {
sourceKey: ["商品编号", "partNumber"], sourceKey: ["编号", "物料编号", "商品编号", "partNumber"],
header: $t("_prop.production.bom_item.partNumber"), header: $t("_prop.production.bom_item.partNumber"),
width: 20, width: 20,
defaultValue: "", defaultValue: "",

View File

@@ -238,6 +238,8 @@ const authShowFunc = (row: any, button: globalThis.ButtonProp) => {
if (row.status === 1 && button.eventName === "approve") return false; if (row.status === 1 && button.eventName === "approve") return false;
// 已审核后不能编辑和删除 // 已审核后不能编辑和删除
if (row.status === 1 && (button.eventName === "edit" || button.eventName === "remove")) return false; if (row.status === 1 && (button.eventName === "edit" || button.eventName === "remove")) return false;
// 退料按钮只在已审核状态下展示
if (button.eventName === "productionReturn" && row.status !== 1) return false;
return true; return true;
}; };

View File

@@ -7,6 +7,7 @@ import { $t } from "@/common/languages";
import { ElMessage, ElMessageBox, type FormInstance, type FormItemRule, type FormRules } from "element-plus"; import { ElMessage, ElMessageBox, type FormInstance, type FormItemRule, type FormRules } from "element-plus";
import BaseFormWithTable from "@/components/base/base-form-with-table/BaseFormWithTable.vue"; import BaseFormWithTable from "@/components/base/base-form-with-table/BaseFormWithTable.vue";
import BaseTableForm from "@/components/base/base-table-form/BaseTableForm.vue"; import BaseTableForm from "@/components/base/base-table-form/BaseTableForm.vue";
import BaseItemDialog from "@/components/base/base-item-dialog/BaseItemDialog.vue";
import ExpandablePageableTable from "@/components/base/expandable-pageable-table/ExpandablePageableTable.vue"; import ExpandablePageableTable from "@/components/base/expandable-pageable-table/ExpandablePageableTable.vue";
import BaseSelect from "@/components/base/base-select/BaseSelect.vue"; import BaseSelect from "@/components/base/base-select/BaseSelect.vue";
import QrCodeDialog from "@/components/base/base-qrcode/QrCodeDialog.vue"; import QrCodeDialog from "@/components/base/base-qrcode/QrCodeDialog.vue";
@@ -29,12 +30,14 @@ const partNumberExistsUrl = "/warehouse/warehouseitem/existsWarehouseItem";
const searchers = [ const searchers = [
{ name: "searchCode", type: "text" as const, placeholder: $t("_prop.purchase.purchase_order.searchCode") }, { name: "searchCode", type: "text" as const, placeholder: $t("_prop.purchase.purchase_order.searchCode") },
{ name: "partNumber", type: "text" as const, placeholder: $t("_prop.purchase.purchase_order_item.partNumber") },
]; ];
const getFormStatusLabel = (status: number) => { const getFormStatusLabel = (status: number) => {
const labels: Record<number, string> = { const labels: Record<number, string> = {
0: $t("_status.in_progress"), 0: $t("_status.in_progress"),
4: $t("_status.completed"), 4: $t("_status.completed"),
5: $t("_status.receipting"),
}; };
return labels[status] ?? String(status); return labels[status] ?? String(status);
}; };
@@ -60,7 +63,7 @@ const validatePartNumber = (rule: any, value: string, callback: (error?: Error)
}; };
const rules = reactive<FormRules>({ const rules = reactive<FormRules>({
vendorName: [{ required: true, message: $t("_message.purchase.purchase_order.input_vendorName"), trigger: "blur" }], vendorNo: [{ required: true, message: $t("_message.purchase.purchase_order.select_vendor"), trigger: "change" }],
partNumber: [ partNumber: [
{ {
required: true, required: true,
@@ -97,7 +100,7 @@ const inboundForm = reactive({
orderCode: "", orderCode: "",
vendorName: "", vendorName: "",
formCode: "", formCode: "",
storeNo: null as number, storeNo: null as number | null,
storeName: "", storeName: "",
formMark: "", formMark: "",
items: [] as any[], items: [] as any[],
@@ -106,6 +109,10 @@ const inboundForm = reactive({
const qrCodeVisible = ref(false); const qrCodeVisible = ref(false);
const qrCodeData = ref<any[]>([]); const qrCodeData = ref<any[]>([]);
const showItemVisible = ref(false);
const showItemData = ref<any[]>([]);
const showItemRow = ref<any>(null);
const mappingConfig: FieldMappingConfig = { const mappingConfig: FieldMappingConfig = {
partNumber: { partNumber: {
sourceKey: "物料编号", sourceKey: "物料编号",
@@ -266,6 +273,11 @@ const showQrCode = async (row: any) => {
} }
}; };
const showItem = (row: any) => {
showItemRow.value = row;
showItemVisible.value = true;
};
const submit = (formData: any, formRef: FormInstance | undefined) => { const submit = (formData: any, formRef: FormInstance | undefined) => {
if (formRef !== undefined) { if (formRef !== undefined) {
formRef.validate(valid => { formRef.validate(valid => {
@@ -307,6 +319,9 @@ const operateButtonClick = (eventName: string, row: any) => {
case "printQrCode": case "printQrCode":
showQrCode(row); showQrCode(row);
break; break;
case "showItem":
showItem(row);
break;
} }
}; };
@@ -368,6 +383,7 @@ const getFormStatusTagType = (code: number | null): string => {
:item-url="getItemsUrl" :item-url="getItemsUrl"
item-id-key="id" item-id-key="id"
item-id-name="orderId" item-id-name="orderId"
item-field-name="items"
> >
<template #tool-button> <template #tool-button>
<DefaultToolButton @top-button-click="topButtonClick" /> <DefaultToolButton @top-button-click="topButtonClick" />
@@ -434,9 +450,9 @@ const getFormStatusTagType = (code: number | null): string => {
<el-form-item prop="id" v-if="false"><el-input v-model="form.id" /></el-form-item> <el-form-item prop="id" v-if="false"><el-input v-model="form.id" /></el-form-item>
<el-row :gutter="20"> <el-row :gutter="20">
<el-col :span="8"> <el-col :span="8">
<el-form-item :label="$t('_prop.purchase.purchase_order.vendorName')" prop="vendorName"> <el-form-item :label="$t('_prop.purchase.purchase_order.vendorName')" prop="vendorNo">
<BaseSelect <BaseSelect
v-model="form.vendorName" v-model="form.vendorNo"
:url="getVendorSelectListUrl" :url="getVendorSelectListUrl"
ref="vendorSelectRef" ref="vendorSelectRef"
:placeholder="$t('_message.purchase.purchase_order.select_vendor')" :placeholder="$t('_message.purchase.purchase_order.select_vendor')"
@@ -580,4 +596,39 @@ const getFormStatusTagType = (code: number | null): string => {
:qr-code-list="qrCodeData" :qr-code-list="qrCodeData"
:qr-code-size="200" :qr-code-size="200"
/> />
<BaseItemDialog
:title="$t('_title.purchase.purchase_order.showItem')"
v-model:visible="showItemVisible"
:url="getItemsUrl"
parent-param-name="orderId"
:parent-param-value="showItemRow?.id"
>
<template #columns>
<el-table-column :label="$t('_prop.purchase.purchase_order_item.partNumber')" prop="partNumber" width="150" />
<el-table-column :label="$t('_prop.purchase.purchase_order_item.productSpecs')" prop="productSpecs" width="150" />
<el-table-column
:label="$t('_prop.purchase.purchase_order_item.purchaseCount')"
prop="purchaseCount"
width="100"
/>
<el-table-column :label="$t('_prop.purchase.purchase_order_item.receiptCount')" prop="receiptCount" width="100" />
<el-table-column
:label="$t('_prop.purchase.purchase_order_item.remainingCount')"
prop="remainingCount"
width="100"
/>
<el-table-column :label="$t('_prop.purchase.purchase_order_item.price')" prop="price" width="100">
<template #default="{ row }">
{{ new Decimal(row.price ?? 0).toFixed(2) }}
</template>
</el-table-column>
<el-table-column :label="$t('_prop.purchase.purchase_order_item.totalPrice')" prop="totalPrice" width="120">
<template #default="{ row }">
{{ new Decimal(row.totalPrice ?? 0).toFixed(2) }}
</template>
</el-table-column>
<el-table-column :label="$t('_prop.purchase.purchase_order_item.purchaseMark')" prop="purchaseMark" />
</template>
</BaseItemDialog>
</template> </template>

View File

@@ -30,6 +30,7 @@ const removeUrl = "/purchase/purchaseplan/deletePurchasePlan";
const getItemsUrl = "/purchase/purchaseplan/getPurchasePlanItemsWithVendorSuggestions"; const getItemsUrl = "/purchase/purchaseplan/getPurchasePlanItemsWithVendorSuggestions";
const generateOrderUrl = "/purchase/purchaseplan/generatePurchaseOrder"; const generateOrderUrl = "/purchase/purchaseplan/generatePurchaseOrder";
const getItemUrl = "/purchase/purchaseplan/getPurchasePlanItems"; const getItemUrl = "/purchase/purchaseplan/getPurchasePlanItems";
const partNumberExistsUrl = "/warehouse/warehouseitem/existsWarehouseItem";
const searchers = [ const searchers = [
{ name: "searchCode", type: "text" as const, placeholder: $t("_prop.purchase.purchase_plan.searchCode") }, { name: "searchCode", type: "text" as const, placeholder: $t("_prop.purchase.purchase_plan.searchCode") },
]; ];
@@ -53,6 +54,28 @@ const rules = reactive<FormRules>({
], ],
}); });
const itemArrayName = "planItems"; const itemArrayName = "planItems";
/**
* 验证物料编号是否存在
*/
const validatePartNumber = (rule: any, value: string, callback: (error?: Error) => void) => {
if (!value) {
callback(new Error($t("_message.purchase.purchase_plan_item.input_partNumber")));
return;
}
get(partNumberExistsUrl, { partNumber: value })
.then(res => {
if (res.data === true) {
callback();
} else {
callback(new Error($t("_message.warehouse.warehouse_item.not_exist_partNumber")));
}
})
.catch(() => {
callback();
});
};
/** /**
* 基本不变通用变量 * 基本不变通用变量
*/ */
@@ -445,8 +468,6 @@ const mappingConfig: FieldMappingConfig = {
<BaseSelect <BaseSelect
v-model="form.vendorId" v-model="form.vendorId"
:url="'/sys/vendor/getVendorList'" :url="'/sys/vendor/getVendorList'"
name="id"
label="vendorName"
:placeholder="$t('_message.purchase.purchase_plan.select_vendor')" :placeholder="$t('_message.purchase.purchase_plan.select_vendor')"
/> />
</el-form-item> </el-form-item>
@@ -455,9 +476,7 @@ const mappingConfig: FieldMappingConfig = {
<el-form-item :label="$t('_prop.purchase.purchase_plan.storeName')" prop="storeNo"> <el-form-item :label="$t('_prop.purchase.purchase_plan.storeName')" prop="storeNo">
<BaseSelect <BaseSelect
v-model="form.storeNo" v-model="form.storeNo"
:url="'/warehouse/store/getStoreList'" :url="'/warehouse/warehouse/getWarehouseSelectList'"
name="storeNo"
label="storeName"
:placeholder="$t('_message.purchase.purchase_plan.select_store')" :placeholder="$t('_message.purchase.purchase_plan.select_store')"
/> />
</el-form-item> </el-form-item>
@@ -477,9 +496,7 @@ const mappingConfig: FieldMappingConfig = {
<template #default="{ row, $index }"> <template #default="{ row, $index }">
<el-form-item <el-form-item
:prop="`${itemArrayName}.${$index}.partNumber`" :prop="`${itemArrayName}.${$index}.partNumber`"
:rules="[ :rules="[{ required: true, validator: validatePartNumber, trigger: 'blur' }]"
{ required: true, message: $t('_message.purchase.purchase_plan_item.input_partNumber'), trigger: 'blur' },
]"
> >
<el-input v-model="row.partNumber" size="small" /> <el-input v-model="row.partNumber" size="small" />
</el-form-item> </el-form-item>

View File

@@ -294,6 +294,8 @@ const operateButtonClick = (eventName: string, row: any) => {
const authShowFunc = (row: any, button: globalThis.ButtonProp) => { const authShowFunc = (row: any, button: globalThis.ButtonProp) => {
if (row.status === 0 && button.eventName === "reject") return false; if (row.status === 0 && button.eventName === "reject") return false;
if (row.status === 1 && button.eventName === "approve") return false; if (row.status === 1 && button.eventName === "approve") return false;
if (row.status === 1 && button.eventName === "edit") return false;
if (row.status === 1 && button.eventName === "remove") return false;
return true; return true;
}; };
</script> </script>
@@ -311,12 +313,12 @@ const authShowFunc = (row: any, button: globalThis.ButtonProp) => {
<DefaultToolButton @top-button-click="topButtonClick" /> <DefaultToolButton @top-button-click="topButtonClick" />
</template> </template>
<template #columns> <template #columns>
<el-table-column :label="$t('_prop.warehouse.stocktransferorder.formCode')" prop="formCode" /> <el-table-column :label="$t('_prop.warehouse.stocktransferorder.formCode')" prop="formCode" width="175" />
<el-table-column :label="$t('_prop.warehouse.stocktransferorder.formName')" prop="formName" /> <el-table-column :label="$t('_prop.warehouse.stocktransferorder.formName')" prop="formName" width="250" />
<el-table-column :label="$t('_prop.warehouse.stocktransferorder.storeName')" prop="storeName" /> <el-table-column :label="$t('_prop.warehouse.stocktransferorder.storeName')" prop="storeName" width="100" />
<el-table-column :label="$t('_prop.warehouse.stocktransferorder.outStoreName')" prop="outStoreName" /> <el-table-column :label="$t('_prop.warehouse.stocktransferorder.outStoreName')" prop="outStoreName" width="100" />
<el-table-column :label="$t('_prop.warehouse.stocktransferorder.formMark')" prop="formMark" /> <el-table-column :label="$t('_prop.warehouse.stocktransferorder.formMark')" prop="formMark" width="250" />
<el-table-column :label="$t('_prop.common.createDate')" prop="createDate" :formatter="formatDate" /> <el-table-column :label="$t('_prop.common.createDate')" prop="createDate" :formatter="formatDate" width="150" />
<DefaultStatusSwitchColumn <DefaultStatusSwitchColumn
status-param-name="status" status-param-name="status"
:status-label-mapping="getFormStatusLabel" :status-label-mapping="getFormStatusLabel"

View File

@@ -8,7 +8,6 @@ import { $t } from "@/common/languages";
import { ElMessage, type FormInstance, type FormRules } from "element-plus"; import { ElMessage, type FormInstance, type FormRules } from "element-plus";
import { formatDate } from "@/common/utils/format-utils"; import { formatDate } from "@/common/utils/format-utils";
import { get, post } from "@/common/http/request"; import { get, post } from "@/common/http/request";
import BaseTableForm from "@/components/base/base-table-form/BaseTableForm.vue";
import QrCodeDialog from "@/components/base/base-qrcode/QrCodeDialog.vue"; import QrCodeDialog from "@/components/base/base-qrcode/QrCodeDialog.vue";
import { Delete, Edit, Plus } from "@element-plus/icons-vue"; import { Delete, Edit, Plus } from "@element-plus/icons-vue";
@@ -169,10 +168,6 @@ const saveVendorList = async () => {
const validVendors = dialogTableData.value.filter(v => v.vendorId !== null && v.vendorId !== undefined); const validVendors = dialogTableData.value.filter(v => v.vendorId !== null && v.vendorId !== undefined);
if (validVendors.length === 0) {
return;
}
const vendorList = validVendors.map(v => ({ const vendorList = validVendors.map(v => ({
vendorId: v.vendorId, vendorId: v.vendorId,
costPrice: v.costPrice, costPrice: v.costPrice,
@@ -244,14 +239,18 @@ const cancelVendorEdit = (row: any, originalRow: any) => {
<DefaultToolButton @top-button-click="topButtonClick" /> <DefaultToolButton @top-button-click="topButtonClick" />
</template> </template>
<template #columns> <template #columns>
<el-table-column :label="$t('_prop.warehouse.warehouse_item.partNumber')" prop="partNumber" width="150" /> <el-table-column :label="$t('_prop.warehouse.warehouse_item.partNumber')" prop="partNumber" width="125" />
<el-table-column :label="$t('_prop.warehouse.warehouse_item.productType')" prop="productType" /> <el-table-column :label="$t('_prop.warehouse.warehouse_item.productType')" prop="productType" width="200" />
<el-table-column :label="$t('_prop.warehouse.warehouse_item.productSpecs')" prop="productSpecs" width="150" /> <el-table-column :label="$t('_prop.warehouse.warehouse_item.productSpecs')" prop="productSpecs" width="200" />
<el-table-column :label="$t('_prop.warehouse.warehouse_item.productBrand')" prop="productBrand" /> <el-table-column :label="$t('_prop.warehouse.warehouse_item.productBrand')" prop="productBrand" width="100" />
<el-table-column :label="$t('_prop.warehouse.warehouse_item.productPacking')" prop="productPacking" /> <el-table-column :label="$t('_prop.warehouse.warehouse_item.productPacking')" prop="productPacking" width="100" />
<el-table-column :label="$t('_prop.warehouse.warehouse_item.productPackSize')" prop="productPackSize" /> <el-table-column
:label="$t('_prop.warehouse.warehouse_item.productPackSize')"
prop="productPackSize"
width="125"
/>
<el-table-column :label="$t('_prop.warehouse.warehouse_item.productPrice')" prop="productPrice" /> <el-table-column :label="$t('_prop.warehouse.warehouse_item.productPrice')" prop="productPrice" />
<el-table-column :label="$t('_prop.common.createDate')" prop="createDate" :formatter="formatDate" /> <el-table-column :label="$t('_prop.common.createDate')" prop="createDate" :formatter="formatDate" width="200" />
<el-table-column :label="$t('_prop.warehouse.warehouse_item.createUserName')" prop="createUserName" /> <el-table-column :label="$t('_prop.warehouse.warehouse_item.createUserName')" prop="createUserName" />
<DefaultOperateButtonColumn @operate-button-click="operateButtonClick" /> <DefaultOperateButtonColumn @operate-button-click="operateButtonClick" />
</template> </template>
@@ -325,7 +324,14 @@ const cancelVendorEdit = (row: any, originalRow: any) => {
</el-form-item> </el-form-item>
</template> </template>
</BaseForm> </BaseForm>
<el-dialog v-model="vendorDialogVisible" :title="vendorDialogTitle" width="80%" :close-on-click-modal="false"> <el-dialog
class="vendor-dialog"
v-model="vendorDialogVisible"
:title="vendorDialogTitle"
width="80%"
:close-on-click-modal="false"
:lock-scroll="false"
>
<el-form ref="vendorFormRef" :model="{ dialogTableData }" :rules="vendorFormRules"> <el-form ref="vendorFormRef" :model="{ dialogTableData }" :rules="vendorFormRules">
<el-table :data="dialogTableData" border stripe style="width: 100%" max-height="50vh"> <el-table :data="dialogTableData" border stripe style="width: 100%" max-height="50vh">
<el-table-column :label="$t('_prop.warehouse.warehouse_item.vendorName')" width="250" show-overflow-tooltip> <el-table-column :label="$t('_prop.warehouse.warehouse_item.vendorName')" width="250" show-overflow-tooltip>

View File

@@ -161,6 +161,7 @@ const authShowFunc = (row: any, button: globalThis.ButtonProp) => {
if (row.status === 0 && button.eventName === "reject") return false; if (row.status === 0 && button.eventName === "reject") return false;
if (row.status === 1 && button.eventName === "approve") return false; if (row.status === 1 && button.eventName === "approve") return false;
if (row.status === 1 && button.eventName === "edit") return false; if (row.status === 1 && button.eventName === "edit") return false;
if (row.status === 1 && button.eventName === "remove") return false;
return true; return true;
}; };
@@ -212,11 +213,11 @@ const submit = (form: any, formRef: FormInstance | undefined) => {
<DefaultToolButton @top-button-click="topButtonClick" /> <DefaultToolButton @top-button-click="topButtonClick" />
</template> </template>
<template #columns> <template #columns>
<el-table-column :label="$t('_prop.warehouse.warehousereceipt.formCode')" prop="formCode" /> <el-table-column :label="$t('_prop.warehouse.warehousereceipt.formCode')" prop="formCode" width="175" />
<el-table-column :label="$t('_prop.warehouse.warehousereceipt.storeName')" prop="storeName" /> <el-table-column :label="$t('_prop.warehouse.warehousereceipt.storeName')" prop="storeName" width="125" />
<el-table-column :label="$t('_prop.warehouse.warehousereceipt.formName')" prop="formName" /> <el-table-column :label="$t('_prop.warehouse.warehousereceipt.formName')" prop="formName" width="350" />
<el-table-column :label="$t('_prop.warehouse.warehousereceipt.formMark')" prop="formMark" /> <el-table-column :label="$t('_prop.warehouse.warehousereceipt.formMark')" prop="formMark" width="200" />
<el-table-column :label="$t('_prop.common.createDate')" prop="createDate" :formatter="formatDate" /> <el-table-column :label="$t('_prop.common.createDate')" prop="createDate" :formatter="formatDate" width="150" />
<DefaultStatusSwitchColumn <DefaultStatusSwitchColumn
status-param-name="status" status-param-name="status"
:status-label-mapping="getFormStatusLabel" :status-label-mapping="getFormStatusLabel"

View File

@@ -53,14 +53,14 @@ export default defineConfig(({ command, mode }: ConfigEnv): UserConfig => {
open: viteEnv.VITE_OPEN, open: viteEnv.VITE_OPEN,
cors: true, cors: true,
// 跨域代理配置 // 跨域代理配置
proxy: { // proxy: {
"/api": { // "/api": {
target: "https://vue3-design.teek.top", // target: "https://vue3-design.teek.top",
changeOrigin: true, // changeOrigin: true,
secure: true, // 是否忽略 https 安全证书问题true 不忽略false 忽略 // secure: true, // 是否忽略 https 安全证书问题true 不忽略false 忽略
rewrite: path => path.replace(/^\/api/, ""), // rewrite: path => path.replace(/^\/api/, ""),
}, // },
}, // },
// 预热文件以提前转换和缓存结果,降低启动期间的初始页面加载时长并防止转换瀑布 // 预热文件以提前转换和缓存结果,降低启动期间的初始页面加载时长并防止转换瀑布
warmup: { warmup: {
clientFiles: ["./index.html", "./src/{views,components}/*"], clientFiles: ["./index.html", "./src/{views,components}/*"],