迁移班组管理功能
This commit is contained in:
19
docs/功能测试-班组管理.md
Normal file
19
docs/功能测试-班组管理.md
Normal file
@@ -0,0 +1,19 @@
|
||||
# 功能测试任务列表 - 班组管理
|
||||
|
||||
> 路由:`/system_settings/organization/production_team_manage`
|
||||
|
||||
| 序号 | 测试项 | 操作步骤 | 预期结果 | 结果 |
|
||||
|---|---|---|---|---|
|
||||
| 1 | 页面入口 | 从菜单进入“班组管理” | 页面正常打开,展示班组名称、所属厂区、所属产线、创建/更新时间 | ☐ |
|
||||
| 2 | 条件查询 | 输入班组名称、选择厂区/产线或创建时间后查询 | 列表按条件刷新 | ☐ |
|
||||
| 3 | 新增校验 | 点击新增,不填班组名称、厂区或产线直接确认 | 显示必填校验,不提交 | ☐ |
|
||||
| 4 | 新增班组 | 填写班组信息,添加成员并设置班组长后确认 | 提示操作成功,列表出现新班组 | ☐ |
|
||||
| 5 | 班组长唯一性 | 添加多个成员并尝试设置两个班组长 | 第二个班组长被拦截,提示只允许一个班组长 | ☐ |
|
||||
| 6 | 编辑班组 | 点击编辑,修改成员或班组信息后确认 | 保存成功,重新打开可看到新数据 | ☐ |
|
||||
| 7 | 删除成员 | 编辑已有班组,删除已有成员 | 成员删除成功,列表刷新 | ☐ |
|
||||
| 8 | 单条删除 | 点击行内删除并确认 | 班组删除成功 | ☐ |
|
||||
| 9 | 批量删除 | 勾选多条数据后点击批量删除并确认 | 所选班组删除成功 | ☐ |
|
||||
| 10 | 导入模板 | 点击导入后下载模板 | 浏览器下载班组导入模板 | ☐ |
|
||||
| 11 | 导入数据 | 选择合法 xls/xlsx 文件并确认导入 | 预览数据正确,提交后提示成功并刷新列表 | ☐ |
|
||||
| 12 | 导出任务 | 点击导出并确认 | 提示下载任务创建成功 | ☐ |
|
||||
| 13 | 权限按钮 | 使用缺少权限账号进入页面 | 对应新增/编辑/删除/导入/导出按钮隐藏或不可操作 | ☐ |
|
||||
@@ -3,8 +3,8 @@
|
||||
> 根据 `后台Webman界面截图对照表.md` 生成。状态以当前 V2 项目中已落地的页面目录为准。
|
||||
|
||||
- 总功能数:79
|
||||
- 已迁移:75
|
||||
- 未迁移:4
|
||||
- 已迁移:76
|
||||
- 未迁移:3
|
||||
|
||||
| 状态 | 一级模块 | 二级模块 | 三级模块 | 功能说明 | V2 目标路径 |
|
||||
|:---:|---|---|---|---|---|
|
||||
@@ -26,7 +26,7 @@
|
||||
| ✅ | 生产配置 (Production Master Data) | 物料模型 (Material Model) | BOM物料清单 (Bill of Materials) | 产品BOM管理 | `src/views/production-master-data/material-model/bill-of-materials/` |
|
||||
| ✅ | 生产配置 (Production Master Data) | 物料模型 (Material Model) | 计量单位 (Unit of Measure) | 计量单位配置与管理 | `src/views/production-master-data/material-model/material-unit/` |
|
||||
| ✅ | 生产配置 (Production Master Data) | SPC采集模型 (SPC Configuration) | SPC采集配置 (Data Collection Configuration) | 配置SPC采集参数 | `src/views/production-master-data/spc-configuration/data-collection-configuration/` |
|
||||
| ⬜ | 生产配置 (Production Master Data) | 班组模型 (Team Model) | 班组管理 (Team Management) | 管理生产班组 | 待确认 |
|
||||
| ✅ | 生产配置 (Production Master Data) | 班组模型 (Team Model) | 班组管理 (Team Management) | 管理生产班组 | `src/views/production-master-data/team-model/team-management/` |
|
||||
| ⬜ | 生产配置 (Production Master Data) | 班组模型 (Team Model) | 班次管理 (Shift Management) | 管理生产班次 | 待确认 |
|
||||
| ⬜ | 生产配置 (Production Master Data) | 班组模型 (Team Model) | 排班日历 (Scheduling Calendar) | 查看排班日历 | 待确认 |
|
||||
| ✅ | 设备模型 (Equipment Management) | 设备类别 (Equipment Category) | 设备类别 (Equipment Category) | 管理设备类别 | `src/views/equipment-management/equipment-model/equipment-category/` |
|
||||
|
||||
24
src/api/production-master-data/team-management.js
Normal file
24
src/api/production-master-data/team-management.js
Normal file
@@ -0,0 +1,24 @@
|
||||
import { request } from '@/api/_service'
|
||||
|
||||
const BASE = 'system_settings/organization/production_team_manage/'
|
||||
const MEMBER_BASE = 'system_settings/organization/production_members_manage/'
|
||||
|
||||
function params (method, data = {}) {
|
||||
return { method: `system_settings_organization_production_team_manage_${method}`, platform: 'background', ...data }
|
||||
}
|
||||
|
||||
function memberParams (method, data = {}) {
|
||||
return { method: `system_settings_organization_production_members_manage_${method}`, platform: 'background', ...data }
|
||||
}
|
||||
|
||||
export function getTeamAll (data) { return request({ url: BASE + 'all', method: 'get', params: params('all', data) }) }
|
||||
export function getTeamList (data) { return request({ url: BASE + 'list', method: 'get', params: params('list', data) }) }
|
||||
export function createTeam (data) { return request({ url: BASE + 'create', method: 'post', data: params('create', data) }) }
|
||||
export function editTeam (data) { return request({ url: BASE + 'edit', method: 'put', data: params('edit', data) }) }
|
||||
export function deleteTeam (data) { return request({ url: BASE + 'delete', method: 'delete', data: params('delete', data) }) }
|
||||
export function getTeamImportTemplate (data) { return request({ url: BASE + 'get_import_template', method: 'post', responseType: 'blob', data: params('get_import_template', data) }) }
|
||||
export function importTeamData (data) { return request({ url: BASE + 'data_import', method: 'post', data: params('data_import', data) }) }
|
||||
export function exportTeamTask (data) { return request({ url: BASE + 'data_export_task', method: 'post', data: params('data_export_task', data) }) }
|
||||
|
||||
export function getTeamMemberList (data) { return request({ url: MEMBER_BASE + 'list', method: 'get', params: memberParams('list', data) }) }
|
||||
export function deleteTeamMember (data) { return request({ url: MEMBER_BASE + 'delete', method: 'delete', data: memberParams('delete', data) }) }
|
||||
@@ -487,6 +487,70 @@
|
||||
"help": "Error/NG management is used to maintain equipment error types and product NG types"
|
||||
}
|
||||
},
|
||||
"team_model": {
|
||||
"team_management": {
|
||||
"search": "Search",
|
||||
"reset": "Reset",
|
||||
"add": "Add",
|
||||
"edit": "Edit",
|
||||
"delete": "Delete",
|
||||
"batch_delete": "Batch Delete",
|
||||
"import": "Import",
|
||||
"export": "Export",
|
||||
"confirm": "Confirm",
|
||||
"cancel": "Cancel",
|
||||
"prompt": "Notice",
|
||||
"operation": "Operation",
|
||||
"team_name": "Team Name",
|
||||
"enter_team_name": "Please enter team name",
|
||||
"area": "Area",
|
||||
"select_area": "Please select area",
|
||||
"production_line": "Production Line",
|
||||
"select_area_then_line": "Select area before line",
|
||||
"last_create_time": "Create Time",
|
||||
"select_create_time": "Please select create time",
|
||||
"start_time": "Start Time",
|
||||
"end_time": "End Time",
|
||||
"serial_number": "No.",
|
||||
"affiliated_factory": "Factory Area",
|
||||
"affiliated_production_line": "Production Line",
|
||||
"create_time": "Created At",
|
||||
"update_time": "Updated At",
|
||||
"add_team": "Add Team",
|
||||
"edit_team": "Edit Team",
|
||||
"please_select": "Please select",
|
||||
"please_select_factory_then_line": "Select factory before line",
|
||||
"select_affiliated_factory": "Please select factory",
|
||||
"select_affiliated_production_line": "Please select production line",
|
||||
"please_enter_team_name": "Please enter team name",
|
||||
"please_select_affiliated_factory": "Please select factory",
|
||||
"please_select_affiliated_production_line": "Please select production line",
|
||||
"length_2_to_20_characters": "Length must be 2-20 characters",
|
||||
"add_member": "Add Member",
|
||||
"member_name": "Member Name",
|
||||
"is_team_leader": "Team Leader",
|
||||
"yes": "Yes",
|
||||
"no": "No",
|
||||
"only_one_team_leader_allowed": "Only one team leader is allowed",
|
||||
"operation_successful": "Operation successful",
|
||||
"delete_team_confirm_message": "Are you sure to delete this team?",
|
||||
"batch_delete_confirm_message": "Are you sure to delete selected teams?",
|
||||
"please_select_table_data": "Please select table data first",
|
||||
"export_confirm_message": "Export current query result?",
|
||||
"download_task_created": "Download task created",
|
||||
"operation_cancelled": "Operation cancelled",
|
||||
"production_team_data_import": "Import Team Data",
|
||||
"upload_file_alert_title": "Import using the template format",
|
||||
"upload_file_alert_description": "Download the template before importing",
|
||||
"production_team_data_import_table": "Team Import Table",
|
||||
"select_file": "Select File",
|
||||
"download_template": "Download Template",
|
||||
"preview": "Preview",
|
||||
"please_import_department_data": "Please import team data first",
|
||||
"team_data_import_template": "Team Import Template",
|
||||
"upload_format_error": "Please upload xls or xlsx file"
|
||||
}
|
||||
},
|
||||
"spc_configuration": {
|
||||
"data_collection_configuration": {
|
||||
"search": "Search",
|
||||
|
||||
@@ -487,6 +487,70 @@
|
||||
"help": "异常不良管理用于维护设备的异常种类和产品的不良种类信息"
|
||||
}
|
||||
},
|
||||
"team_model": {
|
||||
"team_management": {
|
||||
"search": "查询",
|
||||
"reset": "重置",
|
||||
"add": "新增",
|
||||
"edit": "编辑",
|
||||
"delete": "删除",
|
||||
"batch_delete": "批量删除",
|
||||
"import": "导入",
|
||||
"export": "导出",
|
||||
"confirm": "确定",
|
||||
"cancel": "取消",
|
||||
"prompt": "提示",
|
||||
"operation": "操作",
|
||||
"team_name": "班组名称",
|
||||
"enter_team_name": "请输入班组名称",
|
||||
"area": "厂区",
|
||||
"select_area": "请选择厂区",
|
||||
"production_line": "产线",
|
||||
"select_area_then_line": "请先选择厂区再选择产线",
|
||||
"last_create_time": "创建时间",
|
||||
"select_create_time": "请选择创建时间",
|
||||
"start_time": "开始时间",
|
||||
"end_time": "结束时间",
|
||||
"serial_number": "序号",
|
||||
"affiliated_factory": "所属厂区",
|
||||
"affiliated_production_line": "所属产线",
|
||||
"create_time": "创建时间",
|
||||
"update_time": "更新时间",
|
||||
"add_team": "新增班组",
|
||||
"edit_team": "编辑班组",
|
||||
"please_select": "请选择",
|
||||
"please_select_factory_then_line": "请先选择厂区再选择产线",
|
||||
"select_affiliated_factory": "请选择所属厂区",
|
||||
"select_affiliated_production_line": "请选择所属产线",
|
||||
"please_enter_team_name": "请输入班组名称",
|
||||
"please_select_affiliated_factory": "请选择所属厂区",
|
||||
"please_select_affiliated_production_line": "请选择所属产线",
|
||||
"length_2_to_20_characters": "长度在 2 到 20 个字符",
|
||||
"add_member": "添加成员",
|
||||
"member_name": "成员名称",
|
||||
"is_team_leader": "是否班组长",
|
||||
"yes": "是",
|
||||
"no": "否",
|
||||
"only_one_team_leader_allowed": "只允许设置一个班组长",
|
||||
"operation_successful": "操作成功",
|
||||
"delete_team_confirm_message": "确定要删除该班组吗?",
|
||||
"batch_delete_confirm_message": "确定要删除所选班组吗?",
|
||||
"please_select_table_data": "请先选择表格数据",
|
||||
"export_confirm_message": "确定要导出当前查询结果吗?",
|
||||
"download_task_created": "下载任务创建成功",
|
||||
"operation_cancelled": "操作已取消",
|
||||
"production_team_data_import": "班组数据导入",
|
||||
"upload_file_alert_title": "请按模板格式导入文件",
|
||||
"upload_file_alert_description": "导入前请先下载模板并按模板字段填写",
|
||||
"production_team_data_import_table": "班组数据导入表",
|
||||
"select_file": "选择文件",
|
||||
"download_template": "下载模板",
|
||||
"preview": "预览",
|
||||
"please_import_department_data": "请先导入班组数据",
|
||||
"team_data_import_template": "班组数据导入模板",
|
||||
"upload_format_error": "请上传 xls 或 xlsx 文件"
|
||||
}
|
||||
},
|
||||
"spc_configuration": {
|
||||
"data_collection_configuration": {
|
||||
"search": "查询",
|
||||
|
||||
@@ -55,6 +55,12 @@ export default {
|
||||
name: `${pre}system_monitoring-setting`,
|
||||
meta: { ...meta, cache: true, title: '监控设置' },
|
||||
component: _import('system-administration/system-monitoring/monitoring-configuration')
|
||||
},
|
||||
{
|
||||
path: 'organization/production_team_manage',
|
||||
name: `${pre}organization-production_team_manage`,
|
||||
meta: { ...meta, cache: true, title: '班组管理' },
|
||||
component: _import('production-master-data/team-model/team-management')
|
||||
}
|
||||
])('system_settings-')
|
||||
}
|
||||
|
||||
@@ -0,0 +1,287 @@
|
||||
<template>
|
||||
<d2-container>
|
||||
<template #header>
|
||||
<div class="search-bar">
|
||||
<el-form :inline="true" size="mini">
|
||||
<el-form-item :label="$t(key('team_name'))">
|
||||
<el-input v-model.trim="search.name" :placeholder="$t(key('enter_team_name'))" clearable style="width:200px" @keyup.enter.native="onSearch" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t(key('area'))">
|
||||
<el-select v-model="search.area_id" :placeholder="$t(key('select_area'))" clearable filterable style="width:200px" @change="onSearchAreaChange">
|
||||
<el-option v-for="item in areaOptions" :key="item.value" :label="item.label" :value="item.value" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t(key('production_line'))">
|
||||
<el-select v-model="search.line_id" :placeholder="$t(key('select_area_then_line'))" clearable filterable style="width:200px">
|
||||
<el-option v-for="item in searchLineOptions" :key="item.value" :label="item.label" :value="item.value" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t(key('last_create_time'))">
|
||||
<el-date-picker v-model="search.create_time" type="datetimerange" value-format="yyyy-MM-dd HH:mm:ss" :start-placeholder="$t(key('start_time'))" :end-placeholder="$t(key('end_time'))" style="width:330px" />
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" icon="el-icon-search" @click="onSearch">{{ $t(key('search')) }}</el-button>
|
||||
<el-button icon="el-icon-refresh" @click="onReset">{{ $t(key('reset')) }}</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<page-table ref="pageTable" :columns="columns" :data="tableData" :loading="loading" :toolbar-buttons="toolbarButtons" :row-buttons="rowButtons" :pagination="pagination" auto-height @page-change="onPageChange" @selection-change="selectedRows = $event" />
|
||||
|
||||
<el-dialog :title="$t(dialogTitle)" :visible.sync="dialogVisible" width="80%" :close-on-click-modal="false" @close="closeDialog">
|
||||
<el-form ref="form" :model="formData" :rules="translatedRules" inline label-width="150px" size="small">
|
||||
<el-form-item :label="$t(key('team_name'))" prop="name"><el-input v-model="formData.name" /></el-form-item>
|
||||
<el-form-item :label="$t(key('affiliated_factory'))" prop="area_id">
|
||||
<el-select v-model="formData.area_id" clearable filterable :placeholder="$t(key('please_select'))" @change="onFormAreaChange">
|
||||
<el-option v-for="item in areaOptions" :key="item.value" :label="item.label" :value="item.value" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t(key('affiliated_production_line'))" prop="line_id">
|
||||
<el-select v-model="formData.line_id" clearable filterable :placeholder="$t(key('please_select_factory_then_line'))">
|
||||
<el-option v-for="item in formLineOptions" :key="item.value" :label="item.label" :value="item.value" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<el-divider />
|
||||
<el-button size="mini" type="success" icon="el-icon-plus" @click="addMember">{{ $t(key('add_member')) }}</el-button>
|
||||
<el-table :data="membersData" style="width:100%;margin-top:10px" border>
|
||||
<el-table-column :label="$t(key('member_name'))">
|
||||
<template slot-scope="scope">
|
||||
<el-select v-model="membersData[scope.$index].user_id" size="small" clearable filterable :placeholder="$t(key('please_select'))">
|
||||
<el-option v-for="item in userOptions" :key="item.value" :label="item.label" :value="item.value" />
|
||||
</el-select>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="$t(key('is_team_leader'))" width="220">
|
||||
<template slot-scope="scope">
|
||||
<el-switch v-model="membersData[scope.$index].is_main" :active-text="$t(key('yes'))" :inactive-text="$t(key('no'))" :active-value="1" :inactive-value="0" @change="val => onLeaderChange(val, scope.$index)" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="$t(key('operation'))" width="120">
|
||||
<template slot-scope="scope"><el-button type="danger" size="mini" icon="el-icon-delete" @click="deleteMember(scope.row, scope.$index)">{{ $t(key('delete')) }}</el-button></template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<span slot="footer">
|
||||
<el-button @click="closeDialog">{{ $t(key('cancel')) }}</el-button>
|
||||
<el-button type="primary" :loading="submitting" @click="submitDialog">{{ $t(key('confirm')) }}</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
|
||||
<el-dialog :title="$t(key('production_team_data_import'))" :visible.sync="importVisible" width="50%" :close-on-click-modal="false">
|
||||
<el-alert :title="$t(key('upload_file_alert_title'))" :description="$t(key('upload_file_alert_description'))" :closable="false" type="warning" />
|
||||
<el-upload class="upload" action="" :multiple="false" :auto-upload="false" :show-file-list="true" :file-list="importFileList" accept=".xls,.xlsx" :on-change="onImportFileChange">
|
||||
<el-button slot="trigger" size="mini" type="success">{{ $t(key('select_file')) }}</el-button>
|
||||
<el-button style="margin-left:10px" size="mini" type="primary" :loading="importLoading" @click.stop="downloadTemplate">{{ $t(key('download_template')) }}</el-button>
|
||||
</el-upload>
|
||||
<el-table :data="importRows" height="320" border style="margin-top:12px" v-loading="importTableLoading">
|
||||
<el-table-column prop="name" :label="$t(key('team_name'))" />
|
||||
<el-table-column prop="area_name" :label="$t(key('affiliated_factory'))" />
|
||||
<el-table-column prop="line_name" :label="$t(key('affiliated_production_line'))" />
|
||||
<el-table-column prop="members_user_name" :label="$t(key('member_name'))" />
|
||||
<el-table-column prop="is_main" :label="$t(key('is_team_leader'))" />
|
||||
</el-table>
|
||||
<span slot="footer">
|
||||
<el-button @click="importVisible = false">{{ $t(key('cancel')) }}</el-button>
|
||||
<el-button type="primary" @click="submitImport">{{ $t(key('confirm')) }}</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
</d2-container>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { useTableColumns } from '@/composables/useTableColumns'
|
||||
import { useTableButtons } from '@/composables/useTableButtons'
|
||||
import { i18nMixin } from '@/composables/useI18n'
|
||||
import { confirmMixin } from '@/composables/useConfirmHandle'
|
||||
import PageTable from '@/components/page-table'
|
||||
import { getFactoryAreaALL } from '@/api/production-master-data/factory-area'
|
||||
import { getProductionLineList } from '@/api/production-master-data/production-line'
|
||||
import { getUserList } from '@/api/system-administration/user'
|
||||
import { downloadRename, readExcel } from '@/utils/file'
|
||||
import { getTeamList, createTeam, editTeam, deleteTeam, getTeamImportTemplate, importTeamData, exportTeamTask, getTeamMemberList, deleteTeamMember } from '@/api/production-master-data/team-management'
|
||||
|
||||
function readPageData (res) {
|
||||
const data = res && res.data ? res.data : res
|
||||
if (!data) return { list: [], total: 0 }
|
||||
if (Array.isArray(data)) return { list: data, total: data.length }
|
||||
return { list: data.data || data.list || [], total: Number(data.count || data.total || 0) }
|
||||
}
|
||||
|
||||
export default {
|
||||
name: 'production-master-data-team-management',
|
||||
components: { PageTable },
|
||||
mixins: [i18nMixin('page.production_master_data.team_model.team_management'), confirmMixin],
|
||||
data () {
|
||||
return {
|
||||
loading: false,
|
||||
submitting: false,
|
||||
tableData: [],
|
||||
selectedRows: [],
|
||||
columns: [],
|
||||
toolbarButtons: [],
|
||||
rowButtons: [],
|
||||
search: { name: '', area_id: '', line_id: '', create_time: '' },
|
||||
pagination: { current: 1, size: 10, total: 0 },
|
||||
areaOptions: [],
|
||||
searchLineOptions: [],
|
||||
formLineOptions: [],
|
||||
userOptions: [],
|
||||
dialogVisible: false,
|
||||
dialogTitle: '',
|
||||
handleType: 'create',
|
||||
editId: '',
|
||||
leaderIndex: undefined,
|
||||
formData: { name: '', area_id: '', line_id: '' },
|
||||
membersData: [],
|
||||
importVisible: false,
|
||||
importFileList: [],
|
||||
importRows: [],
|
||||
importLoading: false,
|
||||
importTableLoading: false,
|
||||
rules: {
|
||||
name: [{ required: true, message: this.key('please_enter_team_name'), trigger: 'blur' }, { min: 2, max: 20, message: this.key('length_2_to_20_characters'), trigger: 'blur' }],
|
||||
area_id: [{ required: true, message: this.key('please_select_affiliated_factory'), trigger: 'change' }],
|
||||
line_id: [{ required: true, message: this.key('please_select_affiliated_production_line'), trigger: 'change' }]
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
translatedRules () {
|
||||
const next = {}
|
||||
Object.keys(this.rules).forEach(key => { next[key] = this.rules[key].map(rule => ({ ...rule, message: this.$t(rule.message) })) })
|
||||
return next
|
||||
}
|
||||
},
|
||||
created () {
|
||||
this.initOptions()
|
||||
this.columns = useTableColumns([
|
||||
{ prop: 'sort', label: this.key('serial_number'), width: 80 },
|
||||
{ prop: 'name', label: this.key('team_name'), minWidth: 140 },
|
||||
{ prop: 'area_name', label: this.key('affiliated_factory'), minWidth: 140 },
|
||||
{ prop: 'line_name', label: this.key('affiliated_production_line'), minWidth: 160 },
|
||||
{ prop: 'create_time', label: this.key('create_time'), minWidth: 160 },
|
||||
{ prop: 'update_time', label: this.key('update_time'), minWidth: 160 },
|
||||
{ prop: '_actions', label: this.key('operation'), width: 180, fixed: 'right' }
|
||||
])
|
||||
const btns = useTableButtons({
|
||||
toolbar: [
|
||||
{ key: 'add', label: this.key('add'), icon: 'el-icon-plus', type: 'primary', auth: '/system_settings/organization/production_team_manage/create', onClick: this.openAdd },
|
||||
{ key: 'batch_delete', label: this.key('batch_delete'), icon: 'el-icon-delete', color: 'danger', auth: '/system_settings/organization/production_team_manage/batch-delete', needSelection: true, onClick: this.handleBatchDelete },
|
||||
{ key: 'import', label: this.key('import'), icon: 'el-icon-upload2', type: 'success', auth: '/system_settings/organization/production_team_manage/import', onClick: this.openImport },
|
||||
{ key: 'export', label: this.key('export'), icon: 'el-icon-download', type: 'primary', auth: '/system_settings/organization/production_team_manage/export', onClick: this.handleExport }
|
||||
],
|
||||
row: [
|
||||
{ key: 'edit', label: this.key('edit'), icon: 'el-icon-edit', auth: '/system_settings/organization/production_team_manage/edit', onClick: this.openEdit },
|
||||
{ key: 'delete', label: this.key('delete'), icon: 'el-icon-delete', color: 'danger', auth: '/system_settings/organization/production_team_manage/delete', onClick: this.handleDelete }
|
||||
]
|
||||
}, this.$permission)
|
||||
this.toolbarButtons = btns.toolbarButtons
|
||||
this.rowButtons = btns.rowButtons
|
||||
this.fetchData()
|
||||
},
|
||||
methods: {
|
||||
async initOptions () {
|
||||
const [areas, users] = await Promise.all([getFactoryAreaALL({}), getUserList({ page_no: 1, page_size: 10000 })])
|
||||
this.areaOptions = ((areas && areas.data) || areas || []).map(item => ({ label: item.name, value: item.area_id || item.id }))
|
||||
const userPage = readPageData(users)
|
||||
this.userOptions = userPage.list.map(item => ({ label: item.nickname || item.name || item.username, value: item.user_id || item.id }))
|
||||
},
|
||||
async loadLines (areaId, target) {
|
||||
if (!areaId) { this[target] = []; return }
|
||||
const res = await getProductionLineList({ area_id: areaId, page_no: 1, page_size: 10000 })
|
||||
const { list } = readPageData(res)
|
||||
this[target] = list.map(item => ({ label: item.name, value: item.id }))
|
||||
},
|
||||
onSearchAreaChange (areaId) { this.search.line_id = ''; this.loadLines(areaId, 'searchLineOptions') },
|
||||
onFormAreaChange (areaId) { this.formData.line_id = ''; this.loadLines(areaId, 'formLineOptions') },
|
||||
async fetchData () {
|
||||
this.loading = true
|
||||
try {
|
||||
const res = await getTeamList({ ...this.search, page_no: this.pagination.current, page_size: this.pagination.size })
|
||||
const { list, total } = readPageData(res)
|
||||
this.tableData = list
|
||||
this.pagination.total = total
|
||||
} finally { this.loading = false }
|
||||
},
|
||||
onSearch () { this.pagination.current = 1; this.fetchData() },
|
||||
onReset () { this.search = { name: '', area_id: '', line_id: '', create_time: '' }; this.searchLineOptions = []; this.pagination.current = 1; this.fetchData() },
|
||||
onPageChange (page) { this.pagination.current = page.current; this.pagination.size = page.size; this.fetchData() },
|
||||
openAdd () { this.handleType = 'create'; this.dialogTitle = this.key('add_team'); this.dialogVisible = true },
|
||||
async openEdit (row) {
|
||||
this.handleType = 'edit'; this.dialogTitle = this.key('edit_team'); this.editId = row.id
|
||||
this.formData = { name: row.name, area_id: row.area_id, line_id: row.line_id }
|
||||
await this.loadLines(row.area_id, 'formLineOptions')
|
||||
const res = await getTeamMemberList({ production_team_id: row.id, page_no: 1, page_size: 10000 })
|
||||
const { list } = readPageData(res)
|
||||
this.membersData = list.map(item => ({ ...item, is_main: Number(item.is_main) }))
|
||||
this.leaderIndex = this.membersData.findIndex(item => Number(item.is_main) === 1)
|
||||
if (this.leaderIndex < 0) this.leaderIndex = undefined
|
||||
this.dialogVisible = true
|
||||
},
|
||||
addMember () { this.membersData.push({ user_id: '', is_main: 0 }) },
|
||||
onLeaderChange (val, index) {
|
||||
if (Number(val) === 1 && this.leaderIndex !== undefined && this.leaderIndex !== index) {
|
||||
this.$message.error(this.$t(this.key('only_one_team_leader_allowed')))
|
||||
this.membersData[index].is_main = 0
|
||||
} else if (this.leaderIndex === index && Number(val) === 0) this.leaderIndex = undefined
|
||||
else if (Number(val) === 1) this.leaderIndex = index
|
||||
},
|
||||
async deleteMember (row, index) {
|
||||
if (row.id) { await deleteTeamMember({ id: [row.id] }); this.$message.success(this.$t(this.key('operation_successful'))) }
|
||||
this.membersData.splice(index, 1)
|
||||
},
|
||||
submitDialog () {
|
||||
this.$refs.form.validate(async valid => {
|
||||
if (!valid) return
|
||||
this.submitting = true
|
||||
try {
|
||||
const payload = { ...this.formData, membersData: this.membersData }
|
||||
if (this.handleType === 'create') await createTeam(payload)
|
||||
else await editTeam({ ...payload, id: this.editId })
|
||||
this.$message.success(this.$t(this.key('operation_successful')))
|
||||
this.closeDialog(); this.fetchData()
|
||||
} finally { this.submitting = false }
|
||||
})
|
||||
},
|
||||
closeDialog () { this.dialogVisible = false; this.formData = { name: '', area_id: '', line_id: '' }; this.membersData = []; this.formLineOptions = []; this.leaderIndex = undefined; this.editId = '' },
|
||||
async handleDelete (row) {
|
||||
const cancelled = await this.$confirmAction({ message: this.key('delete_team_confirm_message'), title: this.key('prompt'), confirmButtonText: this.key('confirm'), cancelButtonText: this.key('cancel') }, () => deleteTeam({ id: [row.id] }))
|
||||
if (cancelled) return
|
||||
this.$message.success(this.$t(this.key('operation_successful'))); this.fetchData()
|
||||
},
|
||||
async handleBatchDelete () {
|
||||
if (!this.selectedRows.length) { this.$message.error(this.$t(this.key('please_select_table_data'))); return }
|
||||
const cancelled = await this.$confirmAction({ message: this.key('batch_delete_confirm_message'), title: this.key('prompt'), confirmButtonText: this.key('confirm'), cancelButtonText: this.key('cancel') }, () => deleteTeam({ id: this.selectedRows.map(item => item.id) }))
|
||||
if (cancelled) return
|
||||
this.$message.success(this.$t(this.key('operation_successful'))); this.fetchData()
|
||||
},
|
||||
openImport () { this.importFileList = []; this.importRows = []; this.importVisible = true },
|
||||
async downloadTemplate () { this.importLoading = true; try { const res = await getTeamImportTemplate({}); downloadRename(res, 'xlsx', this.$t(this.key('team_data_import_template'))) } finally { this.importLoading = false } },
|
||||
async onImportFileChange (file) {
|
||||
if (!file || !/\.(xls|xlsx)$/i.test(file.name)) { this.$message.error(this.$t(this.key('upload_format_error'))); return }
|
||||
this.importFileList = [file]
|
||||
this.importTableLoading = true
|
||||
try {
|
||||
const rows = await readExcel(file.raw)
|
||||
this.importRows = rows.map(row => ({ name: row['班组名称'], area_name: row['所属厂区'], line_name: row['所属产线'], members_user_name: row['成员名称'], is_main: row['是否班组组长'] }))
|
||||
} finally { this.importTableLoading = false }
|
||||
},
|
||||
async submitImport () {
|
||||
if (!this.importRows.length) { this.$message.error(this.$t(this.key('please_import_department_data'))); return }
|
||||
await importTeamData({ import_data: JSON.stringify(this.importRows) })
|
||||
this.$message.success(this.$t(this.key('operation_successful'))); this.importVisible = false; this.fetchData()
|
||||
},
|
||||
async handleExport () {
|
||||
const cancelled = await this.$confirmAction({ message: this.key('export_confirm_message'), title: this.key('prompt'), confirmButtonText: this.key('confirm'), cancelButtonText: this.key('cancel') }, () => exportTeamTask({ ...this.search, action: 'download' }))
|
||||
if (cancelled) return
|
||||
this.$message.success(this.$t(this.key('download_task_created')))
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.search-bar { padding: 10px 0; }
|
||||
/deep/ .el-form-item--mini.el-form-item { margin-bottom: 4px; }
|
||||
</style>
|
||||
Reference in New Issue
Block a user