feat(inventory): 新增备货信息管理功能

- 在库存模块中添加新的备货信息页面,支持查询、新增、修改和删除操作
- 实现了备货状态的更新逻辑,包括从“待备货”到“已备货”的转换
- 增加了按照项目编号、名称、合同编号及备货状态进行筛选的功能
- 支持按到货时间和审批时间排序
- 提供了导出备货信息列表为Excel文件的功能
- 添加了查看项目详情和订单详情的跳转链接
- 优化了移动端展示效果,确保在不同设备上都能良好显示数据
- 更新了权限配置,确保相关路由可以被正确访问
- 修复了部分UI交互问题,提升了用户体验
dev_1.0.0
chenhao 2025-11-21 16:15:35 +08:00
parent f236c22d7f
commit 6b3deec414
14 changed files with 1361 additions and 14 deletions

View File

@ -0,0 +1,56 @@
import request from '@/utils/request'
// 查询备货信息列表
export function listStock(query) {
return request({
url: '/stock/vue/list',
method: 'get',
params: query
})
}
// 获取备货信息详细信息
export function getStock(id) {
return request({
url: '/stock/vue/' + id,
method: 'get'
})
}
// 新增备货信息
export function addStock(data) {
return request({
url: '/stock/vue',
method: 'post',
data: data
})
}
// 修改备货信息
export function updateStock(data) {
return request({
url: '/stock/vue',
method: 'put',
data: data
})
}
// 删除备货信息
export function delStock(ids) {
return request({
url: '/stock/vue/' + ids,
method: 'delete'
})
}
// 导出备货信息
export function exportStock(query) {
return request({
url: '/stock/vue/export',
method: 'post', // Assuming POST for export with query params based on how old one was set up.
params: query,
// The original export function used window.location.href, so the backend handles the file download.
// We'll mimic the backend behavior for now and let it respond with a downloadable file.
responseType: 'blob' // Important for file download
})
}

View File

@ -51,3 +51,12 @@ export function exportPartner(query) {
data: query
})
}
// 查询代理商信息(公开查询)
export function queryPartner(query) {
return request({
url: '/system/partner/list/query',
method: 'get',
params: query
})
}

View File

@ -8,7 +8,7 @@ import { isRelogin } from '@/utils/request'
NProgress.configure({ showSpinner: false })
const whiteList = ['/login', '/register', '/service-query']
const whiteList = ['/login', '/register', '/manage/service','/system/vendor/query','/system/partner/query']
const isWhiteList = (path) => {
return whiteList.some(pattern => isPathMatch(pattern, path))

View File

@ -91,9 +91,19 @@ export const constantRoutes = [
{
path: '/service-query',
path: '/manage/service',
component: () => import('@/views/manage/service/index'),
hidden: true
},
{
path: '/system/vendor/query',
component: () => import('@/views/system/vendor/query'),
hidden: true
},
{
path: '/system/partner/query',
component: () => import('@/views/system/partner/query'),
hidden: true
}
]

View File

@ -1,9 +1,9 @@
<template xmlns="http://www.w3.org/1999/html">
<div class="app-container">
<div class="app-container" style="max-height: 70vh;overflow-y: auto">
<el-form ref="form" :model="form" :rules="rules" label-width="120px">
<el-card class="box-card">
<div slot="header" class="clearfix">
<el-button icon="el-icon-back" type="text" @click="cancel"></el-button>
<!-- <el-button icon="el-icon-back" type="text" @click="cancel"></el-button>-->
<br/>
<span>订单信息</span>
</div>
@ -74,10 +74,6 @@
</el-table>
</el-card>
<div style="text-align: center; margin-top: 30px;">
<el-button type="primary" @click="submitForm" v-if="canUpdate"> </el-button>
<el-button @click="cancel"> </el-button>
</div>
<!-- 出库对话框 -->
<checkout-dialog ref="checkoutDialog" :order-info="form" @success="handleCheckoutSuccess"></checkout-dialog>
@ -120,7 +116,6 @@ export default {
partnerPhone: [{ required: true, message: "联系方式不能为空", trigger: "blur" }],
currencyType: [{ required: true, message: "币种不能为空", trigger: "change" }],
},
canUpdate: false,
productDetailList: [],
inventoryOuterList: [],
industryOptions: []
@ -152,7 +147,6 @@ export default {
this.form = response.data.projectOrderInfo;
this.productDetailList = response.data.productDetailList;
this.inventoryOuterList = response.data.inventoryOuterList;
this.canUpdate = response.data.canUpdate;
this.fetchIndustryOptions(this.form.bgProperty);
this.currentOrderId=this.form.id
});

View File

@ -143,6 +143,7 @@
size="mini"
type="text"
icon="el-icon-delete"
style="color: red"
@click="handleRecall(scope.row)"
v-hasPermi="['inventory:execution:recall']"
>撤单</el-button>
@ -166,6 +167,9 @@
@success="handleEditSuccess"
@cancel="handleEditCancel"
/>
<template slot="footer">
<el-button @click="editDialogVisible=false"> </el-button>
</template>
</el-dialog>
<!-- 签收文件上传对话框 -->

View File

@ -82,7 +82,8 @@
<delivery-detail :delivery-id="deliveryId" :visible.sync="viewOpen" />
<div slot="footer" class="dialog-footer">
<el-button @click="handleCancel"> </el-button>
<el-button v-if="showReturn" type="danger" @click="handleCancel">退 </el-button>
<el-button @click="handleCancel"> </el-button>
</div>
</el-dialog>
</template>
@ -99,6 +100,7 @@ export default {
data() {
return {
visible: false,
showReturn: false,
title: '出库单发货管理',
form: {},
productList: [],
@ -117,6 +119,7 @@ export default {
this.form = response.data.inventoryOuter;
this.productList = response.data.productVoList || [];
this.deliveryList = response.data.deliveryList || [];
this.showReturn=this.deliveryList.length<=0;
});
}
},

View File

@ -61,7 +61,7 @@
<el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)" v-hasPermi="['inventory:outer:edit']"></el-button>
</template>
<template v-else>
<el-button size="mini" type="text" @click="handleStatusChange(scope.row, '4')">退回</el-button>
<el-button size="mini" type="text" style="color: red" @click="handleStatusChange(scope.row, '4')">退回</el-button>
<el-button size="mini" type="text" @click="handleStatusChange(scope.row, '3')">确认接收</el-button>
</template>
</template>

View File

@ -0,0 +1,619 @@
<template>
<div class="app-container">
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="80px">
<el-form-item label="项目编号" prop="projectCode">
<el-input
v-model="queryParams.projectCode"
placeholder="请输入项目编号"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="项目名称" prop="projectName">
<el-input
v-model="queryParams.projectName"
placeholder="请输入项目名称"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="合同编号" prop="orderCode">
<el-input
v-model="queryParams.orderCode"
placeholder="请输入合同编号"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="备货状态" prop="stockStatus">
<el-select v-model="queryParams.stockStatus" placeholder="请选择备货状态" clearable>
<el-option label="待备货" value="0" />
<el-option label="已备货" value="1" />
</el-select>
</el-form-item>
<el-form-item label="到货时间">
<el-date-picker
v-model="queryParams.deliveryTimeRange"
style="width: 240px"
value-format="yyyy-MM-dd"
type="daterange"
range-separator="-"
start-placeholder="开始日期"
end-placeholder="结束日期"
></el-date-picker>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery"></el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery"></el-button>
</el-form-item>
</el-form>
<el-table v-loading="loading" :data="stockList" @selection-change="handleSelectionChange" @sort-change="handleSortChange">
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="ID" align="center" prop="id" v-if="false"/>
<el-table-column label="项目编号" align="center" prop="projectCode" width="100" />
<el-table-column label="项目名称" align="center" prop="projectName" width="300" show-overflow-tooltip>
<template slot-scope="scope">
<a href="javascript:void(0)" @click="viewProjectDetail(scope.row.projectId)" class="link-type">
<span>{{ scope.row.projectName }}</span>
</a>
</template>
</el-table-column>
<el-table-column label="合同编号" align="center" prop="orderCode" width="200" show-overflow-tooltip>
<template slot-scope="scope">
<a href="javascript:void(0)" @click="viewDetail(scope.row.orderId)" class="link-type">
<span>{{ scope.row.orderCode }}</span>
</a>
</template>
</el-table-column>
<el-table-column label="备货状态" align="center" prop="stockStatus" width="100">
<template slot-scope="scope">
<span>{{ scope.row.stockStatus === '0' ? '待备货' : '已备货' }}</span>
</template>
</el-table-column>
<el-table-column label="数量" align="center" prop="allQuantity" width="100" />
<el-table-column label="备货地址" align="center" prop="notifierAddress" width="300" show-overflow-tooltip />
<el-table-column label="联系人" align="center" prop="notifier" width="100" />
<el-table-column label="联系电话" align="center" prop="notifierPhone" width="120" />
<el-table-column label="到货时间" align="center" prop="deliveryTime" sortable="custom" width="180" class-name="time3" />
<el-table-column label="审批时间" align="center" prop="createTime" sortable="custom" width="180" class-name="time4" />
<el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="180" fixed="right">
<template slot-scope="scope">
<el-button
size="mini"
type="text"
icon="el-icon-s-operation"
@click="handleUpdateStatus(scope.row)"
v-if="scope.row.stockStatus === '0'"
v-hasPermi="['stock:stock:edit']"
>开始备货</el-button>
<el-button
size="mini"
type="text"
icon="el-icon-delete"
@click="handleDelete(scope.row)"
v-else
v-hasPermi="['stock:stock:remove']"
>删除</el-button>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total>0"
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
<!-- 添加或修改备货信息对话框 -->
<el-dialog :title="titleAddEdit" :visible.sync="openAddEdit" width="800px" append-to-body>
<el-form ref="form" :model="form" :rules="rules" label-width="120px">
<el-row>
<el-col :span="12">
<el-form-item label="项目编号" prop="projectCode">
<el-input v-model="form.projectCode" placeholder="请输入项目编号" :disabled="form.id != null" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="项目名称" prop="projectName">
<el-input v-model="form.projectName" placeholder="请输入项目名称" :disabled="form.id != null" />
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="合同编号" prop="orderCode">
<el-input v-model="form.orderCode" placeholder="请输入合同编号" :disabled="form.id != null" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="备货状态" prop="stockStatus">
<el-select v-model="form.stockStatus" placeholder="请选择备货状态" :disabled="form.id != null">
<el-option label="待备货" value="0" />
<el-option label="已备货" value="1" />
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="数量" prop="allQuantity">
<el-input v-model="form.allQuantity" placeholder="请输入数量" :disabled="form.id != null" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="备货地址" prop="notifierAddress">
<el-input v-model="form.notifierAddress" placeholder="请输入备货地址" :disabled="form.id != null" />
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="联系人" prop="notifier">
<el-input v-model="form.notifier" placeholder="请输入联系人" :disabled="form.id != null" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="联系电话" prop="notifierPhone">
<el-input v-model="form.notifierPhone" placeholder="请输入联系电话" :disabled="form.id != null" />
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="到货时间" prop="deliveryTime">
<el-date-picker clearable
v-model="form.deliveryTime"
type="datetime"
value-format="yyyy-MM-dd HH:mm:ss"
placeholder="请选择到货时间"
:disabled="form.id != null">
</el-date-picker>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="审批时间" prop="createTime">
<el-date-picker clearable
v-model="form.createTime"
type="datetime"
value-format="yyyy-MM-dd HH:mm:ss"
placeholder="请选择审批时间"
:disabled="form.id != null">
</el-date-picker>
</el-form-item>
</el-col>
</el-row>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitForm"> </el-button>
<el-button @click="cancelAddEdit"> </el-button>
</div>
</el-dialog>
<!-- 备货信息详情抽屉 -->
<el-drawer
:title="titleDetail"
:visible.sync="openDetail"
direction="rtl"
size="50%"
destroy-on-close
>
<el-form ref="detailForm" :model="form" label-width="120px" class="drawer-form-wrapper">
<el-row>
<el-col :span="24">
<el-form-item label="项目编号">
<el-input v-model="form.projectCode" disabled />
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="24">
<el-form-item label="项目名称">
<el-input v-model="form.projectName" disabled />
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="24">
<el-form-item label="合同编号">
<el-input v-model="form.orderCode" disabled />
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="24">
<el-form-item label="备货状态">
<el-input :value="form.stockStatus === '0' ? '待备货' : '已备货'" disabled />
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="24">
<el-form-item label="数量">
<el-input v-model="form.allQuantity" disabled />
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="24">
<el-form-item label="备货地址">
<el-input v-model="form.notifierAddress" disabled />
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="24">
<el-form-item label="联系人">
<el-input v-model="form.notifier" disabled />
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="24">
<el-form-item label="联系电话">
<el-input v-model="form.notifierPhone" disabled />
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="24">
<el-form-item label="到货时间">
<el-input v-model="form.deliveryTime" disabled />
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="24">
<el-form-item label="审批时间">
<el-input v-model="form.createTime" disabled />
</el-form-item>
</el-col>
</el-row>
</el-form>
</el-drawer>
</div>
</template>
<script>
import { listStock, getStock, addStock, updateStock, delStock, exportStock } from "@/api/inventory/stock";
import Pagination from '@/components/Pagination'; // Assuming standard path
export default {
name: "Stock",
components: {
Pagination,
},
data() {
return {
//
loading: true,
//
ids: [],
//
single: true,
//
multiple: true,
//
showSearch: true,
//
total: 0,
//
stockList: [],
//
titleAddEdit: "",
titleDetail: "",
//
openAddEdit: false,
openDetail: false,
//
queryParams: {
pageNum: 1,
pageSize: 10,
projectCode: null,
projectName: null,
orderCode: null,
stockStatus: null,
deliveryTimeRange: [], // For el-date-picker daterange
orderByColumn: null,
isAsc: null,
},
//
form: {},
//
rules: {
projectCode: [
{ required: true, message: "项目编号不能为空", trigger: "blur" }
],
projectName: [
{ required: true, message: "项目名称不能为空", trigger: "blur" }
],
orderCode: [
{ required: true, message: "合同编号不能为空", trigger: "blur" }
],
stockStatus: [
{ required: true, message: "备货状态不能为空", trigger: "change" }
],
allQuantity: [
{ required: true, message: "数量不能为空", trigger: "blur" }
],
notifierAddress: [
{ required: true, message: "备货地址不能为空", trigger: "blur" }
],
notifier: [
{ required: true, message: "联系人不能为空", trigger: "blur" }
],
notifierPhone: [
{ required: true, message: "联系电话不能为空", trigger: "blur" }
],
deliveryTime: [
{ required: true, message: "到货时间不能为空", trigger: "change" }
],
}
};
},
created() {
this.getList();
},
methods: {
/** 查询备货信息列表 */
getList() {
this.loading = true;
let query = JSON.parse(JSON.stringify(this.queryParams));
// Handle date range
if (query.deliveryTimeRange && query.deliveryTimeRange.length === 2) {
query.deliveryTimeStart = query.deliveryTimeRange[0];
query.deliveryTimeEnd = query.deliveryTimeRange[1];
} else {
query.deliveryTimeStart = null;
query.deliveryTimeEnd = null;
}
delete query.deliveryTimeRange;
listStock(query).then(response => {
this.stockList = response.rows;
this.total = response.total;
this.loading = false;
});
},
//
cancelAddEdit() {
this.openAddEdit = false;
this.resetForm();
},
cancelDetail() {
this.openDetail = false;
this.resetForm();
},
//
resetForm() {
this.form = {
id: null,
projectCode: null,
projectName: null,
orderCode: null,
stockStatus: "0", // Default to ''
allQuantity: null,
notifierAddress: null,
notifier: null,
notifierPhone: null,
deliveryTime: null,
createTime: null,
};
this.resetForm('form'); // Reset validation
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1;
this.getList();
},
/** 重置按钮操作 */
resetQuery() {
this.queryParams.deliveryTimeRange = [];
this.resetForm("queryForm"); // Reset search form
this.handleQuery();
},
//
handleSelectionChange(selection) {
this.ids = selection.map(item => item.id);
this.single = selection.length !== 1;
this.multiple = !selection.length;
},
/** 新增按钮操作 */
handleAdd() {
this.resetForm();
this.openAddEdit = true;
this.titleAddEdit = "添加备货信息";
},
/** 修改按钮操作 */
handleUpdate(row) {
this.resetForm();
const id = row.id || this.ids;
getStock(id).then(response => {
this.form = response.data;
this.openAddEdit = true;
this.titleAddEdit = "修改备货信息";
});
},
/** 详情按钮操作 */
handleDetail(row) {
this.resetForm();
getStock(row.id).then(response => {
this.form = response.data;
this.openDetail = true;
this.titleDetail = "备货信息详情";
});
},
/** 提交按钮 */
submitForm() {
this.$refs["form"].validate(valid => {
if (valid) {
if (this.form.id != null) {
updateStock(this.form).then(response => {
this.$modal.msgSuccess("修改成功");
this.openAddEdit = false;
this.getList();
});
} else {
addStock(this.form).then(response => {
this.$modal.msgSuccess("新增成功");
this.openAddEdit = false;
this.getList();
});
}
}
});
},
/** 删除按钮操作 */
handleDelete(row) {
const ids = row.id || this.ids;
this.$modal.confirm('是否确认删除备货信息编号为"' + ids + '"的数据项?').then(function() {
return delStock(ids);
}).then(() => {
this.getList();
this.$modal.msgSuccess("删除成功");
}).catch(() => {});
},
/** 导出按钮操作 */
handleExport() {
this.$modal.confirm('是否确认导出所有备货信息数据项?').then(() => {
this.loading = true;
let query = JSON.parse(JSON.stringify(this.queryParams));
if (query.deliveryTimeRange && query.deliveryTimeRange.length === 2) {
query.deliveryTimeStart = query.deliveryTimeRange[0];
query.deliveryTimeEnd = query.deliveryTimeRange[1];
} else {
query.deliveryTimeStart = null;
query.deliveryTimeEnd = null;
}
delete query.deliveryTimeRange;
return exportStock(query);
}).then(response => {
// Assuming response is a blob for file download
// The original method used window.location.href, which expects the backend to handle the file response directly.
// For a Vue frontend with axios/request, we typically handle blob responses.
const blob = new Blob([response]);
const fileName = '备货信息列表.xlsx'; // Or parse from Content-Disposition header
if (typeof window.chrome !== 'undefined') {
// Chrome
const link = document.createElement('a');
link.href = window.URL.createObjectURL(blob);
link.download = fileName;
link.click();
} else if (typeof window.navigator.msSaveBlob !== 'undefined') {
// IE
window.navigator.msSaveBlob(blob, fileName);
} else {
// Firefox
const link = document.createElement('a');
link.href = window.URL.createObjectURL(blob);
link.download = fileName;
link.click();
}
this.loading = false;
this.$modal.msgSuccess("导出成功");
}).catch(() => {
this.loading = false;
});
},
/** 开始备货按钮操作 */
handleUpdateStatus(row) {
this.$modal.confirm('是否确认将项目编号为"' + row.projectCode + '"的备货信息状态修改为“已备货”?').then(function() {
// Create a new object with only id and stockStatus to send for update
return updateStock({ id: row.id, stockStatus: "1" });
}).then(() => {
this.getList();
this.$modal.msgSuccess("操作成功");
}).catch(() => {});
},
/** 排序改变事件 */
handleSortChange(column) {
if (column.order === 'ascending') {
this.queryParams.isAsc = 'asc';
} else if (column.order === 'descending') {
this.queryParams.isAsc = 'desc';
} else {
this.queryParams.isAsc = null;
}
// Map prop to original orderByColumn values
if (column.prop === 'deliveryTime') {
this.queryParams.orderByColumn = 't2.deliveryTime';
} else if (column.prop === 'createTime') {
this.queryParams.orderByColumn = 't1.createTime';
} else {
this.queryParams.orderByColumn = null;
}
this.getList();
},
/** 查看项目详情 */
viewProjectDetail(projectId) {
// Placeholder: In a real app, this would open a dialog/drawer or navigate to a project detail page.
// Example using El-drawer if a component exists:
// this.$refs.projectDetailDrawer.open(projectId);
// Or routing:
// this.$router.push('/project/detail/' + projectId);
this.$modal.alert('查看项目详情 ID: ' + projectId);
console.log('Viewing Project Detail ID:', projectId);
},
/** 查看订单详情 */
viewDetail(orderId) {
// Placeholder: In a real app, this would open a dialog/drawer or navigate to an order detail page.
this.$modal.alert('查看订单详情 ID: ' + orderId);
console.log('Viewing Order Detail ID:', orderId);
},
/** 查看审批日志 */
viewApproveLog(orderId) {
// Placeholder: In a real app, this would open a dialog/drawer for approve logs.
this.$modal.alert('查看审批日志 Order ID: ' + orderId);
console.log('Viewing Approve Log for Order ID:', orderId);
}
}
};
</script>
<style lang="scss" scoped>
/*
The original CSS had some global overrides and specific class names.
Here, I'm trying to scope them as much as possible to this component.
Some styles like .select-list li p, .select-list li label were specific to the old layout.
Element UI generally handles spacing and layout well, so some may not be strictly necessary
or might be better handled by Element UI's own layout components (el-row, el-col).
*/
.select-list ul {
list-style: none;
padding: 0;
margin: 0;
display: flex;
flex-wrap: wrap;
align-items: center;
gap: 10px; /* Adjust gap as needed */
}
.select-list li {
display: flex;
align-items: center;
}
/* Specific overrides for label width if needed, but Element UI form-item label-width is preferred */
.el-form-item {
margin-bottom: 18px; /* Adjust as needed */
}
/* Original .sortBox styles - handled by el-table sortable="custom" and handleSortChange */
/* If custom sort icons are needed, they would be injected into el-table-column header slot */
.timeSearch {
display: flex;
gap: 10px;
align-items: center;
}
.drawer-form-wrapper {
padding: 20px;
}
</style>

View File

@ -0,0 +1,350 @@
<template>
<div class="partner-query-container">
<div class="content-wrapper">
<!-- 标题 -->
<div class="topBox">
<div class="title">代理商查询</div>
</div>
<!-- 查询表单 -->
<div class="container">
<div class="form-group">
<label for="partnerCode">代理商代码</label>
<el-input
v-model="partnerCode"
placeholder="请输入代理商代码"
clearable
@keyup.enter.native="getData"
style="width: 300px"
/>
</div>
<el-button type="primary" @click="getData"></el-button>
</div>
<!-- 查询结果标题 -->
<div class="result-title">查询结果</div>
<div class="subtitle-wrapper">
<blockquote class="subtitle-blockquote">代理商信息</blockquote>
</div>
<!-- PC端表格 -->
<div class="table-wrapper">
<el-table
v-loading="loading"
:data="partnerList"
class="partner-table"
:header-cell-style="{ background: '#f5f5f5', padding: '10px' }"
:cell-style="{ padding: '10px' }"
>
<el-table-column
prop="partnerCode"
label="代理商编码"
align="center"
min-width="100"
/>
<el-table-column
prop="partnerName"
label="代理商名称"
align="center"
min-width="100"
/>
<el-table-column
prop="province"
label="省"
align="center"
min-width="100"
/>
<el-table-column
prop="city"
label="市"
align="center"
min-width="100"
/>
<el-table-column
prop="address"
label="详细地址"
align="center"
min-width="100"
show-overflow-tooltip
/>
<el-table-column
prop="contactPerson"
label="联系人"
align="center"
min-width="100"
/>
<el-table-column
prop="contactPhone"
label="联系电话"
align="center"
min-width="100"
/>
<el-table-column
prop="levelName"
label="认证级别"
align="center"
min-width="100"
/>
<template slot="empty">
<div class="empty-data">暂无数据</div>
</template>
</el-table>
</div>
<!-- 移动端显示 -->
<div class="mobile-table">
<div v-if="partnerList.length === 0" class="empty-data-mobile">
暂无数据
</div>
<div v-else class="mobile-row" v-for="(item, index) in partnerList" :key="index">
<div class="mobile-cell">
<span class="mobile-label">代理商编码</span>
<span class="mobile-value">{{ item.partnerCode }}</span>
</div>
<div class="mobile-cell">
<span class="mobile-label">代理商名称</span>
<span class="mobile-value">{{ item.partnerName }}</span>
</div>
<div class="mobile-cell">
<span class="mobile-label"></span>
<span class="mobile-value">{{ item.province }}</span>
</div>
<div class="mobile-cell">
<span class="mobile-label"></span>
<span class="mobile-value">{{ item.city }}</span>
</div>
<div class="mobile-cell">
<span class="mobile-label">地址</span>
<span class="mobile-value">{{ item.address }}</span>
</div>
<div class="mobile-cell">
<span class="mobile-label">联系人</span>
<span class="mobile-value">{{ item.contactPerson }}</span>
</div>
<div class="mobile-cell">
<span class="mobile-label">联系电话</span>
<span class="mobile-value">{{ item.contactPhone }}</span>
</div>
<div class="mobile-cell">
<span class="mobile-label">认证级别</span>
<span class="mobile-value">{{ item.levelName }}</span>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import { queryPartner } from "@/api/system/partner";
export default {
name: "PartnerQuery",
data() {
return {
//
partnerCode: '',
//
loading: false,
//
partnerList: []
};
},
created() {
// URL
if (this.$route.query.code) {
this.partnerCode = this.$route.query.code;
}
//
this.getData();
},
methods: {
/** 查询代理商数据 */
getData() {
this.loading = true;
const params = {};
if (this.partnerCode) {
params.partnerCode = this.partnerCode;
}
queryPartner(params).then(response => {
if (response.data && Array.isArray(response.data)) {
this.partnerList = response.data;
} else {
this.partnerList = [];
}
this.loading = false;
}).catch(() => {
this.partnerList = [];
this.loading = false;
});
}
}
};
</script>
<style scoped>
.partner-query-container {
width: 100%;
margin: 0;
padding: 20px;
background-color: #f9f9f9;
box-sizing: border-box;
}
.content-wrapper {
max-width: 1200px;
margin: 0 auto;
}
.topBox {
display: flex;
flex-direction: row;
gap: 20px;
margin: 30px 0 10px;
align-items: center;
}
.topBox .title {
font-size: 24px;
font-weight: 600;
color: #333;
}
.container {
margin: 0;
padding: 10px 0;
background-color: white;
border-radius: 8px;
display: flex;
flex-direction: row;
gap: 30px;
justify-content: center;
align-items: center;
padding: 20px;
}
.form-group {
margin-bottom: 0;
display: flex;
flex-direction: row;
align-items: center;
gap: 10px;
}
.form-group label {
margin-bottom: 0;
width: 100px;
font-weight: 600;
flex-shrink: 0;
}
.result-title {
font-size: 20px;
text-align: left;
margin: 10px 0;
font-weight: 500;
}
.subtitle-wrapper {
font-size: 16px;
text-align: left;
font-weight: 600;
margin-bottom: 10px;
}
.subtitle-blockquote {
border-left: 5px solid #1c84c6;
margin-left: 0;
padding-left: 10px;
line-height: 1.5;
margin: 10px 0;
}
.table-wrapper {
width: 100%;
overflow-x: auto;
background-color: white;
border-radius: 8px;
padding: 15px;
}
.partner-table {
width: 100%;
}
.empty-data {
text-align: center;
padding: 20px;
color: #999;
}
.mobile-table {
display: none;
}
.empty-data-mobile {
text-align: center;
padding: 20px;
color: #999;
background-color: white;
border-radius: 8px;
}
/* 移动端样式 */
@media (max-width: 768px) {
.partner-query-container {
padding: 10px;
}
.container,
.topBox {
display: none;
}
.table-wrapper {
display: none;
}
.mobile-table {
display: block;
}
.mobile-row {
display: flex;
flex-direction: column;
border-bottom: 1px solid #ddd;
margin-bottom: 10px;
background-color: #fff;
border-radius: 5px;
padding: 10px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}
.mobile-cell {
display: flex;
justify-content: space-between;
align-items: center;
padding: 8px 10px;
border-bottom: 1px solid #eee;
}
.mobile-row .mobile-cell:last-child {
border-bottom: none;
}
.mobile-label {
font-weight: bold;
min-width: 100px;
max-width: 100px;
margin-right: 10px;
color: #333;
}
.mobile-value {
flex: 1;
text-align: right;
word-break: break-all;
}
}
</style>

View File

@ -0,0 +1,296 @@
<template>
<div class="vendor-query-container">
<div class="content-wrapper">
<div class="topBox">
<div class="title">UNISSENSE云终端</div>
</div>
<!-- 注释掉的查询功能如需使用可取消注释
<div class="container">
<div class="form-group">
<label for="partnerCode">代理商代码</label>
<el-input
v-model="partnerCode"
placeholder="请输入代理商代码"
clearable
/>
</div>
<el-button type="primary" @click="getData"></el-button>
</div>
-->
<div class="subtitle-wrapper">
<blockquote class="subtitle-blockquote">
<span class="desktop-title">UNISSENSE云终端售后联系方式</span>
<span class="mobile-title">UNISSENSE云终端<br>售后联系方式</span>
</blockquote>
</div>
<div class="table-wrapper">
<el-table
:data="vendorData"
class="vendor-table"
:header-cell-style="{ background: '#f5f5f5', padding: '10px' }"
:cell-style="{ padding: '10px' }"
>
<el-table-column
prop="manufacturerName"
label="制造商名称"
align="center"
/>
<el-table-column
prop="product"
label="产品"
align="center"
/>
<el-table-column
prop="phone"
label="售后电话"
align="center"
>
<template slot-scope="scope">
<a :href="'tel:' + scope.row.phoneNumber" class="phone-link">
{{ scope.row.phone }}
</a>
</template>
</el-table-column>
<el-table-column
prop="email"
label="邮箱地址"
align="center"
/>
</el-table>
<!-- 移动端显示 -->
<div class="mobile-table">
<div class="mobile-row" v-for="(item, index) in vendorData" :key="index">
<div class="mobile-cell">
<span class="mobile-label">制造商名称</span>
<span class="mobile-value">{{ item.manufacturerName }}</span>
</div>
<div class="mobile-cell">
<span class="mobile-label">产品</span>
<span class="mobile-value">{{ item.product }}</span>
</div>
<div class="mobile-cell">
<span class="mobile-label">售后电话</span>
<span class="mobile-value">
<a :href="'tel:' + item.phoneNumber" class="phone-link">{{ item.phone }}</a>
</span>
</div>
<div class="mobile-cell">
<span class="mobile-label">邮箱地址</span>
<span class="mobile-value">{{ item.email }}</span>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
name: "VendorQuery",
data() {
return {
//
partnerCode: '',
//
vendorData: [
{
manufacturerName: '紫光汇智信息技术有限公司',
product: 'UNISSENSE云终端',
phone: '193571916585*8小时',
phoneNumber: '19357191658',
email: 'jiachenming@unisinsight.com'
}
]
};
},
created() {
//
},
methods: {
/** 查询数据(备用功能)*/
getData() {
// TODO:
// : /system/vendor/query?partnerCode=${this.partnerCode}
console.log('查询代理商代码:', this.partnerCode);
}
}
};
</script>
<style scoped>
.vendor-query-container {
width: 100%;
margin: 0;
padding: 0;
background-color: #f9f9f9;
}
.content-wrapper {
padding: 20px;
box-sizing: border-box;
}
.container {
margin: 0;
padding: 10px 0;
background-color: white;
border-radius: 8px;
display: flex;
flex-direction: row;
gap: 30px;
justify-content: center;
align-items: center;
}
.topBox {
display: flex;
flex-direction: row;
gap: 20px;
margin: 30px 0 10px;
align-items: center;
}
.topBox .title {
font-size: 24px;
font-weight: 600;
color: #333;
text-align: center;
width: 100%;
}
.form-group {
margin-bottom: 15px;
display: flex;
flex-direction: row;
align-items: center;
gap: 10px;
}
.form-group label {
margin-bottom: 0;
width: 100px;
font-weight: 600;
}
.subtitle-wrapper {
font-size: 16px;
text-align: left;
font-weight: 600;
margin-bottom: 10px;
}
.subtitle-blockquote {
border-left: 5px solid #1c84c6;
margin-left: 0;
padding-left: 10px;
line-height: 1.5;
margin: 10px 0;
}
.mobile-title {
display: none;
}
.desktop-title {
display: inline-block;
}
.table-wrapper {
width: 100%;
background-color: white;
border-radius: 8px;
padding: 15px;
}
.vendor-table {
width: 100%;
}
.phone-link {
color: #1c84c6;
text-decoration: none;
}
.phone-link:hover {
text-decoration: underline;
}
.mobile-table {
display: none;
}
/* 移动端样式 */
@media (max-width: 768px) {
.content-wrapper {
padding: 10px;
}
.container {
display: none;
}
.topBox {
margin: 10px 0;
}
.topBox .title {
font-size: 20px;
}
.desktop-title {
display: none;
}
.mobile-title {
display: inline-block;
}
.vendor-table {
display: none;
}
.mobile-table {
display: block;
}
.mobile-row {
display: flex;
flex-direction: column;
border-bottom: 1px solid #ddd;
margin-bottom: 10px;
background-color: #fff;
border-radius: 5px;
padding: 10px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}
.mobile-cell {
display: flex;
justify-content: flex-start;
align-items: center;
padding: 15px 10px;
border-bottom: 1px solid #eee;
}
.mobile-row .mobile-cell:last-child {
border-bottom: none;
}
.mobile-label {
font-weight: bold;
color: #333;
width: 90px;
flex-shrink: 0;
}
.mobile-value {
flex: 1;
word-break: break-all;
}
}
</style>

View File

@ -160,4 +160,7 @@ unis:
mail:
enabled: true
# 商务角色id
businessRoleId: 103
businessRoleId: 103
flowable:
database-schema-update: false

View File

@ -84,7 +84,7 @@ public class VueInventoryOuterController extends BaseController
@PostMapping("/status")
public AjaxResult updateStatus(@RequestBody InventoryOuter inventoryOuter)
{
return toAjax(inventoryOuterService.updateInventoryOuter(inventoryOuter));
return toAjax(inventoryOuterService.statusUpdate(inventoryOuter));
}
@GetMapping("/view/{id}")

View File

@ -331,6 +331,9 @@ public class TodoServiceImpl implements TodoService {
@Override
public void fillOrderApproveNode(List<ProjectOrderInfo> list) {
List<String> businessKeyList = list.stream().map(ProjectOrderInfo::getOrderCode).collect(Collectors.toList());
if (CollUtil.isEmpty(businessKeyList)){
return;
}
List<Todo> todoList = todoMapper.listTodoByBusinessKeyAndProcessKey(businessKeyList, Arrays.asList(orderOnlineFlowKey, orderOfflineFlowKey));
Map<String, String> approveUserNameMap = todoList.stream()
.collect(Collectors.groupingBy(Todo::getBusinessKey,