【愚公系列】2023年03月 WMS智能仓储系统-013.基础设置(首页、公司信息、角色设置)
【摘要】 前言基础设置主要分为以下几个模块:首页公司信息角色设置菜单设置用户管理商品类别设置商品管理供应商信息仓库设置货主信息运费设置客户信息 一、基础设置 1.首页这就不多说了就是个标题和svg图片 2.公司信息 2.1 页面代码1、主页面代码<template> <div class="container"> <div> <!-- Main Content --> <...
前言
基础设置主要分为以下几个模块:
- 首页
- 公司信息
- 角色设置
- 菜单设置
- 用户管理
- 商品类别设置
- 商品管理
- 供应商信息
- 仓库设置
- 货主信息
- 运费设置
- 客户信息
一、基础设置
1.首页
这就不多说了就是个标题和svg图片
2.公司信息
2.1 页面代码
1、主页面代码
<template>
<div class="container">
<div>
<!-- Main Content -->
<v-card class="mt-5">
<v-card-text>
<div class="operateArea">
<v-row no-gutters>
<!-- Operate Btn -->
<v-col cols="12" sm="3" class="col">
<tooltip-btn icon="mdi-plus" :tooltip-text="$t('system.page.add')" @click="method.add()"></tooltip-btn>
<tooltip-btn icon="mdi-refresh" :tooltip-text="$t('system.page.refresh')" @click="method.refresh()"></tooltip-btn>
<tooltip-btn icon="mdi-export-variant" :tooltip-text="$t('system.page.export')" @click="method.exportTable"></tooltip-btn>
</v-col>
<!-- Search Input -->
<v-col cols="12" sm="9">
<!-- <v-row no-gutters @keyup.enter="method.sureSearch">
<v-col cols="12" sm="4">
<v-text-field
v-model="data.searchForm.userName"
clearable
hide-details
density="comfortable"
class="searchInput ml-5 mt-1"
:label="$t('login.userName')"
variant="solo"
>
</v-text-field>
</v-col>
<v-col cols="12" sm="4">
<v-text-field
v-model="data.searchForm.userName1"
clearable
hide-details
density="comfortable"
class="searchInput ml-5 mt-1"
:label="$t('login.userName')"
variant="solo"
>
</v-text-field>
</v-col>
<v-col cols="12" sm="4">
<v-text-field
v-model="data.searchForm.userName2"
clearable
hide-details
density="comfortable"
class="searchInput ml-5 mt-1"
:label="$t('login.userName')"
variant="solo"
>
</v-text-field>
</v-col>
</v-row> -->
</v-col>
</v-row>
</div>
<!-- Table -->
<div
class="mt-5"
:style="{
height: cardHeight
}"
>
<vxe-table ref="xTable" :data="data.tableData" :height="tableHeight" align="center">
<template #empty>
{{ i18n.global.t('system.page.noData') }}
</template>
<vxe-column type="seq" width="60"></vxe-column>
<vxe-column field="company_name" :title="$t('base.companySetting.company_name')"></vxe-column>
<vxe-column field="city" :title="$t('base.companySetting.city')"></vxe-column>
<vxe-column field="address" :title="$t('base.companySetting.address')"></vxe-column>
<vxe-column field="manager" :title="$t('base.companySetting.manager')"></vxe-column>
<vxe-column field="contact_tel" :title="$t('base.companySetting.contact_tel')"></vxe-column>
<vxe-column field="operate" :title="$t('system.page.operate')" width="160" :resizable="false" show-overflow>
<template #default="{ row }">
<tooltip-btn
:flat="true"
icon="mdi-pencil-outline"
:tooltip-text="$t('system.page.edit')"
@click="method.editRow(row)"
></tooltip-btn>
<tooltip-btn
:flat="true"
icon="mdi-delete-outline"
:tooltip-text="$t('system.page.delete')"
:icon-color="errorColor"
@click="method.deleteRow(row)"
></tooltip-btn>
</template>
</vxe-column>
</vxe-table>
</div>
</v-card-text>
</v-card>
</div>
<!-- Add or modify data mode window -->
<addOrUpdateDialog :show-dialog="data.showDialog" :form="data.dialogForm" @close="method.closeDialog" @saveSuccess="method.saveSuccess" />
</div>
</template>
<script lang="ts" setup>
import { computed, reactive, onMounted, ref } from 'vue'
import { computedCardHeight, computedTableHeight, errorColor } from '@/constant/style'
import tooltipBtn from '@/components/tooltip-btn.vue'
import { CompanyVO, DataProps } from '@/types/Base/CompanySetting'
import { getCompanyAll, deleteCompany } from '@/api/base/companySetting'
import { hookComponent } from '@/components/system'
import addOrUpdateDialog from './add-or-update-company.vue'
import i18n from '@/languages/i18n'
import { exportData } from '@/utils/exportTable'
const xTable = ref()
const data: DataProps = reactive({
// searchForm: {
// userName: '',
// userName1: '',
// userName2: ''
// },
tableData: [],
// Dialog info
showDialog: false,
dialogForm: {
id: 0,
company_name: '',
city: '',
address: '',
manager: '',
contact_tel: ''
}
})
const method = reactive({
sureSearch: () => {
// console.log(data.searchForm)
},
// Find Data by Pagination
getCompanyList: async () => {
const { data: res } = await getCompanyAll()
if (!res.isSuccess) {
hookComponent.$message({
type: 'error',
content: res.errorMessage
})
return
}
data.tableData = res.data
},
// Add user
add: () => {
data.dialogForm = {
id: 0,
company_name: '',
city: '',
address: '',
manager: '',
contact_tel: ''
}
data.showDialog = true
},
// Shut add or update dialog
closeDialog: () => {
data.showDialog = false
},
// after Add or update success.
saveSuccess: () => {
method.refresh()
method.closeDialog()
},
// Refresh data
refresh: () => {
method.getCompanyList()
},
editRow(row: CompanyVO) {
data.dialogForm = JSON.parse(JSON.stringify(row))
data.showDialog = true
},
deleteRow(row: CompanyVO) {
hookComponent.$dialog({
content: i18n.global.t('system.tips.beforeDeleteMessage'),
handleConfirm: async () => {
if (row.id) {
const { data: res } = await deleteCompany(row.id)
if (!res.isSuccess) {
hookComponent.$message({
type: 'error',
content: res.errorMessage
})
return
}
hookComponent.$message({
type: 'success',
content: `${ i18n.global.t('system.page.delete') }${ i18n.global.t('system.tips.success') }`
})
method.refresh()
}
}
})
},
// Export table
exportTable: () => {
const $table = xTable.value
exportData({
table: $table,
filename: i18n.global.t('router.sideBar.companySetting'),
columnFilterMethod({ column }: any) {
return !['checkbox'].includes(column?.type) && !['operate'].includes(column?.field)
}
})
}
})
onMounted(async () => {
await method.getCompanyList()
})
const cardHeight = computed(() => computedCardHeight({ hasTab: false }))
const tableHeight = computed(() => computedTableHeight({ hasTab: false, hasPager: false }))
</script>
<style scoped lang="less">
.operateArea {
width: 100%;
min-width: 760px;
display: flex;
align-items: center;
border-radius: 10px;
padding: 0 10px;
}
.col {
display: flex;
align-items: center;
}
</style>
2、窗体代码
<template>
<v-dialog v-model="isShow" :width="'30%'" transition="dialog-top-transition" :persistent="true">
<template #default>
<v-card>
<v-toolbar color="white" :title="`${$t('router.sideBar.companySetting')}`"></v-toolbar>
<v-card-text>
<v-form ref="formRef">
<v-text-field
v-model="data.form.company_name"
:label="$t('base.companySetting.company_name')"
:rules="data.rules.company_name"
variant="outlined"
></v-text-field>
<v-text-field v-model="data.form.city" :label="$t('base.companySetting.city')" :rules="data.rules.city" variant="outlined"></v-text-field>
<v-text-field
v-model="data.form.address"
:label="$t('base.companySetting.address')"
:rules="data.rules.address"
variant="outlined"
></v-text-field>
<v-text-field
v-model="data.form.manager"
:label="$t('base.companySetting.manager')"
:rules="data.rules.manager"
variant="outlined"
></v-text-field>
<v-text-field
v-model="data.form.contact_tel"
:label="$t('base.companySetting.contact_tel')"
:rules="data.rules.contact_tel"
variant="outlined"
></v-text-field>
</v-form>
</v-card-text>
<v-card-actions class="justify-end">
<v-btn variant="text" @click="method.closeDialog">{{ $t('system.page.close') }}</v-btn>
<v-btn color="primary" variant="text" @click="method.submit">{{ $t('system.page.submit') }}</v-btn>
</v-card-actions>
</v-card>
</template>
</v-dialog>
</template>
<script lang="ts" setup>
import { reactive, computed, ref, watch } from 'vue'
import { CompanyVO } from '@/types/Base/CompanySetting'
import i18n from '@/languages/i18n'
import { hookComponent } from '@/components/system/index'
import { addCompany, updateCompany } from '@/api/base/companySetting'
import { StringLength } from '@/utils/dataVerification/formRule'
const formRef = ref()
const emit = defineEmits(['close', 'saveSuccess'])
const props = defineProps<{
showDialog: boolean
form: CompanyVO
}>()
const isShow = computed(() => props.showDialog)
const dialogTitle = computed(() => {
if (props.form.id && props.form.id > 0) {
return 'update'
}
return 'add'
})
const data = reactive({
form: ref<CompanyVO>({
id: 0,
company_name: '',
city: '',
address: '',
manager: '',
contact_tel: ''
}),
rules: {
company_name: [
(val: string) => !!val || `${ i18n.global.t('system.checkText.mustInput') }${ i18n.global.t('base.companySetting.company_name') }!`,
(val: string) => StringLength(val, 0, 256) === '' || StringLength(val, 0, 256)
],
city: [(val: string) => StringLength(val, 0, 128) === '' || StringLength(val, 0, 128)],
address: [(val: string) => StringLength(val, 0, 256) === '' || StringLength(val, 0, 256)],
manager: [(val: string) => StringLength(val, 0, 64) === '' || StringLength(val, 0, 64)],
contact_tel: [(val: string) => StringLength(val, 0, 64) === '' || StringLength(val, 0, 64)]
}
})
const method = reactive({
closeDialog: () => {
emit('close')
},
submit: async () => {
const { valid } = await formRef.value.validate()
if (valid) {
const { data: res } = dialogTitle.value === 'add' ? await addCompany(data.form) : await updateCompany(data.form)
if (!res.isSuccess) {
hookComponent.$message({
type: 'error',
content: res.errorMessage
})
return
}
hookComponent.$message({
type: 'success',
content: `${ i18n.global.t('system.page.submit') }${ i18n.global.t('system.tips.success') }`
})
emit('saveSuccess')
} else {
hookComponent.$message({
type: 'error',
content: i18n.global.t('system.checkText.checkFormFail')
})
}
}
})
watch(
() => isShow.value,
(val) => {
if (val) {
data.form = props.form
}
}
)
</script>
<style scoped lang="less">
.v-form {
div {
margin-bottom: 7px;
}
}
</style>
2.2 接口代码
import http from '@/utils/http/request'
import { CompanyVO } from '@/types/Base/CompanySetting'
// Get all
export const getCompanyAll = () => http({
url: '/company/all',
method: 'get'
})
// Add a new form
export const addCompany = (data: CompanyVO) => http({
url: '/company',
method: 'post',
data
})
// Update form
export const updateCompany = (data: CompanyVO) => http({
url: '/company',
method: 'put',
data
})
// Delete form
export const deleteCompany = (id: number) => http({
url: '/company',
method: 'delete',
params: {
id
}
})
[Route("company")]
[ApiController]
[ApiExplorerSettings(GroupName = "Base")]
public class CompanyController: BaseController
{
#region Args
/// <summary>
/// company Service
/// </summary>
private readonly ICompanyService _companyService;
/// <summary>
/// Localizer Service
/// </summary>
private readonly IStringLocalizer<ModernWMS.Core.MultiLanguage> _stringLocalizer;
#endregion
#region constructor
/// <summary>
/// constructor
/// </summary>
/// <param name="companyService">company Service</param>
/// <param name="stringLocalizer">Localizer</param>
public CompanyController(
ICompanyService companyService
, IStringLocalizer<ModernWMS.Core.MultiLanguage> stringLocalizer
)
{
this._companyService = companyService;
this._stringLocalizer = stringLocalizer;
}
#endregion
#region Api
/// <summary>
/// Get all records
/// </summary>
/// <returns>args</returns>
[HttpGet("all")]
public async Task<ResultModel<List<CompanyViewModel>>> GetAllAsync()
{
var data = await _companyService.GetAllAsync(CurrentUser);
if (data.Any())
{
return ResultModel<List<CompanyViewModel>>.Success(data);
}
else
{
return ResultModel<List<CompanyViewModel>>.Success(new List<CompanyViewModel>());
}
}
/// <summary>
/// get a record by id
/// </summary>
/// <returns>args</returns>
[HttpGet]
public async Task<ResultModel<CompanyViewModel>> GetAsync(int id)
{
var data = await _companyService.GetAsync(id);
if (data != null && data.id > 0)
{
return ResultModel<CompanyViewModel>.Success(data);
}
else
{
return ResultModel<CompanyViewModel>.Error(_stringLocalizer["not_exists_entity"]);
}
}
/// <summary>
/// add a new record
/// </summary>
/// <param name="viewModel">args</param>
/// <returns></returns>
[HttpPost]
public async Task<ResultModel<int>> AddAsync(CompanyViewModel viewModel)
{
var (id, msg) = await _companyService.AddAsync(viewModel, CurrentUser);
if (id > 0)
{
return ResultModel<int>.Success(id);
}
else
{
return ResultModel<int>.Error(msg);
}
}
/// <summary>
/// update a record
/// </summary>
/// <param name="viewModel">args</param>
/// <returns></returns>
[HttpPut]
public async Task<ResultModel<bool>> UpdateAsync(CompanyViewModel viewModel)
{
var (flag, msg) = await _companyService.UpdateAsync(viewModel);
if (flag)
{
return ResultModel<bool>.Success(flag);
}
else
{
return ResultModel<bool>.Error(msg, 400, flag);
}
}
/// <summary>
/// delete a record
/// </summary>
/// <param name="id">id</param>
/// <returns></returns>
[HttpDelete]
public async Task<ResultModel<string>> DeleteAsync(int id)
{
var (flag, msg) = await _companyService.DeleteAsync(id);
if (flag)
{
return ResultModel<string>.Success(msg);
}
else
{
return ResultModel<string>.Error(msg);
}
}
#endregion
}
3.角色设置
3.1 页面代码
1、主页面代码
<template>
<div class="container">
<div>
<!-- Main Content -->
<v-card class="mt-5">
<v-card-text>
<div class="operateArea">
<v-row no-gutters>
<!-- Operate Btn -->
<v-col cols="12" sm="3" class="col">
<tooltip-btn icon="mdi-plus" :tooltip-text="$t('system.page.add')" @click="method.add()"></tooltip-btn>
<tooltip-btn icon="mdi-refresh" :tooltip-text="$t('system.page.refresh')" @click="method.refresh()"></tooltip-btn>
<tooltip-btn icon="mdi-export-variant" :tooltip-text="$t('system.page.export')" @click="method.exportTable"></tooltip-btn>
</v-col>
<!-- Search Input -->
<v-col cols="12" sm="9">
<!-- <v-row no-gutters @keyup.enter="method.sureSearch">
<v-col cols="12" sm="4">
<v-text-field
v-model="data.searchForm.userName"
clearable
hide-details
density="comfortable"
class="searchInput ml-5 mt-1"
:label="$t('login.userName')"
variant="solo"
>
</v-text-field>
</v-col>
<v-col cols="12" sm="4">
<v-text-field
v-model="data.searchForm.userName1"
clearable
hide-details
density="comfortable"
class="searchInput ml-5 mt-1"
:label="$t('login.userName')"
variant="solo"
>
</v-text-field>
</v-col>
<v-col cols="12" sm="4">
<v-text-field
v-model="data.searchForm.userName2"
clearable
hide-details
density="comfortable"
class="searchInput ml-5 mt-1"
:label="$t('login.userName')"
variant="solo"
>
</v-text-field>
</v-col>
</v-row> -->
</v-col>
</v-row>
</div>
<!-- Table -->
<div
class="mt-5"
:style="{
height: cardHeight
}"
>
<vxe-table ref="xTable" :data="data.tableData" :height="tableHeight" align="center">
<template #empty>
{{ i18n.global.t('system.page.noData') }}
</template>
<vxe-column type="seq" width="60"></vxe-column>
<vxe-column field="role_name" :title="$t('base.userRoleSetting.role_name')"></vxe-column>
<vxe-column field="is_valid" :title="$t('base.userRoleSetting.is_valid')">
<template #default="{ row, column }">
<span>{{ row[column.property] ? $t('system.combobox.yesOrNo.yes') : $t('system.combobox.yesOrNo.no') }}</span>
</template>
</vxe-column>
<vxe-column field="operate" :title="$t('system.page.operate')" width="160" :resizable="false" show-overflow>
<template #default="{ row }">
<tooltip-btn
:flat="true"
icon="mdi-pencil-outline"
:tooltip-text="$t('system.page.edit')"
@click="method.editRow(row)"
></tooltip-btn>
<tooltip-btn
:flat="true"
icon="mdi-delete-outline"
:tooltip-text="$t('system.page.delete')"
:icon-color="errorColor"
@click="method.deleteRow(row)"
></tooltip-btn>
</template>
</vxe-column>
</vxe-table>
</div>
</v-card-text>
</v-card>
</div>
<!-- Add or modify data mode window -->
<addOrUpdateDialog :show-dialog="data.showDialog" :form="data.dialogForm" @close="method.closeDialog" @saveSuccess="method.saveSuccess" />
</div>
</template>
<script lang="ts" setup>
import { computed, reactive, onMounted, ref } from 'vue'
import { computedCardHeight, computedTableHeight, errorColor } from '@/constant/style'
import tooltipBtn from '@/components/tooltip-btn.vue'
import { DataProps, UserRoleVO } from '@/types/Base/UserRoleSetting'
import { getUserRoleAll, deleteUserRole } from '@/api/base/userRoleSetting'
import { hookComponent } from '@/components/system'
import addOrUpdateDialog from './add-or-update-user-role.vue'
import i18n from '@/languages/i18n'
import { exportData } from '@/utils/exportTable'
const xTable = ref()
const data: DataProps = reactive({
// searchForm: {
// userName: '',
// userName1: '',
// userName2: ''
// },
tableData: [],
// Dialog info
showDialog: false,
dialogForm: {
id: 0,
role_name: '',
is_valid: true
}
})
const method = reactive({
sureSearch: () => {
// console.log(data.searchForm)
},
// Find Data by Pagination
getUserRoleList: async () => {
const { data: res } = await getUserRoleAll()
if (!res.isSuccess) {
hookComponent.$message({
type: 'error',
content: res.errorMessage
})
return
}
data.tableData = res.data
},
// Add user
add: () => {
data.dialogForm = {
id: 0,
role_name: '',
is_valid: true
}
data.showDialog = true
},
// Shut add or update dialog
closeDialog: () => {
data.showDialog = false
},
// after Add or update success.
saveSuccess: () => {
method.refresh()
method.closeDialog()
},
// Refresh data
refresh: () => {
method.getUserRoleList()
},
editRow(row: UserRoleVO) {
data.dialogForm = JSON.parse(JSON.stringify(row))
data.showDialog = true
},
deleteRow(row: UserRoleVO) {
hookComponent.$dialog({
content: i18n.global.t('system.tips.beforeDeleteMessage'),
handleConfirm: async () => {
if (row.id) {
const { data: res } = await deleteUserRole(row.id)
if (!res.isSuccess) {
hookComponent.$message({
type: 'error',
content: res.errorMessage
})
return
}
hookComponent.$message({
type: 'success',
content: `${ i18n.global.t('system.page.delete') }${ i18n.global.t('system.tips.success') }`
})
method.refresh()
}
}
})
},
// Export table
exportTable: () => {
const $table = xTable.value
exportData({
table: $table,
filename: i18n.global.t('router.sideBar.userRoleSetting'),
columnFilterMethod({ column }: any) {
return !['checkbox'].includes(column?.type) && !['operate'].includes(column?.field)
}
})
}
})
onMounted(async () => {
await method.getUserRoleList()
})
const cardHeight = computed(() => computedCardHeight({ hasTab: false }))
const tableHeight = computed(() => computedTableHeight({ hasTab: false, hasPager: false }))
</script>
<style scoped lang="less">
.operateArea {
width: 100%;
min-width: 760px;
display: flex;
align-items: center;
border-radius: 10px;
padding: 0 10px;
}
.col {
display: flex;
align-items: center;
}
</style>
2、窗体代码
3.2 接口代码
#region Api
/// <summary>
/// save all records
/// </summary>
/// <param name="viewModels">viewmodel</param>
/// <returns></returns>
[HttpPost("save")]
public async Task<ResultModel<string>> SaveAllAsync(List<UserroleViewModel> viewModels)
{
var (flag,msg) = await _userroleService.BulkSaveAsync(viewModels, CurrentUser);
if(flag)
{
return ResultModel<string>.Success(msg);
}
return ResultModel<string>.Error(msg);
}
/// <summary>
/// get all records
/// </summary>
/// <returns>args</returns>
[HttpGet("all")]
public async Task<ResultModel<List<UserroleViewModel>>> GetAllAsync()
{
var data = await _userroleService.GetAllAsync(CurrentUser);
if (data.Any())
{
return ResultModel<List<UserroleViewModel>>.Success(data);
}
else
{
return ResultModel<List<UserroleViewModel>>.Success(new List<UserroleViewModel>());
}
}
/// <summary>
/// get a record by id
/// </summary>
/// <returns>args</returns>
[HttpGet]
public async Task<ResultModel<UserroleViewModel>> GetAsync(int id)
{
var data = await _userroleService.GetAsync(id);
if (data!=null)
{
return ResultModel<UserroleViewModel>.Success(data);
}
else
{
return ResultModel<UserroleViewModel>.Error(_stringLocalizer["exists_entity"]);
}
}
/// <summary>
/// add a new record
/// </summary>
/// <param name="viewModel">args</param>
/// <returns></returns>
[HttpPost]
public async Task<ResultModel<int>> AddAsync(UserroleViewModel viewModel)
{
var (id, msg) = await _userroleService.AddAsync(viewModel,CurrentUser);
if (id > 0)
{
return ResultModel<int>.Success(id);
}
else
{
return ResultModel<int>.Error(msg);
}
}
/// <summary>
/// update a record
/// </summary>
/// <param name="viewModel">args</param>
/// <returns></returns>
[HttpPut]
public async Task<ResultModel<bool>> UpdateAsync(UserroleViewModel viewModel)
{
var (flag, msg) = await _userroleService.UpdateAsync(viewModel, CurrentUser);
if (flag)
{
return ResultModel<bool>.Success(flag);
}
else
{
return ResultModel<bool>.Error(msg, 400, flag);
}
}
/// <summary>
/// delete a record
/// </summary>
/// <param name="id">id</param>
/// <returns></returns>
[HttpDelete]
public async Task<ResultModel<string>> DeleteAsync(int id)
{
var (flag, msg) = await _userroleService.DeleteAsync(id);
if (flag)
{
return ResultModel<string>.Success(msg);
}
else
{
return ResultModel<string>.Error(msg);
}
}
#endregion
【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)