feat: 修改光芯OA审批的BUG与新增导出功能

This commit is contained in:
TianyangZhang 2026-03-23 09:50:09 +08:00
parent 12b0f280d9
commit a994cbc10d
27 changed files with 1124 additions and 760 deletions

View File

@ -4,7 +4,7 @@ NODE_ENV = development
# 标题 # 标题
# VUE_APP_TITLE = '曲阳金隅安全智能管控平台' # VUE_APP_TITLE = '曲阳金隅安全智能管控平台'
# VUE_APP_TITLE = '托克逊能源管理平台' # VUE_APP_TITLE = '托克逊能源管理平台'
VUE_APP_TITLE = '中建材光科技有限公司' VUE_APP_TITLE = '中建材光科技有限公司'
# VUE_APP_TITLE = '超低排放系统' # VUE_APP_TITLE = '超低排放系统'
VUE_APP_PJ = 'gx' VUE_APP_PJ = 'gx'
@ -21,20 +21,28 @@ VUE_APP_PJ = 'gx'
# VUE_APP_BASEURL = http://10.50.211.228:2250/ # VUE_APP_BASEURL = http://10.50.211.228:2250/
# VUE_APP_BASEURL = http://127.0.0.1:8887 VUE_APP_API_BASEURL = http://127.0.0.1:2226/api
# VUE_APP_BASEURL = http://127.0.0.1:226 VUE_APP_BASEURL = http://127.0.0.1:2226
# #光子 # 托克逊
# VUE_APP_API_BASEURL = http://tkx.xxhhcty.xyz:8080/api # VUE_APP_API_BASEURL = http://10.50.211.228:2250/api
# VUE_APP_BASEURL = http://tkx.xxhhcty.xyz:8080 # VUE_APP_BASEURL = http://10.50.211.228:2250/
# 光芯 # 光芯
VUE_APP_API_BASEURL = http://49.232.14.174:2226/api # VUE_APP_API_BASEURL = http://127.0.0.1:2226/api
VUE_APP_BASEURL = http://49.232.14.174:2226 # VUE_APP_BASEURL = http://127.0.0.1:2226
# 光芯线上
# VUE_APP_API_BASEURL = http://gxerp.xxhhcty.xyz:8080/api
# VUE_APP_BASEURL = http://gxerp.xxhhcty.xyz:8080
# # 凌源 bh # # 凌源 bh
# VUE_APP_API_BASEURL = http://lybh.xxhhcty.xyz:8080/api # VUE_APP_API_BASEURL = http://lybh.xxhhcty.xyz:8080/api
# VUE_APP_BASEURL = http://lybh.xxhhcty.xyz:8080/ # VUE_APP_BASEURL = http://lybh.xxhhcty.xyz:8080/
# 凌源 sl
# VUE_APP_API_BASEURL = http://lysl.xxhhcty.xyz:8080/api
# VUE_APP_BASEURL = http://lysl.xxhhcty.xyz:8080/
# 本地端口 # 本地端口
VUE_APP_PORT = 2800 VUE_APP_PORT = 2800

View File

@ -4,8 +4,7 @@
"private": true, "private": true,
"scripts": { "scripts": {
"serve": "vue-cli-service serve", "serve": "vue-cli-service serve",
"build": "vue-cli-service build --report", "build": "vue-cli-service build --report"
"lint": "vue-cli-service lint"
}, },
"dependencies": { "dependencies": {
"@element-plus/icons-vue": "2.0.10", "@element-plus/icons-vue": "2.0.10",
@ -49,40 +48,11 @@
}, },
"devDependencies": { "devDependencies": {
"@babel/core": "7.21.00", "@babel/core": "7.21.00",
"@babel/eslint-parser": "7.19.1",
"@vue/cli-plugin-babel": "5.0.8", "@vue/cli-plugin-babel": "5.0.8",
"@vue/cli-plugin-eslint": "5.0.8",
"@vue/cli-service": "5.0.8", "@vue/cli-service": "5.0.8",
"eslint": "8.35.0",
"eslint-plugin-vue": "9.9.0",
"sass": "1.58.3", "sass": "1.58.3",
"sass-loader": "10.1.1" "sass-loader": "10.1.1"
}, },
"eslintConfig": {
"root": true,
"env": {
"node": true
},
"globals": {
"APP_CONFIG": true
},
"extends": [
"plugin:vue/vue3-essential"
],
"parserOptions": {
"parser": "@babel/eslint-parser"
},
"rules": {
"indent": 0,
"no-tabs": 0,
"no-mixed-spaces-and-tabs": 0,
"vue/no-unused-components": 0,
"vue/multi-word-component-names": 0,
"no-debugger": "off",
"no-console": "off",
"no-trailing-spaces": "off"
}
},
"browserslist": [ "browserslist": [
"> 1%", "> 1%",
"last 2 versions", "last 2 versions",

View File

@ -0,0 +1,80 @@
<template>
<el-dropdown trigger="click" @command="handleExport">
<el-button type="success" icon="el-icon-download">导出</el-button>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item command="page">导出本页数据</el-dropdown-item>
<el-dropdown-item command="all">导出全部数据</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
</template>
<script>
import { dataToExcel } from "@/utils/exportExcel";
const ACT_STATE_MAP = { 0: "草稿中", 1: "进行中", 2: "被退回", 3: "被撤回", 4: "已完成", 5: "已关闭" };
export default {
name: "ScExportBtn",
props: {
getTableRef: { type: Function, required: true },
columns: { type: Array, required: true },
fileName: { type: String, default: "台账数据" },
},
methods: {
flattenData(list) {
if (!Array.isArray(list)) return [];
return list.map(row => {
const flat = { ...row };
const actState = row.ticket_?.act_state;
flat._act_state_text = ACT_STATE_MAP[actState] ?? "";
flat._state_name = row.ticket_?.state_?.name ?? "";
for (const key of Object.keys(flat)) {
if (Array.isArray(flat[key])) {
flat[key] = flat[key].join("、");
}
}
//
for (const key of Object.keys(flat)) {
if (typeof row[key] === "boolean") {
flat["_" + key + "_text"] = row[key] ? "是" : "否";
}
}
return flat;
});
},
getFlatColumns() {
return this.columns.map(col => {
if (col.key === "ticket_.act_state") return { ...col, key: "_act_state_text", type_dict: undefined };
// columns key _text
if (col.boolKey) return { ...col, key: "_" + col.boolKey + "_text", type_dict: undefined };
return col;
});
},
doExport(data) {
const flatData = this.flattenData(data);
const flatCols = this.getFlatColumns();
dataToExcel(flatCols, flatData, this.fileName);
},
handleExport(command) {
const table = this.getTableRef();
if (!table) return;
if (command === "page") {
this.doExport(table.tableData);
} else if (command === "all") {
const query = Object.assign({}, table.query, table.tableParams, { page: 0 });
const loading = this.$loading({ lock: true, text: "数据导出中...", background: "rgba(0,0,0,0.1)" });
table.apiObj.req(query).then((res) => {
loading.close();
this.doExport(res);
}).catch((err) => {
loading.close();
console.error("导出失败", err);
this.$message.error("导出失败");
});
}
},
},
};
</script>

View File

@ -3,6 +3,7 @@
<el-header> <el-header>
<div class="left-panel"> <div class="left-panel">
<el-button type="primary" @click="handleAdd('入库')" v-auth="'assetlog.create'">资产入库</el-button> <el-button type="primary" @click="handleAdd('入库')" v-auth="'assetlog.create'">资产入库</el-button>
<ExportBtn v-if="canExport" :getTableRef="() => $refs.table" :columns="exportCols" fileName="资产台账" />
</div> </div>
<div class="right-panel"> <div class="right-panel">
<el-input <el-input
@ -54,10 +55,20 @@
</el-drawer> </el-drawer>
</template> </template>
<script setup> <script setup>
import { ref } from 'vue' import { ref, computed } from 'vue'
import API from '@/api' import API from '@/api'
import TOOL from "@/utils/tool.js"
import { actStateEnum, interveneTypeEnum } from "@/utils/enum.js"; import { actStateEnum, interveneTypeEnum } from "@/utils/enum.js";
import assetlogin_form from './assetlogin_form.vue' import assetlogin_form from './assetlogin_form.vue'
import ExportBtn from '@/components/scExportBtn/index.vue'
const EXPORT_DEPTS = ['财务', '运营保障部', '综合管理部']
const userInfo = TOOL.data.get("USER_INFO")
const canExport = computed(() => {
const deptName = userInfo?.belong_dept_name || ''
return EXPORT_DEPTS.some(d => deptName.includes(d))
})
const query = ref({}); const query = ref({});
const drawerVisible = ref(false); const drawerVisible = ref(false);
const drawerTitle = ref('资产入库'); const drawerTitle = ref('资产入库');
@ -67,4 +78,12 @@ const handleAdd = () => {
mode.value = 'add'; mode.value = 'add';
drawerVisible.value = true; drawerVisible.value = true;
} }
const exportCols = [
{ header: "操作类型", key: "type", wch: 10 },
{ header: "审批状态", key: "_act_state_text", wch: 10 },
{ header: "启用日期", key: "start_date", wch: 16 },
{ header: "保管部门", key: "keep_dept_name", wch: 16 },
{ header: "保管人", key: "keeper_name", wch: 10 },
{ header: "创建时间", key: "create_time", wch: 18 },
]
</script> </script>

View File

@ -1,47 +1,58 @@
<template> <template>
<el-container> <el-container>
<el-header> <el-header>
<div class="left-panel"> <div class="left-panel">
<el-button type="primary" @click="handleAdd">新增</el-button> <el-button type="primary" @click="handleAdd">新增</el-button>
</div> <ExportBtn :getTableRef="() => $refs.table" :columns="exportCols" fileName="劳动合同台账" />
</el-header> </div>
<el-main class="nopadding"> </el-header>
<scTable <el-main class="nopadding">
ref="table" <scTable ref="table" :apiObj="API.hrm.empcontract.list" row-key="id" stripe
:apiObj="API.hrm.empcontract.list" @row-click="(row)=>{t_id=row.id;mode='show';drawerVisible=true;}">
row-key="id" <el-table-column label="部门" prop="dept_need_name" min-width="100" show-overflow-tooltip></el-table-column>
stripe <el-table-column label="员工姓名" prop="employee_name" min-width="80" show-overflow-tooltip></el-table-column>
:query="query" <el-table-column label="岗位" prop="post_name" min-width="80" show-overflow-tooltip></el-table-column>
@row-click="(row)=>{t_id=row.id;mode='show';drawerVisible=true;}" <el-table-column label="入职日期" prop="join_date" min-width="100" show-overflow-tooltip></el-table-column>
> <el-table-column label="合同结束日期" prop="end_contract" min-width="110" show-overflow-tooltip></el-table-column>
<el-table-column label="部门" prop="dept_need_name" width="80" show-overflow-tooltip></el-table-column> <el-table-column label="变更次数" prop="counts" min-width="80" show-overflow-tooltip></el-table-column>
<el-table-column label="审批状态" width="200" show-overflow-tooltip> <el-table-column label="应续签" prop="plan_renewal" min-width="100" show-overflow-tooltip></el-table-column>
<template #default="scope"> <el-table-column label="正常续签" prop="normal_renewal" min-width="100" show-overflow-tooltip></el-table-column>
<el-tag :type="actStateEnum[scope.row.ticket_?.act_state]?.type"> <el-table-column label="续签/变更(年)" prop="change_date" min-width="110" show-overflow-tooltip></el-table-column>
{{ actStateEnum[scope.row.ticket_?.act_state]?.text }} <el-table-column label="变更原因" prop="change_reason" min-width="150" show-overflow-tooltip></el-table-column>
</el-tag> <el-table-column label="审批状态" min-width="180">
<el-tag type="info" effect="plain">{{ scope.row.ticket_?.state_.name }}</el-tag> <template #default="scope">
<el-tag :type="actStateEnum[scope.row.ticket_?.act_state]?.type">{{ actStateEnum[scope.row.ticket_?.act_state]?.text }}</el-tag>
</template> <el-tag type="info" effect="plain">{{ scope.row.ticket_?.state_?.name }}</el-tag>
</el-table-column> </template>
</scTable> </el-table-column>
</el-main> </scTable>
</el-container> </el-main>
<el-drawer title="劳动合同变更" v-model="drawerVisible" :size="'80%'" destroy-on-close> </el-container>
<empcontract_form :mode="mode" :t_id="t_id"></empcontract_form> <el-drawer title="劳动合同变更" v-model="drawerVisible" :size="'80%'" destroy-on-close>
</el-drawer> <empcontract_form :mode="mode" :t_id="t_id"></empcontract_form>
</el-drawer>
</template> </template>
<script setup> <script setup>
import { ref } from 'vue' import { ref } from 'vue'
import API from '@/api' import API from '@/api'
import empcontract_form from './empcontract_form.vue' import empcontract_form from './empcontract_form.vue'
import { actStateEnum, interveneTypeEnum } from "@/utils/enum.js"; import ExportBtn from '@/components/scExportBtn/index.vue'
const query = ref({}); import { actStateEnum } from "@/utils/enum.js"
const drawerVisible = ref(false); const drawerVisible = ref(false)
const mode = ref('add'); const mode = ref('add')
const t_id = ref(null); const t_id = ref(null)
const handleAdd = () => { const handleAdd = () => { mode.value = 'add'; t_id.value = null; drawerVisible.value = true; }
mode.value = 'add'; const exportCols = [
drawerVisible.value = true; { header: "部门", key: "dept_need_name", wch: 15 },
} { header: "员工姓名", key: "employee_name", wch: 10 },
</script> { header: "岗位", key: "post_name", wch: 12 },
{ header: "入职日期", key: "join_date", wch: 12 },
{ header: "合同结束日期", key: "end_contract", wch: 14 },
{ header: "变更次数", key: "counts", wch: 8 },
{ header: "应续签", key: "plan_renewal", wch: 12 },
{ header: "正常续签", key: "normal_renewal", wch: 12 },
{ header: "续签/变更(年)", key: "change_date", wch: 12 },
{ header: "变更原因", key: "change_reason", wch: 25 },
{ header: "审批状态", key: "_act_state_text", wch: 10 },
]
</script>

View File

@ -1,48 +1,42 @@
<template> <template>
<el-container> <el-container>
<el-header> <el-header>
<div class="left-panel"> <div class="left-panel">
<el-button type="primary" @click="handleAdd">新增</el-button> <el-button type="primary" @click="handleAdd">新增</el-button>
</div> <ExportBtn :getTableRef="() => $refs.table" :columns="exportCols" fileName="人员交接台账" />
</el-header> </div>
<el-main class="nopadding"> </el-header>
<scTable <el-main class="nopadding">
ref="table" <scTable ref="table" :apiObj="API.hrm.empjoin.list" row-key="id" stripe
:apiObj="API.hrm.empjoin.list" @row-click="(row)=>{t_id=row.id;mode='show';drawerVisible=true;}">
row-key="id" <el-table-column label="部门" prop="dept_need_name" min-width="100" show-overflow-tooltip></el-table-column>
stripe <el-table-column label="入职日期" prop="join_date" min-width="100" show-overflow-tooltip></el-table-column>
:query="query" <el-table-column label="审批状态" min-width="180">
@row-click="(row)=>{t_id=row.id;mode='show';drawerVisible=true;}" <template #default="scope">
> <el-tag :type="actStateEnum[scope.row.ticket_?.act_state]?.type">{{ actStateEnum[scope.row.ticket_?.act_state]?.text }}</el-tag>
<el-table-column label="部门" prop="dept_need_name" width="80" show-overflow-tooltip></el-table-column> <el-tag type="info" effect="plain">{{ scope.row.ticket_?.state_?.name }}</el-tag>
<el-table-column label="入职日期" prop="join_date" width="80" show-overflow-tooltip></el-table-column> </template>
<el-table-column label="审批状态" width="200" show-overflow-tooltip> </el-table-column>
<template #default="scope"> </scTable>
<el-tag :type="actStateEnum[scope.row.ticket_?.act_state]?.type"> </el-main>
{{ actStateEnum[scope.row.ticket_?.act_state]?.text }} </el-container>
</el-tag> <el-drawer title="人员交接审核" v-model="drawerVisible" :size="'80%'" destroy-on-close>
<el-tag type="info" effect="plain">{{ scope.row.ticket_?.state_.name }}</el-tag> <empjoin_form :mode="mode" :t_id="t_id"></empjoin_form>
</el-drawer>
</template>
</el-table-column>
</scTable>
</el-main>
</el-container>
<el-drawer title="员工需求审核" v-model="drawerVisible" :size="'80%'" destroy-on-close>
<empjoin_form :mode="mode" :t_id="t_id"></empjoin_form>
</el-drawer>
</template> </template>
<script setup> <script setup>
import { ref } from 'vue' import { ref } from 'vue'
import API from '@/api' import API from '@/api'
import empjoin_form from './empjoin_form.vue' import empjoin_form from './empjoin_form.vue'
import { actStateEnum, interveneTypeEnum } from "@/utils/enum.js"; import ExportBtn from '@/components/scExportBtn/index.vue'
const query = ref({}); import { actStateEnum } from "@/utils/enum.js"
const drawerVisible = ref(false); const drawerVisible = ref(false)
const mode = ref('add'); const mode = ref('add')
const t_id = ref(null); const t_id = ref(null)
const handleAdd = () => { const handleAdd = () => { mode.value = 'add'; t_id.value = null; drawerVisible.value = true; }
mode.value = 'add'; const exportCols = [
drawerVisible.value = true; { header: "部门", key: "dept_need_name", wch: 15 },
} { header: "入职日期", key: "join_date", wch: 12 },
</script> { header: "审批状态", key: "_act_state_text", wch: 10 },
]
</script>

View File

@ -1,56 +1,58 @@
<template> <template>
<el-container> <el-container>
<el-header> <el-header>
<div class="left-panel"> <div class="left-panel">
<el-button type="primary" @click="handleAdd">新增</el-button> <el-button type="primary" @click="handleAdd">新增</el-button>
</div> <ExportBtn :getTableRef="() => $refs.table" :columns="exportCols" fileName="人员需求台账" />
</el-header> </div>
<el-main class="nopadding"> </el-header>
<scTable <el-main class="nopadding">
ref="table" <scTable ref="table" :apiObj="API.hrm.empneed.list" row-key="id" stripe
:apiObj="API.hrm.empneed.list" @row-click="(row)=>{t_id=row.id;mode='show';drawerVisible=true;}">
row-key="id" <el-table-column label="部门" prop="dept_need_name" min-width="100" show-overflow-tooltip></el-table-column>
stripe <el-table-column label="需求岗位" prop="post_need" min-width="100" show-overflow-tooltip></el-table-column>
:query="query" <el-table-column label="需求人数" prop="count_need" min-width="80" show-overflow-tooltip></el-table-column>
@row-click="(row)=>{t_id=row.id;mode='show';drawerVisible=true;}" <el-table-column label="工资报酬" prop="salary" min-width="80" show-overflow-tooltip></el-table-column>
> <el-table-column label="到岗日期" prop="arrival_date" min-width="100" show-overflow-tooltip></el-table-column>
<el-table-column label="部门" prop="dept_need_name" width="80" show-overflow-tooltip></el-table-column> <el-table-column label="岗位职责" prop="duty" min-width="150" show-overflow-tooltip></el-table-column>
<el-table-column label="审批状态" width="200" show-overflow-tooltip> <el-table-column label="性别要求" prop="gender" min-width="80" show-overflow-tooltip></el-table-column>
<template #default="scope"> <el-table-column label="学历要求" prop="education" min-width="80" show-overflow-tooltip></el-table-column>
<el-tag :type="actStateEnum[scope.row.ticket_?.act_state]?.type"> <el-table-column label="申请理由" prop="reason" min-width="150" show-overflow-tooltip></el-table-column>
{{ actStateEnum[scope.row.ticket_?.act_state]?.text }} <el-table-column label="专业及技能要求" prop="professional_requirement" min-width="180" show-overflow-tooltip></el-table-column>
</el-tag> <el-table-column label="审批状态" min-width="180">
<el-tag type="info" effect="plain">{{ scope.row.ticket_?.state_.name }}</el-tag> <template #default="scope">
<el-tag :type="actStateEnum[scope.row.ticket_?.act_state]?.type">{{ actStateEnum[scope.row.ticket_?.act_state]?.text }}</el-tag>
</template> <el-tag type="info" effect="plain">{{ scope.row.ticket_?.state_?.name }}</el-tag>
</el-table-column> </template>
<el-table-column label="需求岗位" prop="post_need" width="120" show-overflow-tooltip></el-table-column> </el-table-column>
<el-table-column label="需求人数" prop="count_need" width="80" show-overflow-tooltip></el-table-column> </scTable>
<el-table-column label="工资报酬" prop="salary" width="80" show-overflow-tooltip></el-table-column> </el-main>
<el-table-column label="到岗日期" prop="arrival_date" width="120" show-overflow-tooltip></el-table-column> </el-container>
<el-table-column label="岗位人员职责描述" prop="duty" width="130" show-overflow-tooltip></el-table-column> <el-drawer title="员工需求审核" v-model="drawerVisible" :size="'80%'" destroy-on-close>
<el-table-column label="性别要求" prop="gender" width="80" show-overflow-tooltip></el-table-column> <empneed_form :mode="mode" :t_id="t_id"></empneed_form>
<el-table-column label="学历要求" prop="education" width="80" show-overflow-tooltip></el-table-column> </el-drawer>
<el-table-column label="申请理由" prop="reason" width="150" show-overflow-tooltip></el-table-column>
<el-table-column label="相关专业及技能要求" prop="professional_requirement" width="200" show-overflow-tooltip></el-table-column>
</scTable>
</el-main>
</el-container>
<el-drawer title="员工需求审核" v-model="drawerVisible" :size="'80%'" destroy-on-close>
<empneed_form :mode="mode" :t_id="t_id"></empneed_form>
</el-drawer>
</template> </template>
<script setup> <script setup>
import { ref } from 'vue' import { ref } from 'vue'
import API from '@/api' import API from '@/api'
import empneed_form from './empneed_form.vue' import empneed_form from './empneed_form.vue'
import { actStateEnum, interveneTypeEnum } from "@/utils/enum.js"; import ExportBtn from '@/components/scExportBtn/index.vue'
const query = ref({}); import { actStateEnum } from "@/utils/enum.js"
const drawerVisible = ref(false); const drawerVisible = ref(false)
const mode = ref('add'); const mode = ref('add')
const t_id = ref(null); const t_id = ref(null)
const handleAdd = () => { const handleAdd = () => { mode.value = 'add'; t_id.value = null; drawerVisible.value = true; }
mode.value = 'add'; const exportCols = [
drawerVisible.value = true; { header: "部门", key: "dept_need_name", wch: 15 },
} { header: "需求岗位", key: "post_need", wch: 12 },
</script> { header: "需求人数", key: "count_need", wch: 10 },
{ header: "工资报酬", key: "salary", wch: 10 },
{ header: "到岗日期", key: "arrival_date", wch: 12 },
{ header: "岗位职责", key: "duty", wch: 20 },
{ header: "性别要求", key: "gender", wch: 8 },
{ header: "学历要求", key: "education", wch: 10 },
{ header: "申请理由", key: "reason", wch: 20 },
{ header: "专业及技能要求", key: "professional_requirement", wch: 25 },
{ header: "审批状态", key: "_act_state_text", wch: 10 },
]
</script>

View File

@ -1,134 +1,116 @@
<template> <template>
<el-container> <el-container>
<el-header> <el-header>
<div class="left-panel"> <div class="left-panel">
<el-button type="primary" @click="handleAdd">新增</el-button> <el-button type="primary" icon="el-icon-plus" @click="handleAdd">新增</el-button>
</div> <ExportBtn :getTableRef="() => $refs.table" :columns="exportCols" fileName="请假台账" />
<div class="right-panel"> </div>
<el-select <div class="right-panel">
v-model="query.leave_type" <el-input v-model="query.search" placeholder="姓名/工号" clearable @keyup.enter="handleQuery" style="width:140px" />
placeholder="请假类型" <el-select v-model="query.leave_type" placeholder="请假类型" @change="handleQuery" clearable style="width:120px">
@change="handleQuery" <el-option v-for="item in leaveOptions" :key="item.value" :label="item.label" :value="item.value" />
clearable </el-select>
style="margin-left: 2px; width: 120px" <el-cascader v-model="query.employee__belong_dept" :options="deptData" clearable placeholder="部门"
> @change="handleQuery" :show-all-levels="false" :props="{ emitPath: false, checkStrictly: true }"
<el-option style="width:150px" />
v-for="item in leaveOptions" <el-button type="primary" icon="el-icon-search" @click="handleQuery"></el-button>
:key="item.value" </div>
:label="item.label" </el-header>
:value="item.value" <el-main class="nopadding">
></el-option> <scTable ref="table" :apiObj="this.$API.hrm.leave.list" row-key="id" stripe
</el-select> @row-click="(row)=>{t_id=row.id;mode='show';drawerVisible=true;}">
<el-cascader <el-table-column label="姓名" prop="employee_name" min-width="80" show-overflow-tooltip />
v-model="query.employee__belong_dept" <el-table-column label="部门" prop="belong_dept_name" min-width="100" show-overflow-tooltip />
:options="deptData" <el-table-column label="岗位" prop="post_name" min-width="80" show-overflow-tooltip />
clearable <el-table-column label="请假类型" min-width="80">
placeholder="部门/单位" <template #default="scope">
@change="handleQuery" <el-tag
:show-all-levels="false" :type="leaveTagType[scope.row.leave_type] || 'info'"
:props="{ emitPath: false, checkStrictly: true }" effect="plain"
style="margin-left: 4px; width: 150px" size="small">
/> {{ leaveTypeMap[scope.row.leave_type] ?? scope.row.leave_type }}
<el-button </el-tag>
type="primary" </template>
icon="el-icon-search" </el-table-column>
@click="handleQuery" <el-table-column label="开始时间" prop="start_date" min-width="140" show-overflow-tooltip />
></el-button> <el-table-column label="结束时间" prop="end_date" min-width="140" show-overflow-tooltip />
</div> <el-table-column label="时长(h)" prop="hour" min-width="70" align="center" />
</el-header> <el-table-column label="请假事由" prop="reason" min-width="150" show-overflow-tooltip />
<el-main class="nopadding"> <el-table-column label="审批状态" min-width="180">
<scTable <template #default="scope">
ref="table" <el-tag :type="actStateEnum[scope.row.ticket_?.act_state]?.type" size="small">
:apiObj="this.$API.hrm.leave.list" {{ actStateEnum[scope.row.ticket_?.act_state]?.text }}
row-key="id" </el-tag>
stripe <el-tag type="info" effect="plain" size="small">{{ scope.row.ticket_?.state_?.name }}</el-tag>
:query="query" </template>
@row-click="(row)=>{t_id=row.id;mode='show';drawerVisible=true;}" </el-table-column>
> </scTable>
<el-table-column label="部门" prop="belong_dept_name" width="80" show-overflow-tooltip></el-table-column> </el-main>
<el-table-column label="姓名" prop="employee_name" width="80" show-overflow-tooltip></el-table-column> </el-container>
<el-table-column label="岗位" prop="post_name" width="80" show-overflow-tooltip></el-table-column> <el-drawer title="请假审批" v-model="drawerVisible" size="55%" destroy-on-close direction="rtl">
<el-table-column label="审批状态" width="200" show-overflow-tooltip> <div style="display: flex; height: calc(100% - 60px);">
<template #default="scope"> <div style="flex: 1; padding-right: 20px; overflow-y: auto;">
<el-tag :type="actStateEnum[scope.row.ticket_?.act_state]?.type"> <leave_form :mode="mode" :t_id="t_id"
{{ actStateEnum[scope.row.ticket_?.act_state]?.text }} @success="()=>{handleQuery(); drawerVisible = false}" />
</el-tag> </div>
<el-tag type="info" effect="plain">{{ scope.row.ticket_?.state_.name }}</el-tag>
</template>
</el-table-column>
<el-table-column label="请假类型" prop="leave_type" width="80" show-overflow-tooltip></el-table-column>
<el-table-column label="开始时间" prop="start_date" width="80" show-overflow-tooltip></el-table-column>
<el-table-column label="结束时间" prop="end_date" width="80" show-overflow-tooltip></el-table-column>
<el-table-column label="请假小时数" prop="hour" width="80" show-overflow-tooltip></el-table-column>
<el-table-column label="请假事由" prop="reason" width="150" show-overflow-tooltip></el-table-column>
</scTable>
</el-main>
</el-container>
<el-drawer title="请假审批" v-model="drawerVisible" :size="'50%'" destroy-on-close>
<div style="display: flex; height: calc(100% - 60px);">
<div style="flex: 1; padding-right: 20px; overflow-y: auto;">
<leave_form
:mode="mode"
:t_id="t_id"
@success="()=>{handleQuery(); drawerVisible = false}"
@closed="drawerVisible = false"
/>
</div> </div>
</div> </el-drawer>
</el-drawer>
</template> </template>
<script> <script>
import leave_form from './leave_form.vue' import leave_form from './leave_form.vue'
import { actStateEnum, interveneTypeEnum } from "@/utils/enum.js"; import ExportBtn from '@/components/scExportBtn/index.vue'
import { genTree } from "@/utils/verificate"; import { actStateEnum } from "@/utils/enum.js"
import { genTree } from "@/utils/verificate"
const LEAVE_OPTIONS = [
{ label: "事假", value: 10 },
{ label: "病假", value: 20 },
{ label: "婚假", value: 30 },
{ label: "丧假", value: 40 },
{ label: "公假", value: 50 },
{ label: "工伤", value: 60 },
{ label: "产假", value: 70 },
{ label: "护理假", value: 80 },
{ label: "其他", value: 90 },
];
const LEAVE_TYPE_MAP = { 10: "事假", 20: "病假", 30: "婚假", 40: "丧假", 50: "公假", 60: "工伤", 70: "产假", 80: "护理假", 90: "其他" };
const LEAVE_TAG_TYPE = { 10: "", 20: "danger", 30: "success", 40: "info", 50: "warning", 60: "danger", 70: "success", 80: "warning", 90: "info" };
export default { export default {
name: "hrm.leave", name: "hrm.leave",
components: { components: { leave_form, ExportBtn },
leave_form, data() {
}, return {
data() { actStateEnum,
return { drawerVisible: false,
actStateEnum, interveneTypeEnum, mode: 'show',
drawerVisible: false, t_id: null,
mode: 'show', deptData: [],
t_id: null, query: {},
deptData: [], leaveOptions: LEAVE_OPTIONS,
query: {}, leaveTypeMap: LEAVE_TYPE_MAP,
leaveOptions:[ leaveTagType: LEAVE_TAG_TYPE,
{ label: "事假", value: 10 }, exportCols: [
{ label: "病假", value: 20 }, { header: "姓名", key: "employee_name", wch: 10 },
{ label: "婚假", value: 30 }, { header: "部门", key: "belong_dept_name", wch: 15 },
{ label: "丧假", value: 40 }, { header: "岗位", key: "post_name", wch: 12 },
{ label: "公假", value: 50 }, { header: "请假类型", key: "leave_type", wch: 10, type_dict: LEAVE_TYPE_MAP },
{ label: "工伤", value: 60 }, { header: "开始时间", key: "start_date", wch: 18 },
{ label: "产假", value: 70 }, { header: "结束时间", key: "end_date", wch: 18 },
{ label: "护理假", value: 80 }, { header: "时长(h)", key: "hour", wch: 8 },
{ label: "其他", value: 90 } { header: "请假事由", key: "reason", wch: 25 },
], { header: "审批状态", key: "_act_state_text", wch: 10 },
}; ],
}, };
mounted() { },
this.getDept(); mounted() { this.getDept(); },
}, methods: {
methods: { handleAdd() { this.mode = 'add'; this.t_id = null; this.drawerVisible = true; },
handleAdd() { handleQuery() { this.$refs.table.queryData(this.query); },
this.mode = 'add'; async getDept() {
this.t_id = null; let res = await this.$API.system.dept.list.req({ page: 0, type__in: "dept,rparty" });
this.drawerVisible = true; this.deptData = genTree(res);
},
handleQuery() {
this.$refs.table.queryData(this.query);
},
async getDept() {
let res = await this.$API.system.dept.list.req({
page: 0,
type__in: "dept,rparty",
});
this.deptData = genTree(res);
},
}, },
},
}; };
</script>
</script>

View File

@ -1,218 +1,246 @@
<template> <template>
<el-container> <el-container>
<el-main class="nopadding"> <el-main class="nopadding">
<el-form label-width="80px" :rules="rules" :model="formData" style="padding: 20px;" :disabled="localMode === 'show'"> <el-form label-width="100px" :rules="rules" :model="formData" ref="formRef"
<el-form-item label="员工信息" required> style="padding: 20px;" :disabled="localMode === 'show'">
{{ formData.employee_name }}{{ formData.belong_dept_name }} - {{ formData.post_name }} <el-form-item label="员工信息" prop="employee" required>
</el-form-item> <template v-if="localMode === 'add'">
<el-form-item label="请假类型" required> <el-select
<el-select v-model="formData.employee"
v-model="formData.leave_type" filterable
placeholder="请选择请假类型" :filter-method="filterEmployee"
clearable placeholder="请输入姓名搜索"
style="width: 200px" :loading="empLoading"
@change="handleTypeChange" style="width: 100%"
> @change="handleEmpChange">
<el-option label="事假" :value="10" /> <el-option
<el-option label="病假" :value="20" /> v-for="item in filteredEmpOptions"
<el-option label="婚假" :value="30" /> :key="item.id"
<el-option label="丧假" :value="40" /> :label="`${item.name}${item.belong_dept_name || ''} - ${item.post_name || ''}`"
<el-option label="公假" :value="50" /> :value="item.id" />
<el-option label="工伤" :value="60" /> </el-select>
<el-option label="产假" :value="70" /> </template>
<el-option label="护理假" :value="80" /> <template v-else>
<el-option label="其他" :value="90" /> <span style="font-weight:500">{{ formData.employee_name }}</span>
</el-select> <span style="color:#909399;margin-left:8px">{{ formData.belong_dept_name }} / {{ formData.post_name }}</span>
</el-form-item> </template>
<el-form-item label="开始日期" required> </el-form-item>
<el-date-picker <el-row :gutter="16">
v-model="formData.start_date" <el-col :span="12">
type="datetime" <el-form-item label="请假类型" prop="leave_type" required>
placeholder="请假开始日期" <el-select v-model="formData.leave_type" placeholder="请选择" clearable
value-format="YYYY-MM-DD HH:mm:ss" style="width: 100%" @change="handleTypeChange">
:readonly="localMode === 'show'" <el-option v-for="item in leaveOptions" :key="item.value"
style="width: 200px" :label="item.label" :value="item.value" />
></el-date-picker> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="结束日期" required> </el-col>
<el-date-picker <el-col :span="12">
v-model="formData.end_date" <el-form-item label="请假时长" prop="hour" required>
type="datetime" <el-input v-model="formData.hour" type="number" :min="1" placeholder="小时数">
placeholder="请假结束日期" <template #append>小时</template>
value-format="YYYY-MM-DD HH:mm:ss" </el-input>
:readonly="localMode === 'show'" </el-form-item>
style="width: 200px" </el-col>
></el-date-picker> </el-row>
</el-form-item> <el-row :gutter="16">
<el-form-item label="请假时长一天8h计算" label-width="180px" required> <el-col :span="12">
<el-input v-model="formData.hour" type="number" min="1" style="width: 160px"> <el-form-item label="开始时间" prop="start_date" required>
<template #append>小时</template> <el-date-picker
</el-input> v-model="formData.start_date"
</el-form-item> type="datetime"
<el-form-item label="上传附件" placeholder="开始时间"
v-if = "showUpload" value-format="YYYY-MM-DD HH:mm:ss"
prop="file"> style="width: 100%" />
<sc-upload-file </el-form-item>
v-model="formData.file" </el-col>
:multiple="false" <el-col :span="12">
:limit="1" <el-form-item label="结束时间" prop="end_date" required>
:accept="['.xlsx', '.xls','.pdf','.docx', '.doc', '.jpg', '.png', '.jpeg']" <el-date-picker
@success = "fileUPSuccess" v-model="formData.end_date"
:disabled="localMode ==='show'" type="datetime"
> placeholder="结束时间"
<el-button type="primary" icon="el-icon-upload"> </el-button> value-format="YYYY-MM-DD HH:mm:ss"
style="width: 100%" />
</el-form-item>
</el-col>
</el-row>
<el-form-item label="上传附件" v-if="showUpload" prop="file">
<sc-upload-file
v-model="formData.file"
:multiple="false"
:limit="1"
:accept="['.xlsx','.xls','.pdf','.docx','.doc','.jpg','.png','.jpeg']"
@success="fileUPSuccess"
:disabled="localMode === 'show'">
<el-button type="primary" icon="el-icon-upload">选择文件</el-button>
</sc-upload-file> </sc-upload-file>
</el-form-item> </el-form-item>
<el-form-item label="申请理由" required> <el-form-item label="请假事由" prop="reason" required>
<el-input v-model="formData.reason" type="textarea" rows="3" style="width: 400px" placeholder="请输入请假理由"></el-input> <el-input v-model="formData.reason" type="textarea" :rows="3" placeholder="请输入请假理由" />
</el-form-item> </el-form-item>
</el-form> </el-form>
<el-footer> <el-footer>
<el-button type="danger" <el-button type="danger" v-if="localMode === 'edit'" @click="handleDel" :loading="saveLoading">删除</el-button>
v-if="localMode=='edit'" <ticketd_b
style="margin-right: 4px;" v-if="formData.ticket_ && localMode === 'show'"
@click="handleDel" :t_id="formData.id"
:loading="saveLoading" :ticket_="formData.ticket_"
>删除</el-button> :ticket_data="ticket_data"
<ticketd_b @success="$emit('success', localMode)"
v-if = "formData.ticket_ && localMode=='show'" ref="ticketd_b" />
:t_id="formData.id" <el-button v-if="localMode !== 'show'" type="primary" @click="handleSave" :loading="saveLoading">提交审批</el-button>
:ticket_="formData.ticket_" </el-footer>
:ticket_data="ticket_data" </el-main>
@success="$emit('success', localMode)" <el-aside width="20%" v-if="formData.ticket_">
ref="ticketd_b" <ticketd :ticket_="formData.ticket_" @success="$emit('success')" style="margin-top: 20px;" />
></ticketd_b> </el-aside>
<el-button </el-container>
v-if="localMode!='show'"
type="primary"
style="margin-right: 4px;"
@click="handleSave"
:loading="saveLoading"
>提交审批</el-button>
</el-footer>
</el-main>
<el-aside width="20%" v-if="formData.ticket_">
<ticketd :ticket_="formData.ticket_" @success="$emit('success')"></ticketd>
</el-aside>
</el-container>
</template> </template>
<script> <script>
import ticketd_b from "@/views/wf/ticketd_b.vue"; import ticketd_b from "@/views/wf/ticketd_b.vue";
import ticketd from '@/views/wf/ticketd.vue' import ticketd from '@/views/wf/ticketd.vue'
export default { const LEAVE_OPTIONS = [
components: { { label: "事假", value: 10 },
ticketd_b, { label: "病假", value: 20 },
ticketd { label: "婚假", value: 30 },
}, { label: "丧假", value: 40 },
props: { { label: "公假", value: 50 },
mode: { { label: "工伤", value: 60 },
type: String, { label: "产假", value: 70 },
default: 'show' { label: "护理假", value: 80 },
}, { label: "其他", value: 90 },
t_id: { ];
type: String, const LEAVE_TYPE_NAME = Object.fromEntries(LEAVE_OPTIONS.map(i => [i.value, i.label]));
default: ""
}
},
computed: {
showUpload() {
return [20, 30, 40, 70].includes(this.formData.leave_type)
},
},
data() {
return {
formData: {},
ticket_data: {},
localMode: this.mode,
saveLoading: false,
rules: {
leave_type: [{ required: true, message: "请输入请假类型", trigger: "blur" }],
start_date: [{ required: true, message: "请选择开始时间", trigger: "blur" }],
end_date: [{ required: true, message: "请选择结束时间", trigger: "blur" }],
hour: [{ required: true, message: "请输入请假时长", trigger: "blur" }],
file: [{ required: true, message: "请上传附件", trigger: "blur" }],
reason: [{ required: true, message: "请输入请假理由", trigger: "blur" }],
},
}
},
watch: {
mode(val) {
this.localMode = val;
}, export default {
}, components: { ticketd_b, ticketd },
mounted() { props: {
if (this.t_id) { mode: { type: String, default: 'show' },
this.getTid(); t_id: { type: String, default: "" },
}else { },
this.initFormData(); data() {
} return {
formData: {},
ticket_data: {},
localMode: this.mode,
saveLoading: false,
empLoading: false,
empOptions: [],
filterKeyword: '',
currentDeptId: null,
leaveOptions: LEAVE_OPTIONS,
rules: {
employee: [{ required: true, message: "请选择员工", trigger: "change" }],
leave_type: [{ required: true, message: "请选择请假类型", trigger: "change" }],
start_date: [{ required: true, message: "请选择开始时间", trigger: "change" }],
end_date: [{ required: true, message: "请选择结束时间", trigger: "change" }],
hour: [{ required: true, message: "请输入请假时长", trigger: "blur" }],
reason: [{ required: true, message: "请输入请假理由", trigger: "blur" }],
},
}
},
computed: {
showUpload() {
return [20, 30, 40, 70].includes(this.formData.leave_type)
}, },
methods: { filteredEmpOptions() {
async getTid() { if (!this.filterKeyword) return this.empOptions;
try { const kw = this.filterKeyword.toLowerCase();
let res = await this.$API.hrm.leave.item.req(this.t_id); return this.empOptions.filter(e =>
this.formData = res; (e.name || '').toLowerCase().includes(kw) ||
if (res.ticket_ && res.ticket_.state_.type == 1 && res.create_by == this.$TOOL.data.get("USER_INFO").id) { (e.belong_dept_name || '').toLowerCase().includes(kw) ||
this.localMode = "edit"; (e.post_name || '').toLowerCase().includes(kw)
} );
} catch (error) { },
console.error('获取请假数据失败:', error); },
} watch: {
}, mode(val) { this.localMode = val; },
async initFormData() { },
try { mounted() {
let res = await this.$API.hrm.employee.read.req(); if (this.t_id) {
this.formData.employee_name = res.name; this.getTid();
this.formData.belong_dept_name = res.belong_dept_name; } else {
this.formData.post_name = res.post_name; this.initFormData();
this.formData.employee = res.id; }
this.localMode = "add"; },
} catch (error) { methods: {
console.error('初始化表单数据失败:', error); async getTid() {
} try {
}, let res = await this.$API.hrm.leave.item.req(this.t_id);
handleTypeChange(val) { this.formData = res;
const map = { if (res.ticket_ && res.ticket_.state_.type == 1 && res.create_by == this.$TOOL.data.get("USER_INFO").id) {
10: '事假', this.localMode = "edit";
20: '病假', }
30: '婚假', } catch (e) {
40: '丧假', console.error('获取请假数据失败:', e);
50: '公假', }
60: '工伤', },
70: '产假', async initFormData() {
80: '护理假', try {
90: '其他', let userInfo = this.$TOOL.data.get("USER_INFO");
} this.currentDeptId = userInfo.belong_dept;
this.formData.leave_type_name = map[val] || '' //
}, let res = await this.$API.hrm.employee.read.req();
handleDel() { this.formData.employee_name = res.name;
this.$confirm(`确定删除吗?`, "提示", { this.formData.belong_dept_name = res.belong_dept_name;
type: "warning", this.formData.post_name = res.post_name;
}) //
.then(()=>{ await this.loadDeptEmployees();
this.$API.hrm.leave.delete.req(this.formData.id).then(res=>{ // add
this.$message.success("删除成功"); this.localMode = "add";
this.$emit('success'); } catch (e) {
}) console.error('初始化表单数据失败:', e);
}) }
}, },
async handleSave() { async loadDeptEmployees() {
if (this.localMode == "add") { if (!this.currentDeptId) return;
try { try {
let res = await this.$API.hrm.leave.create.req(this.formData); let res = await this.$API.hrm.employee.list.req({ page: 0, belong_dept: this.currentDeptId });
this.$message.success("提交成功"); this.empOptions = Array.isArray(res) ? res : (res.results || []);
this.$emit('success', this.localMode); } catch (e) {
} catch (error) { console.error(e);
console.error('请假需求申请失败:', error); }
throw error; },
} filterEmployee(keyword) {
} else if (this.localMode == "edit") { this.filterKeyword = keyword;
this.$message.error("不支持编辑"); },
} handleEmpChange(id) {
}, const emp = this.empOptions.find(e => e.id === id);
}, if (emp) {
}; this.formData.employee_name = emp.name;
</script> this.formData.belong_dept_name = emp.belong_dept_name || '';
this.formData.post_name = emp.post_name || '';
}
},
handleTypeChange(val) {
this.formData.leave_type_name = LEAVE_TYPE_NAME[val] || ''
},
handleDel() {
this.$confirm('确定删除吗?', "提示", { type: "warning" }).then(() => {
this.$API.hrm.leave.delete.req(this.formData.id).then(() => {
this.$message.success("删除成功");
this.$emit('success');
})
})
},
async handleSave() {
if (this.localMode == "add") {
try {
await this.$API.hrm.leave.create.req(this.formData);
this.$message.success("提交成功");
this.$emit('success', this.localMode);
} catch (e) {
console.error('请假申请失败:', e);
throw e;
}
}
},
fileUPSuccess(res) {
this.formData.file = res?.path || ''
},
},
};
</script>

View File

@ -1,119 +1,83 @@
<template> <template>
<el-container> <el-container>
<el-header> <el-header>
<div class="left-panel"> <div class="left-panel">
<el-button type="primary" @click="handleAdd">新增</el-button> <el-button type="primary" @click="handleAdd">新增</el-button>
</div> <ExportBtn :getTableRef="() => $refs.table" :columns="exportCols" fileName="人员转正台账" />
<div class="right-panel"> </div>
<el-input <div class="right-panel">
v-model="query.search" <el-input v-model="query.search" placeholder="姓名/手机号" clearable @keyup.enter="handleQuery" style="width:150px"></el-input>
placeholder="姓名/手机号" <el-cascader v-model="query.reg_dept" :options="deptData" clearable placeholder="部门/单位"
clearable @change="handleQuery" :show-all-levels="false" :props="{ emitPath: false, checkStrictly: true }"
@keyup.enter="handleQuery" style="width:150px" />
style="margin-left: 4px; width: 150px" <el-button type="primary" icon="el-icon-search" @click="handleQuery"></el-button>
></el-input> </div>
<el-cascader </el-header>
v-model="query.reg_dept" <el-main class="nopadding">
:options="deptData" <scTable ref="table" :apiObj="this.$API.hrm.probation.list" row-key="id" stripe
clearable @row-click="(row)=>{t_id=row.id;mode='show';drawerVisible=true;}">
placeholder="部门/单位" <el-table-column label="部门" prop="reg_dept_name" min-width="100" show-overflow-tooltip></el-table-column>
@change="handleQuery" <el-table-column label="姓名" prop="employee_name" min-width="80" show-overflow-tooltip></el-table-column>
:show-all-levels="false" <el-table-column label="岗位" prop="post_name" min-width="80" show-overflow-tooltip></el-table-column>
:props="{ emitPath: false, checkStrictly: true }" <el-table-column label="身份证号" prop="IDcard" min-width="170" show-overflow-tooltip></el-table-column>
style="margin-left: 4px; width: 150px" <el-table-column label="试用日期" prop="trial_date" min-width="100" show-overflow-tooltip></el-table-column>
/> <el-table-column label="转正日期" prop="regular_date" min-width="100" show-overflow-tooltip></el-table-column>
<el-button <el-table-column label="转正申请" prop="content" min-width="150" show-overflow-tooltip></el-table-column>
type="primary" <el-table-column label="审批状态" min-width="180">
icon="el-icon-search" <template #default="scope">
@click="handleQuery" <el-tag :type="actStateEnum[scope.row.ticket_?.act_state]?.type">{{ actStateEnum[scope.row.ticket_?.act_state]?.text }}</el-tag>
></el-button> <el-tag type="info" effect="plain">{{ scope.row.ticket_?.state_?.name }}</el-tag>
</div> </template>
</el-header> </el-table-column>
<el-main class="nopadding"> </scTable>
<scTable </el-main>
ref="table" </el-container>
:apiObj="this.$API.hrm.probation.list" <el-drawer title="转正审批" v-model="drawerVisible" :size="'50%'" destroy-on-close>
row-key="id" <div style="display: flex; height: calc(100% - 60px);">
stripe <div style="flex: 1; padding-right: 20px; overflow-y: auto;">
:query="query" <probation_form :mode="mode" :t_id="t_id"
@row-click="(row)=>{t_id=row.id;mode='show';drawerVisible=true;}" @success="()=>{handleQuery(); drawerVisible = false}" @closed="drawerVisible = false" />
> </div>
<el-table-column label="部门" prop="reg_dept_name" width="80" show-overflow-tooltip></el-table-column>
<el-table-column label="姓名" prop="employee_name" width="80" show-overflow-tooltip></el-table-column>
<el-table-column label="岗位" prop="post_name" width="80" show-overflow-tooltip></el-table-column>
<el-table-column label="审批状态" width="200" show-overflow-tooltip>
<template #default="scope">
<el-tag :type="actStateEnum[scope.row.ticket_?.act_state]?.type">
{{ actStateEnum[scope.row.ticket_?.act_state]?.text }}
</el-tag>
<el-tag type="info" effect="plain">{{ scope.row.ticket_?.state_.name }}</el-tag>
</template>
</el-table-column>
<el-table-column label="身份证号" prop="IDcard" width="80" show-overflow-tooltip></el-table-column>
<el-table-column label="试用日期" prop="trial_date" width="80" show-overflow-tooltip></el-table-column>
<el-table-column label="转正日期" prop="regular_date" width="80" show-overflow-tooltip></el-table-column>
<el-table-column label="转正申请" prop="content" width="80" show-overflow-tooltip></el-table-column>
<el-table-column label="应聘人员登记表" prop="record_file" width="150" show-overflow-tooltip></el-table-column>
<el-table-column label="员工转正申请表" prop="apply_file" width="150" show-overflow-tooltip></el-table-column>
<el-table-column label="PPT 汇报考核" prop="ppt_file" width="150" show-overflow-tooltip></el-table-column>
</scTable>
</el-main>
</el-container>
<el-drawer title="转正审批" v-model="drawerVisible" :size="'50%'" destroy-on-close>
<div style="display: flex; height: calc(100% - 60px);">
<div style="flex: 1; padding-right: 20px; overflow-y: auto;">
<probation_form
:mode="mode"
:t_id="t_id"
@success="()=>{handleQuery(); drawerVisible = false}"
@closed="drawerVisible = false"
/>
</div> </div>
</div> </el-drawer>
</el-drawer>
</template> </template>
<script> <script>
import probation_form from './probation_form.vue' import probation_form from './probation_form.vue'
import { actStateEnum, interveneTypeEnum } from "@/utils/enum.js"; import ExportBtn from '@/components/scExportBtn/index.vue'
import { genTree } from "@/utils/verificate"; import { actStateEnum, interveneTypeEnum } from "@/utils/enum.js"
import { genTree } from "@/utils/verificate"
export default { export default {
name: "hrm.probation", name: "hrm.probation",
components: { components: { probation_form, ExportBtn },
probation_form, data() {
}, return {
data() { actStateEnum, interveneTypeEnum,
return { drawerVisible: false,
actStateEnum, interveneTypeEnum, mode: 'show',
drawerVisible: false, t_id: null,
mode: 'show', deptData: [],
t_id: null, query: {},
deptData: [], exportCols: [
query: {}, { header: "部门", key: "reg_dept_name", wch: 15 },
nameList:[], { header: "姓名", key: "employee_name", wch: 10 },
}; { header: "岗位", key: "post_name", wch: 12 },
}, { header: "身份证号", key: "IDcard", wch: 20 },
mounted() { { header: "试用日期", key: "trial_date", wch: 12 },
this.getDept(); { header: "转正日期", key: "regular_date", wch: 12 },
}, { header: "转正申请", key: "content", wch: 25 },
methods: { { header: "审批状态", key: "_act_state_text", wch: 10 },
handleAdd() { ],
this.mode = 'add'; };
this.t_id = null; },
this.drawerVisible = true; mounted() { this.getDept(); },
}, methods: {
handleQuery() { handleAdd() { this.mode = 'add'; this.t_id = null; this.drawerVisible = true; },
this.$refs.table.queryData(this.query); handleQuery() { this.$refs.table.queryData(this.query); },
}, async getDept() {
async getDept() { let res = await this.$API.system.dept.list.req({ page: 0, type__in: "dept,rparty" });
let res = await this.$API.system.dept.list.req({ this.deptData = genTree(res);
page: 0,
type__in: "dept,rparty",
});
this.deptData = genTree(res);
},
}, },
},
}; };
</script>
</script>

View File

@ -1,65 +1,55 @@
<template> <template>
<el-container> <el-container>
<el-header> <el-header>
<div class="left-panel"></div> <div class="left-panel">
<div class="right-panel"> <ExportBtn :getTableRef="() => $refs.table" :columns="exportCols" fileName="离职申请台账" />
<!-- <el-button type="primary" @click="handleAdd">新增</el-button> --> </div>
<el-input <div class="right-panel">
v-model="query.search" <el-input v-model="query.search" placeholder="姓名" clearable @keyup.enter="handleQuery" style="width:150px"></el-input>
placeholder="姓名" <el-button type="primary" icon="el-icon-search" @click="handleQuery"></el-button>
clearable </div>
@keyup.enter="$refs.table.refresh()" </el-header>
></el-input> <el-main class="nopadding">
<el-button <scTable ref="table" :apiObj="API.hrm.resignation.list" row-key="id" stripe
type="primary" @row-click="(row)=>{t_id=row.id;mode='show';drawerVisible=true;}">
icon="el-icon-search" <el-table-column label="姓名" prop="employee_name" min-width="80" show-overflow-tooltip></el-table-column>
@click="handleQuery" <el-table-column label="部门" prop="belong_dept_name" min-width="100" show-overflow-tooltip></el-table-column>
></el-button> <el-table-column label="岗位" prop="post_name" min-width="100" show-overflow-tooltip></el-table-column>
</div> <el-table-column label="身份证号" prop="employee_id_number" min-width="170" show-overflow-tooltip></el-table-column>
<el-table-column label="离职日期" prop="end_date" min-width="100" show-overflow-tooltip></el-table-column>
</el-header> <el-table-column label="原因" prop="reason" min-width="150" show-overflow-tooltip></el-table-column>
<el-main class="nopadding"> <el-table-column label="审批状态" min-width="180">
<scTable <template #default="scope">
ref="table" <el-tag :type="actStateEnum[scope.row.ticket_?.act_state]?.type">{{ actStateEnum[scope.row.ticket_?.act_state]?.text }}</el-tag>
:apiObj="API.hrm.resignation.list" <el-tag type="info" effect="plain">{{ scope.row.ticket_?.state_?.name }}</el-tag>
row-key="id"
stripe
:query="query"
@row-click="(row)=>{t_id=row.id;mode='show';drawerVisible=true;}"
>
<el-table-column label="姓名" prop="employee_name" width="100" show-overflow-tooltip></el-table-column>
<el-table-column label="审批状态" width="200" show-overflow-tooltip>
<template #default="scope">
<el-tag :type="actStateEnum[scope.row.ticket_?.act_state]?.type">
{{ actStateEnum[scope.row.ticket_?.act_state]?.text }}
</el-tag>
<el-tag type="info" effect="plain">{{ scope.row.ticket_?.state_.name }}</el-tag>
</template> </template>
</el-table-column>` </el-table-column>
<el-table-column label="部门" prop="belong_dept_name" width="120" show-overflow-tooltip></el-table-column>` </scTable>
<el-table-column label="岗位" prop="post_name" width="120" show-overflow-tooltip></el-table-column> </el-main>
<el-table-column label="身份证号" prop="employee_id_number" width="200" show-overflow-tooltip></el-table-column> </el-container>
<el-table-column label="离职日期" prop="end_date" width="100" show-overflow-tooltip></el-table-column> <el-drawer title="离职申请" v-model="drawerVisible" :size="'80%'" destroy-on-close>
<el-table-column label="原因" prop="reason" show-overflow-tooltip></el-table-column> <resignation-form :mode="mode" :t_id="t_id"></resignation-form>
</scTable> </el-drawer>
</el-main>
</el-container>
<el-drawer title="离职申请" v-model="drawerVisible" :size="'80%'" destroy-on-close>
<resignation-form :mode="mode" :t_id="t_id"></resignation-form>
</el-drawer>
</template> </template>
<script setup> <script setup>
import { ref } from 'vue' import { ref } from 'vue'
import API from '@/api' import API from '@/api'
import resignationForm from './resignation_form.vue' import resignationForm from './resignation_form.vue'
import { actStateEnum, interveneTypeEnum } from "@/utils/enum.js"; import ExportBtn from '@/components/scExportBtn/index.vue'
const query = ref({}); import { actStateEnum } from "@/utils/enum.js"
const drawerVisible = ref(false); const query = ref({})
const mode = ref('add'); const drawerVisible = ref(false)
const t_id = ref(null); const mode = ref('add')
const handleAdd = () => { const t_id = ref(null)
mode.value = 'add'; const table = ref(null)
drawerVisible.value = true; const handleQuery = () => { table.value?.queryData(query.value) }
} const exportCols = [
</script> { header: "姓名", key: "employee_name", wch: 10 },
{ header: "部门", key: "belong_dept_name", wch: 15 },
{ header: "岗位", key: "post_name", wch: 12 },
{ header: "身份证号", key: "employee_id_number", wch: 20 },
{ header: "离职日期", key: "end_date", wch: 12 },
{ header: "原因", key: "reason", wch: 25 },
{ header: "审批状态", key: "_act_state_text", wch: 10 },
]
</script>

View File

@ -1,66 +1,68 @@
<template> <template>
<el-container> <el-container>
<el-header> <el-header>
<div class="left-panel"> <div class="left-panel">
<el-button type="primary" @click="handleAdd">新增</el-button> <el-button type="primary" @click="handleAdd">新增</el-button>
</div> <ExportBtn :getTableRef="() => $refs.table" :columns="exportCols" fileName="人员调岗台账" />
</el-header> </div>
<el-main class="nopadding"> </el-header>
<scTable <el-main class="nopadding">
ref="table" <scTable ref="table" :apiObj="API.hrm.transfer.list" row-key="id" stripe
:apiObj="API.hrm.transfer.list" @row-click="(row)=>{t_id=row.id;mode='show';drawerVisible=true;}">
row-key="id" <el-table-column label="员工" prop="employee_name" min-width="80" show-overflow-tooltip></el-table-column>
stripe <el-table-column label="岗位" prop="post_name" min-width="80" show-overflow-tooltip></el-table-column>
:query="query" <el-table-column label="原部门" prop="original_dept_name" min-width="100" show-overflow-tooltip></el-table-column>
@row-click="(row)=>{t_id=row.id;mode='show';drawerVisible=true;}" <el-table-column label="调入部门" prop="new_dept_name" min-width="100" show-overflow-tooltip></el-table-column>
> <el-table-column label="原岗位" prop="original_post_name" min-width="100" show-overflow-tooltip></el-table-column>
<el-table-column label="员工" prop="employee_name" width="80" show-overflow-tooltip></el-table-column> <el-table-column label="调入岗位" prop="new_post_name" min-width="100" show-overflow-tooltip></el-table-column>
<el-table-column label="岗位" prop="post_name" width="80" show-overflow-tooltip></el-table-column> <el-table-column label="跨部门调动" min-width="90" show-overflow-tooltip>
<el-table-column label="原部门" prop="original_dept" width="80" show-overflow-tooltip></el-table-column> <template #default="scope">
<el-table-column label="入职部门" prop="new_dept" width="80" show-overflow-tooltip></el-table-column> <el-tag :type="scope.row.is_change ? 'danger' : 'info'" size="small">{{ scope.row.is_change ? '是' : '否' }}</el-tag>
<el-table-column label="跨部门调动" prop="is_change" width="80" show-overflow-tooltip> </template>
<template #default="scope"> </el-table-column>
{{scope.row.is_change?'是':'否'}} <el-table-column label="晋升" min-width="70" show-overflow-tooltip>
</template> <template #default="scope">
</el-table-column> <el-tag :type="scope.row.is_promotion ? 'success' : 'info'" size="small">{{ scope.row.is_promotion ? '是' : '否' }}</el-tag>
<el-table-column label="跨部门调动" prop="is_change" width="80" show-overflow-tooltip> </template>
<template #default="scope"> </el-table-column>
{{scope.row.is_promotion?'是':'否'}} <el-table-column label="调岗日期" prop="transfer_date" min-width="100" show-overflow-tooltip></el-table-column>
</template> <el-table-column label="个人工作内容" prop="content" min-width="150" show-overflow-tooltip></el-table-column>
</el-table-column> <el-table-column label="调岗原因" prop="transfer_reason" min-width="150" show-overflow-tooltip></el-table-column>
<el-table-column label="原岗位" prop="original_post" width="80" show-overflow-tooltip></el-table-column> <el-table-column label="审批状态" min-width="180">
<el-table-column label="入职岗位" prop="new_post" width="80" show-overflow-tooltip></el-table-column> <template #default="scope">
<el-table-column label="调岗日期" prop="transfer_date" width="80" show-overflow-tooltip></el-table-column> <el-tag :type="actStateEnum[scope.row.ticket_?.act_state]?.type">{{ actStateEnum[scope.row.ticket_?.act_state]?.text }}</el-tag>
<el-table-column label="个人工作内容" prop="content" width="80" show-overflow-tooltip></el-table-column> <el-tag type="info" effect="plain">{{ scope.row.ticket_?.state_?.name }}</el-tag>
<el-table-column label="调岗原因" prop="transfer_reason" width="80" show-overflow-tooltip></el-table-column> </template>
<el-table-column label="调岗日期" prop="transfer_date" width="80" show-overflow-tooltip></el-table-column> </el-table-column>
<el-table-column label="审批状态" width="200" show-overflow-tooltip> </scTable>
<template #default="scope"> </el-main>
<el-tag :type="actStateEnum[scope.row.ticket_?.act_state]?.type"> </el-container>
{{ actStateEnum[scope.row.ticket_?.act_state]?.text }} <el-drawer title="人员调岗审核" v-model="drawerVisible" :size="'80%'" destroy-on-close>
</el-tag> <transfer_form :mode="mode" :t_id="t_id"></transfer_form>
<el-tag type="info" effect="plain">{{ scope.row.ticket_?.state_.name }}</el-tag> </el-drawer>
</template>
</el-table-column>
</scTable>
</el-main>
</el-container>
<el-drawer title="人员调岗审核" v-model="drawerVisible" :size="'80%'" destroy-on-close>
<transfer_form :mode="mode" :t_id="t_id"></transfer_form>
</el-drawer>
</template> </template>
<script setup> <script setup>
import { ref } from 'vue' import { ref } from 'vue'
import API from '@/api' import API from '@/api'
import transfer_form from './transfer_form.vue' import transfer_form from './transfer_form.vue'
import { actStateEnum } from "@/utils/enum.js"; import ExportBtn from '@/components/scExportBtn/index.vue'
const query = ref({}); import { actStateEnum } from "@/utils/enum.js"
const drawerVisible = ref(false); const drawerVisible = ref(false)
const mode = ref('add'); const mode = ref('add')
const t_id = ref(null); const t_id = ref(null)
const handleAdd = () => { const handleAdd = () => { mode.value = 'add'; t_id.value = null; drawerVisible.value = true; }
mode.value = 'add'; const exportCols = [
drawerVisible.value = true; { header: "员工", key: "employee_name", wch: 10 },
} { header: "岗位", key: "post_name", wch: 12 },
</script> { header: "原部门", key: "original_dept_name", wch: 12 },
{ header: "调入部门", key: "new_dept_name", wch: 12 },
{ header: "原岗位", key: "original_post_name", wch: 12 },
{ header: "调入岗位", key: "new_post_name", wch: 12 },
{ header: "跨部门调动", key: "_is_change_text", wch: 10 },
{ header: "晋升", key: "_is_promotion_text", wch: 8 },
{ header: "调岗日期", key: "transfer_date", wch: 12 },
{ header: "个人工作内容", key: "content", wch: 20 },
{ header: "调岗原因", key: "transfer_reason", wch: 20 },
{ header: "审批状态", key: "_act_state_text", wch: 10 },
]
</script>

View File

@ -7,6 +7,7 @@
icon="el-icon-plus" icon="el-icon-plus"
@click="handleAdd" @click="handleAdd"
></el-button> ></el-button>
<ExportBtn :getTableRef="() => $refs.table" :columns="exportCols" fileName="借阅台账" />
</div> </div>
<div class="right-panel"> <div class="right-panel">
<el-input <el-input
@ -125,9 +126,10 @@
<script> <script>
import borrowlForm from "./borrowfile_form.vue"; import borrowlForm from "./borrowfile_form.vue";
import ExportBtn from "./exportBtn.vue";
import { actStateEnum, interveneTypeEnum } from "@/utils/enum.js"; import { actStateEnum, interveneTypeEnum } from "@/utils/enum.js";
export default { export default {
components: { borrowlForm }, components: { borrowlForm, ExportBtn },
name: "index", name: "index",
data() { data() {
return { return {
@ -137,6 +139,17 @@ export default {
limitedVisible: false, limitedVisible: false,
mode: "show", mode: "show",
t_id: null, t_id: null,
exportCols: [
{ header: "档案名称", key: "file_name", wch: 20 },
{ header: "申请部门", key: "belong_dept_name", wch: 15 },
{ header: "申请人", key: "create_by_name", wch: 12 },
{ header: "申请人电话", key: "contacts", wch: 15 },
{ header: "借阅时间", key: "borrow_date", wch: 15 },
{ header: "借阅数量", key: "count", wch: 10 },
{ header: "用途", key: "remark", wch: 20 },
{ header: "归还时间", key: "return_date", wch: 15 },
{ header: "审批状态", key: "_act_state_text", wch: 12 },
],
}; };
}, },
methods: { methods: {

View File

@ -0,0 +1,83 @@
<template>
<el-dropdown trigger="click" @command="handleExport">
<el-button type="success" icon="el-icon-download">导出</el-button>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item command="page">导出本页数据</el-dropdown-item>
<el-dropdown-item command="all">导出全部数据</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
</template>
<script>
import { dataToExcel } from "@/utils/exportExcel";
const ACT_STATE_MAP = { 0: "草稿中", 1: "进行中", 2: "被退回", 3: "被撤回", 4: "已完成", 5: "已关闭" };
export default {
name: "OfmExportBtn",
props: {
getTableRef: { type: Function, required: true },
columns: { type: Array, required: true },
fileName: { type: String, default: "台账数据" },
},
methods: {
// getNestedValue null
flattenData(list) {
if (!Array.isArray(list)) return [];
return list.map(row => {
const flat = { ...row };
//
const actState = row.ticket_?.act_state;
flat._act_state_text = ACT_STATE_MAP[actState] ?? "";
flat._state_name = row.ticket_?.state_?.name ?? "";
// /JSONField
for (const key of Object.keys(flat)) {
if (Array.isArray(flat[key])) {
flat[key] = flat[key].join("、");
}
}
//
if (row.is_lending !== undefined) flat._is_lending_text = row.is_lending ? "是" : "否";
if (row.is_city !== undefined) flat._is_city_text = row.is_city ? "是" : "否";
if (row.is_change !== undefined) flat._is_change_text = row.is_change ? "是" : "否";
if (row.is_promotion !== undefined) flat._is_promotion_text = row.is_promotion ? "是" : "否";
return flat;
});
},
// columns /type_dict key
getFlatColumns() {
return this.columns.map(col => {
if (col.key === "ticket_.act_state") return { ...col, key: "_act_state_text", type_dict: undefined };
if (col.key === "is_lending") return { ...col, key: "_is_lending_text", type_dict: undefined };
if (col.key === "is_city") return { ...col, key: "_is_city_text", type_dict: undefined };
return col;
});
},
doExport(data) {
const flatData = this.flattenData(data);
const flatCols = this.getFlatColumns();
dataToExcel(flatCols, flatData, this.fileName);
},
handleExport(command) {
const table = this.getTableRef();
if (!table) return;
if (command === "page") {
this.doExport(table.tableData);
} else if (command === "all") {
const query = Object.assign({}, table.query, table.tableParams, { page: 0 });
const loading = this.$loading({ lock: true, text: "数据导出中...", background: "rgba(0,0,0,0.1)" });
table.apiObj.req(query).then((res) => {
loading.close();
this.doExport(res);
}).catch((err) => {
loading.close();
console.error("导出失败", err);
this.$message.error("导出失败");
});
}
},
},
};
</script>

View File

@ -7,6 +7,7 @@
icon="el-icon-plus" icon="el-icon-plus"
@click="handleAdd" @click="handleAdd"
></el-button> ></el-button>
<ExportBtn :getTableRef="() => $refs.table" :columns="exportCols" fileName="会议室预约台账" />
</div> </div>
<div class="right-panel"> <div class="right-panel">
<el-date-picker <el-date-picker
@ -79,10 +80,11 @@
<script> <script>
import bookingDialog from "./mroombooking_form.vue"; import bookingDialog from "./mroombooking_form.vue";
import ExportBtn from "./exportBtn.vue";
import { actStateEnum, interveneTypeEnum } from "@/utils/enum.js"; import { actStateEnum, interveneTypeEnum } from "@/utils/enum.js";
export default { export default {
name: "index", name: "index",
components: { bookingDialog }, components: { bookingDialog, ExportBtn },
data() { data() {
return { return {
actStateEnum, interveneTypeEnum, actStateEnum, interveneTypeEnum,
@ -97,7 +99,14 @@ export default {
edit: "编辑会议预定", edit: "编辑会议预定",
show: "查看会议预定", show: "查看会议预定",
}, },
mRoomList: [] mRoomList: [],
exportCols: [
{ header: "标题", key: "title", wch: 20 },
{ header: "会议室名称", key: "mroom_name", wch: 15 },
{ header: "预约日期", key: "mdate", wch: 15 },
{ header: "预约时间", key: "time_ranges", wch: 25 },
{ header: "审批状态", key: "_act_state_text", wch: 12 },
],
}; };
}, },
mounted() { mounted() {
@ -135,7 +144,7 @@ export default {
await this.$API.ofm.mroombooking.checkDelete.req(id); await this.$API.ofm.mroombooking.checkDelete.req(id);
this.$message.success("删除成功"); this.$message.success("删除成功");
this.$refs.table.refresh(); this.$refs.table.refresh();
} catch (error) { } catch (error) { // eslint-disable-line no-empty
} }
}, },
// //

View File

@ -7,6 +7,7 @@
icon="el-icon-plus" icon="el-icon-plus"
@click="handleAdd" @click="handleAdd"
></el-button> ></el-button>
<ExportBtn :getTableRef="() => $refs.table" :columns="exportCols" fileName="宣传报道台账" />
</div> </div>
</el-header> </el-header>
<el-main class="nopadding"> <el-main class="nopadding">
@ -76,7 +77,21 @@
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="操作" fixed="right" align="center" width="250"> <el-table-column
label="终版文件"
min-width="120"
align="center">
<template #default="scope">
<el-link
v-if="scope.row.final_file"
type="primary"
:href="scope.row.final_file"
target="_blank"
>查看文件</el-link>
<span v-else style="color:#999">未上传</span>
</template>
</el-table-column>
<el-table-column label="操作" fixed="right" align="center" width="300">
<template #default="scope"> <template #default="scope">
<el-button <el-button
link link
@ -85,6 +100,14 @@
@click="publicityShow(scope.row)" @click="publicityShow(scope.row)"
>详情 >详情
</el-button> </el-button>
<el-button
v-if="scope.row.ticket_?.state_?.name === '档案管理员审批'"
link
size="small"
type="success"
@click="handleUploadFinal(scope.row)"
>终版上传
</el-button>
<el-popconfirm <el-popconfirm
title="确定删除吗?" title="确定删除吗?"
@confirm="handleDel(scope.row)" @confirm="handleDel(scope.row)"
@ -119,12 +142,30 @@
</div> </div>
</div> </div>
</el-drawer> </el-drawer>
<el-dialog
v-model="uploadVisible"
title="终版文件上传"
width="500px"
:destroy-on-close="true">
<sc-upload-file
v-model="finalFilePath"
:multiple="false"
:limit="1"
accept=".pdf,.doc,.docx,.jpg,.png,.jpeg">
<el-button type="primary" icon="el-icon-upload">选择文件</el-button>
</sc-upload-file>
<template #footer>
<el-button @click="uploadVisible = false">取消</el-button>
<el-button type="primary" :loading="uploadLoading" @click="submitFinalFile">确认上传</el-button>
</template>
</el-dialog>
</template> </template>
<script> <script>
import publicity from "./publicity_form.vue"; import publicity from "./publicity_form.vue";
import ExportBtn from "./exportBtn.vue";
import { actStateEnum, interveneTypeEnum } from "@/utils/enum.js"; import { actStateEnum, interveneTypeEnum } from "@/utils/enum.js";
export default { export default {
components: {publicity}, components: {publicity, ExportBtn},
name: "index", name: "index",
data() { data() {
return { return {
@ -134,6 +175,25 @@ export default {
limitedVisible: false, limitedVisible: false,
mode: "show", mode: "show",
t_id: null, t_id: null,
uploadVisible: false,
uploadLoading: false,
finalFilePath: "",
uploadRowId: null,
exportCols: [
{ header: "记录编号", key: "number", wch: 15 },
{ header: "送审稿件标题", key: "title", wch: 20 },
{ header: "所有撰稿人", key: "participants", wch: 15 },
{ header: "所在部门", key: "belong_dept_name", wch: 15 },
{ header: "涉密等级", key: "level", wch: 12 },
{ header: "稿件内容涉及", key: "content", wch: 20 },
{ header: "宣传报道目的", key: "report_purpose", wch: 20 },
{ header: "宣传报道渠道", key: "channel", wch: 15 },
{ header: "第一撰稿人自审", key: "review", wch: 15 },
{ header: "部门负责人意见", key: "dept_opinion", wch: 15 },
{ header: "总经理意见", key: "dept_opinion_review", wch: 15 },
{ header: "终版文件", key: "final_file", wch: 25 },
{ header: "审批状态", key: "_act_state_text", wch: 12 },
],
}; };
}, },
@ -154,6 +214,31 @@ export default {
this.$refs.table.refresh(); this.$refs.table.refresh();
this.$message.success("删除成功"); this.$message.success("删除成功");
}, },
handleUploadFinal(row) {
this.uploadRowId = row.id;
this.finalFilePath = row.final_file || "";
this.uploadVisible = true;
},
async submitFinalFile() {
if (!this.finalFilePath) {
this.$message.warning("请先选择文件");
return;
}
this.uploadLoading = true;
try {
await this.$API.ofm.publicity.update.req(this.uploadRowId, {
final_file: this.finalFilePath,
});
this.$message.success("终版文件上传成功");
this.uploadVisible = false;
this.$refs.table.refresh();
} catch (e) {
console.error(e);
this.$message.error("上传失败");
} finally {
this.uploadLoading = false;
}
},
// //
handleQuery() { handleQuery() {
this.$refs.table.queryData(this.query); this.$refs.table.queryData(this.query);

View File

@ -76,28 +76,26 @@
<el-radio label="内容涉及国家秘密,申请按涉密渠道发布"></el-radio> <el-radio label="内容涉及国家秘密,申请按涉密渠道发布"></el-radio>
</el-radio-group> </el-radio-group>
</el-form-item> </el-form-item>
<el-form-item label="所在部室定密意见" prop="dept_opinion" v-if="['部门领导审批', '总经理审批', '结束'].includes(addForm.ticket_?.state_?.name)"> <!-- 所在部室定密意见部门负责人审批可填综合管理部审批/总经理审批/档案管理员审批/结束只读 -->
<el-form-item label="所在部室定密意见" prop="dept_opinion" v-if="['部门负责人审批','综合管理部审批','总经理审批','档案管理员审批','结束'].includes(stateName)">
<div class="dept-opinion-wrap"> <div class="dept-opinion-wrap">
<div> <div>
<el-radio-group v-model="addForm.dept_opinion" style="display: inline;" :disabled="addForm.ticket_?.state_?.name === '总经理审批'"> <el-radio-group v-model="addForm.dept_opinion" style="display: inline;" :disabled="stateName !== '部门负责人审批'">
<el-radio label="不符合定密要求">不符合定密要求</el-radio> <el-radio label="不符合定密要求">不符合定密要求</el-radio>
<el-radio label="同意内容为涉密事项">同意内容为涉密事项</el-radio> <el-radio label="同意内容为涉密事项">同意内容为涉密事项</el-radio>
</el-radio-group> </el-radio-group>
</div> </div>
<!-- 根据选择显示不同的选项 -->
<div v-if="addForm.dept_opinion === '不符合定密要求'" style="margin-top: 8px;"> <div v-if="addForm.dept_opinion === '不符合定密要求'" style="margin-top: 8px;">
<span>应做</span> <span>应做</span>
<el-radio-group v-model="disposalMethod" style="display: inline; margin-left: 5px;" :disabled="addForm.ticket_?.state_?.name === '总经理审批'"> <el-radio-group v-model="disposalMethod" style="display: inline; margin-left: 5px;" :disabled="stateName !== '部门负责人审批'">
<el-radio label="公开">公开</el-radio> <el-radio label="公开">公开</el-radio>
<el-radio label="受控">受控</el-radio> <el-radio label="受控">受控</el-radio>
</el-radio-group> </el-radio-group>
<span>处理</span> <span>处理</span>
</div> </div>
<div v-if="addForm.dept_opinion === '同意内容为涉密事项'" style="margin-top: 8px;"> <div v-if="addForm.dept_opinion === '同意内容为涉密事项'" style="margin-top: 8px;">
<span>涉密等级为</span> <span>涉密等级为</span>
<el-radio-group v-model="addForm.secret_level" style="display: inline; margin-left: 5px;"> <el-radio-group v-model="addForm.secret_level" style="display: inline; margin-left: 5px;" :disabled="stateName !== '部门负责人审批'">
<el-radio label="机密">机密</el-radio> <el-radio label="机密">机密</el-radio>
<el-radio label="秘密">秘密</el-radio> <el-radio label="秘密">秘密</el-radio>
</el-radio-group> </el-radio-group>
@ -107,26 +105,44 @@
placeholder="请输入期限" placeholder="请输入期限"
style="width: 200px; margin-left: 5px;" style="width: 200px; margin-left: 5px;"
size="small" size="small"
:disabled="stateName !== '部门负责人审批'"
/> />
<span>请按总院管理要求做好保密管理</span> <span>请按总院管理要求做好保密管理</span>
</div> </div>
</div> </div>
</el-form-item> </el-form-item>
<el-form-item label="综合管理部审查意见" prop="dept_opinion_review" v-if="['部门领导审批', '总经理审批', '结束'].includes(addForm.ticket_?.state_?.name)"> <!-- 综合管理部审查意见综合管理部审批可填总经理审批/档案管理员审批/结束只读 -->
<el-radio-group v-model="addForm.dept_opinion_review" :disabled="addForm.ticket_?.state_?.name === '总经理审批'"> <el-form-item label="综合管理部审查意见" prop="dept_opinion_review" v-if="['综合管理部审批','总经理审批','档案管理员审批','结束'].includes(stateName)">
<el-radio-group v-model="addForm.dept_opinion_review" :disabled="stateName !== '综合管理部审批'">
<el-radio label="内容不涉及国家秘密和商业秘密,同意公开"></el-radio> <el-radio label="内容不涉及国家秘密和商业秘密,同意公开"></el-radio>
<el-radio label="内容不涉及国家秘密、但涉及商业秘密,同意受控公开"></el-radio> <el-radio label="内容不涉及国家秘密、但涉及商业秘密,同意受控公开"></el-radio>
<el-radio label="内容涉及国家秘密,同意按涉密渠道发布"></el-radio> <el-radio label="内容涉及国家秘密,同意按涉密渠道发布"></el-radio>
</el-radio-group> </el-radio-group>
</el-form-item> </el-form-item>
<el-form-item label="总经理审查意见" prop="publicity_opinion" v-if="['总经理审批', '结束'].includes(addForm.ticket_?.state_?.name)"> <!-- 总经理审查意见总经理审批可填档案管理员审批/结束只读 -->
<el-radio-group v-model="addForm.publicity_opinion"> <el-form-item label="总经理审查意见" prop="publicity_opinion" v-if="['总经理审批','档案管理员审批','结束'].includes(stateName)">
<el-radio-group v-model="addForm.publicity_opinion" :disabled="stateName !== '总经理审批'">
<el-radio label="同意公开宣传报道"></el-radio> <el-radio label="同意公开宣传报道"></el-radio>
<el-radio label="同意受控报道"></el-radio> <el-radio label="同意受控报道"></el-radio>
<el-radio label="同意按涉密渠道宣传报道"></el-radio> <el-radio label="同意按涉密渠道宣传报道"></el-radio>
<el-radio label="不同意任何渠道的宣传报道"></el-radio> <el-radio label="不同意任何渠道的宣传报道"></el-radio>
</el-radio-group> </el-radio-group>
</el-form-item> </el-form-item>
<!-- 终版文件档案管理员审批可上传结束可查看 -->
<el-form-item v-if="['档案管理员审批','结束'].includes(stateName)" :required="stateName === '档案管理员审批'" label="终版文件">
<div v-if="stateName === '档案管理员审批'">
<sc-upload-file
v-model="finalFileValue"
:multiple="false"
:limit="1"
accept=".pdf,.doc,.docx,.jpg,.png,.jpeg">
<el-button type="primary" icon="el-icon-upload">上传终版文件</el-button>
</sc-upload-file>
<el-link v-if="addForm.final_file" type="primary" :href="addForm.final_file" target="_blank" style="margin-top:8px">{{ addForm.final_file }}</el-link>
</div>
<el-link v-else-if="addForm.final_file" type="primary" :href="addForm.final_file" target="_blank">查看终版文件</el-link>
<span v-else style="color:#999">未上传</span>
</el-form-item>
</el-form> </el-form>
<el-footer> <el-footer>
<ticketd_b <ticketd_b
@ -219,9 +235,23 @@ export default {
'addForm.publicity_opinion'(val) { 'addForm.publicity_opinion'(val) {
this.ticket_data.publicity_opinion = val this.ticket_data.publicity_opinion = val
}, },
'addForm.final_file'(val) {
this.ticket_data.final_file = val
},
deep:true deep:true
}, },
computed: { computed: {
stateName() {
return this.addForm.ticket_?.state_?.name || '';
},
finalFileValue: {
get() {
return this.addForm.final_file || "";
},
set(val) {
this.addForm.final_file = val;
}
},
disposalMethod: { disposalMethod: {
get() { get() {
return this.addForm.disposal_method || ''; return this.addForm.disposal_method || '';
@ -234,14 +264,18 @@ export default {
methods: { methods: {
async submit_b_func() { async submit_b_func() {
let that = this; let that = this;
if (that.stateName === '档案管理员审批' && !that.addForm.final_file) {
that.$message.warning("请先上传终版文件");
throw new Error("终版文件必填");
}
if (that.localMode === "add") { if (that.localMode === "add") {
let res = await that.$API.ofm.publicity.create.req(that.addForm); let res = await that.$API.ofm.publicity.create.req(that.addForm);
that.addForm.id = res.id; that.addForm.id = res.id;
} else if (that.localMode === "edit"){ } else {
await that.$API.ofm.publicity.update.req( await that.$API.ofm.publicity.update.req(
that.addForm.id, that.addForm.id,
that.addForm that.addForm
); );
} }
}, },
getTid (){ getTid (){

View File

@ -7,6 +7,7 @@
icon="el-icon-plus" icon="el-icon-plus"
@click="handleAdd" @click="handleAdd"
>新增</el-button> >新增</el-button>
<ExportBtn :getTableRef="() => $refs.table" :columns="exportCols" fileName="用印申请台账" />
</div> </div>
<div class="right-panel"> <div class="right-panel">
<el-input <el-input
@ -80,6 +81,15 @@
<span v-else></span> <span v-else></span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column
label="终版文件"
min-width="80"
align="center">
<template #default="scope">
<el-link v-if="scope.row.final_file" type="primary" :href="scope.row.final_file" target="_blank">查看文件</el-link>
<span v-else style="color:#999">未上传</span>
</template>
</el-table-column>
<el-table-column label="审批信息" width="200"> <el-table-column label="审批信息" width="200">
<template #default="scope"> <template #default="scope">
<el-tag :type="actStateEnum[scope.row.ticket_?.act_state]?.type"> <el-tag :type="actStateEnum[scope.row.ticket_?.act_state]?.type">
@ -138,9 +148,10 @@
</template> </template>
<script> <script>
import SealForm from "./seal_form.vue"; import SealForm from "./seal_form.vue";
import ExportBtn from "./exportBtn.vue";
import { actStateEnum, interveneTypeEnum } from "@/utils/enum.js"; import { actStateEnum, interveneTypeEnum } from "@/utils/enum.js";
export default { export default {
components: { SealForm}, components: { SealForm, ExportBtn},
name: "index", name: "index",
data() { data() {
return { return {
@ -150,6 +161,20 @@ export default {
limitedVisible: false, limitedVisible: false,
mode: "show", mode: "show",
t_id: null, t_id: null,
exportCols: [
{ header: "用印时间", key: "create_time", wch: 20 },
{ header: "用印类别", key: "seal", wch: 15 },
{ header: "文件(资料)名称", key: "filename", wch: 25 },
{ header: "份数", key: "file_count", wch: 8 },
{ header: "印章部门", key: "belong_dept_name", wch: 15 },
{ header: "用印人", key: "create_by_name", wch: 12 },
{ header: "借出时间", key: "lending_date", wch: 15 },
{ header: "拟归还时间", key: "return_date", wch: 15 },
{ header: "实际归还时间", key: "actual_return_date", wch: 15 },
{ header: "是否借出", key: "_is_lending_text", wch: 10 },
{ header: "终版文件", key: "final_file", wch: 25 },
{ header: "审批状态", key: "_act_state_text", wch: 12 },
],
}; };
}, },
methods: { methods: {

View File

@ -80,13 +80,28 @@
</sc-upload-file> </sc-upload-file>
</el-form-item> </el-form-item>
<el-form-item label="用印份数" prop="file_count"> <el-form-item label="用印份数" prop="file_count">
<el-input-number <el-input-number
v-model="localForm.file_count" v-model="localForm.file_count"
:min="0" :min="0"
:step="1" :step="1"
controls-position="right" controls-position="right"
:disabled="localMode ==='show'"></el-input-number> :disabled="localMode ==='show'"></el-input-number>
</el-form-item> </el-form-item>
<!-- 终版文件提交人处理可上传结束可查看 -->
<el-form-item v-if="['提交人处理','结束'].includes(stateName)" :required="stateName === '提交人处理'" label="终版文件">
<div v-if="stateName === '提交人处理'">
<sc-upload-file
v-model="finalFileValue"
:multiple="false"
:limit="1"
accept=".pdf,.doc,.docx,.jpg,.png,.jpeg,.xlsx,.xls">
<el-button type="primary" icon="el-icon-upload">上传终版文件</el-button>
</sc-upload-file>
<el-link v-if="localForm.final_file" type="primary" :href="localForm.final_file" target="_blank" style="margin-top:8px">{{ localForm.final_file }}</el-link>
</div>
<el-link v-else-if="localForm.final_file" type="primary" :href="localForm.final_file" target="_blank">查看终版文件</el-link>
<span v-else style="color:#999">未上传</span>
</el-form-item>
</el-form> </el-form>
<el-footer> <el-footer>
<ticketd_b <ticketd_b
@ -155,6 +170,22 @@ export default {
'localForm.actual_return_date'(val) { 'localForm.actual_return_date'(val) {
this.ticket_data.actual_return_date = val this.ticket_data.actual_return_date = val
}, },
'localForm.final_file'(val) {
this.ticket_data.final_file = val
},
},
computed: {
stateName() {
return this.localForm.ticket_?.state_?.name || '';
},
finalFileValue: {
get() {
return this.localForm.final_file || "";
},
set(val) {
this.localForm.final_file = val;
}
},
}, },
methods: { methods: {
handleDateChange(val) { handleDateChange(val) {
@ -163,11 +194,14 @@ export default {
}, },
async submit_b_func() { async submit_b_func() {
let that = this; let that = this;
if (that.stateName === '提交人处理' && !that.localForm.final_file) {
that.$message.warning("请先上传终版文件");
throw new Error("终版文件必填");
}
if(that.localMode == "add") { if(that.localMode == "add") {
let res = await that.$API.ofm.lendingseal.create.req(that.localForm); let res = await that.$API.ofm.lendingseal.create.req(that.localForm);
that.localForm.id = res.id; that.localForm.id = res.id;
} else if (that.localMode == "edit") { } else {
await that.$API.ofm.lendingseal.update.req(that.localForm.id, that.localForm); await that.$API.ofm.lendingseal.update.req(that.localForm.id, that.localForm);
} }
}, },

View File

@ -7,6 +7,7 @@
icon="el-icon-plus" icon="el-icon-plus"
@click="handleAdd" @click="handleAdd"
></el-button> ></el-button>
<ExportBtn :getTableRef="() => $refs.table" :columns="exportCols" fileName="用车申请台账" />
</div> </div>
<div class="right-panel"> <div class="right-panel">
<el-date-picker <el-date-picker
@ -155,10 +156,11 @@
<script> <script>
import VehicleForm from "./vehicle_form.vue"; import VehicleForm from "./vehicle_form.vue";
import ExportBtn from "./exportBtn.vue";
import { actStateEnum, interveneTypeEnum } from "@/utils/enum.js"; import { actStateEnum, interveneTypeEnum } from "@/utils/enum.js";
export default { export default {
components: { components: {
VehicleForm VehicleForm, ExportBtn
}, },
name: "index", name: "index",
data() { data() {
@ -169,7 +171,22 @@ export default {
limitedVisible: false, limitedVisible: false,
type: "show", type: "show",
t_id: null, t_id: null,
vehicleList: [] vehicleList: [],
exportCols: [
{ header: "日期", key: "create_time", wch: 20 },
{ header: "用车部门", key: "belong_dept_name", wch: 15 },
{ header: "用车人", key: "create_by_name", wch: 12 },
{ header: "用车事由", key: "reason", wch: 20 },
{ header: "接待人员", key: "reception", wch: 12 },
{ header: "市内用车", key: "_is_city_text", wch: 10 },
{ header: "发车地点", key: "location", wch: 15 },
{ header: "途经地点", key: "via", wch: 15 },
{ header: "到达地点", key: "destination", wch: 15 },
{ header: "出发公里(km)", key: "start_km", wch: 14 },
{ header: "结束公里(km)", key: "end_km", wch: 14 },
{ header: "使用公里(km)", key: "actual_km", wch: 14 },
{ header: "审批状态", key: "_act_state_text", wch: 12 },
],
}; };
}, },
mounted(){ mounted(){

View File

@ -4,6 +4,7 @@
</div> </div>
</template> </template>
<script> <script>
/* global gantt */
import GanttComponent from '@/components/GanttComponent.vue'; import GanttComponent from '@/components/GanttComponent.vue';
export default { export default {
name: "rparty", name: "rparty",

View File

@ -144,6 +144,7 @@
</el-drawer> </el-drawer>
</template> </template>
<script> <script>
/* global gantt */
import GanttComponent from '@/components/GanttComponent.vue'; import GanttComponent from '@/components/GanttComponent.vue';
import saveDialog from "./utask_form.vue"; import saveDialog from "./utask_form.vue";
import { useTransitionFallthroughEmits } from 'element-plus'; import { useTransitionFallthroughEmits } from 'element-plus';

View File

@ -238,6 +238,7 @@
></save-dialog> ></save-dialog>
</template> </template>
<script> <script>
/* global gantt */
import saveDialog from "./utask_form.vue"; import saveDialog from "./utask_form.vue";
import showDrawer from "./mtask_drawer.vue"; import showDrawer from "./mtask_drawer.vue";
import GanttComponent from "@/components/GanttComponent.vue"; import GanttComponent from "@/components/GanttComponent.vue";

View File

@ -232,6 +232,7 @@
></save-dialog> ></save-dialog>
</template> </template>
<script> <script>
/* global gantt */
import saveDialog from "./utask_form.vue"; import saveDialog from "./utask_form.vue";
import showDrawer from "./mtask_drawer.vue"; import showDrawer from "./mtask_drawer.vue";
import GanttComponent from "@/components/GanttComponent.vue"; import GanttComponent from "@/components/GanttComponent.vue";

View File

@ -240,6 +240,7 @@
</showDrawer> </showDrawer>
</template> </template>
<script> <script>
/* global gantt */
import GanttComponent from "@/components/GanttComponent.vue"; import GanttComponent from "@/components/GanttComponent.vue";
import saveDialog from "./utask_form_2.vue"; import saveDialog from "./utask_form_2.vue";
import showDrawer from "./mtask_drawer.vue"; import showDrawer from "./mtask_drawer.vue";

View File

@ -261,6 +261,7 @@
></save-dialog> ></save-dialog>
</template> </template>
<script> <script>
/* global gantt */
import saveDialog from "./utask_form.vue"; import saveDialog from "./utask_form.vue";
import showDrawer from "./mtask_drawer.vue"; import showDrawer from "./mtask_drawer.vue";
import GanttComponent from "@/components/GanttComponent.vue"; import GanttComponent from "@/components/GanttComponent.vue";

View File

@ -3,6 +3,7 @@
<el-header> <el-header>
<div class="left-panel"> <div class="left-panel">
<el-button type="primary" @click="handleAdd">新增</el-button> <el-button type="primary" @click="handleAdd">新增</el-button>
<ExportBtn :getTableRef="() => $refs.table" :columns="exportCols" fileName="供应商审核台账" />
</div> </div>
</el-header> </el-header>
@ -53,6 +54,7 @@
import { ref } from 'vue' import { ref } from 'vue'
import API from '@/api' import API from '@/api'
import supplieraudit_form from './supplieraudit_form.vue' import supplieraudit_form from './supplieraudit_form.vue'
import ExportBtn from '@/components/scExportBtn/index.vue'
import { actStateEnum, interveneTypeEnum } from "@/utils/enum.js"; import { actStateEnum, interveneTypeEnum } from "@/utils/enum.js";
const query = ref({}); const query = ref({});
const drawerVisible = ref(false); const drawerVisible = ref(false);
@ -62,4 +64,10 @@ const handleAdd = () => {
mode.value = 'add'; mode.value = 'add';
drawerVisible.value = true; drawerVisible.value = true;
} }
const exportCols = [
{ header: "供应商名称", key: "name", wch: 20 },
{ header: "审批状态", key: "_act_state_text", wch: 10 },
{ header: "物料名称", key: "material_name", wch: 20 },
{ header: "物料类别", key: "material_cate", wch: 20 },
]
</script> </script>