340 lines
12 KiB
Vue
340 lines
12 KiB
Vue
<template>
|
||
<div class="request-page">
|
||
<el-row :gutter="20">
|
||
<el-col :span="8">
|
||
<el-card class="form-card" shadow="never">
|
||
<div slot="header" class="card-header">
|
||
<span>用印申请</span>
|
||
|
||
</div>
|
||
<el-form ref="formRef" :model="form" :rules="rules" label-width="120px" size="small" class="metal-form">
|
||
<div class="form-summary">
|
||
<div class="summary-left">
|
||
<div class="summary-title">发起用印</div>
|
||
<div class="summary-sub">请完善信息后提交,系统会推送部门负责人审批</div>
|
||
</div>
|
||
<div class="summary-right">
|
||
<div class="summary-item">
|
||
<div class="k">申请人</div>
|
||
<div class="v">{{ currentApplicantText }}</div>
|
||
</div>
|
||
<div class="summary-item">
|
||
<div class="k">用印类型</div>
|
||
<div class="v">{{ form.sealType || '-' }}</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<el-form-item label="审批部门" prop="deptId">
|
||
<el-select v-model="form.deptId" placeholder="请选择审批部门" filterable @change="onDeptChange" style="width: 100%">
|
||
<el-option
|
||
v-for="item in deptOptions"
|
||
:key="item.deptId"
|
||
:label="item.deptName + (item.leaderNickName ? '(负责人:' + item.leaderNickName + ')' : '(无负责人)')"
|
||
:value="item.deptId"
|
||
/>
|
||
</el-select>
|
||
<div class="hint-text">系统将根据部门负责人自动创建审批任务</div>
|
||
</el-form-item>
|
||
|
||
<el-form-item label="用印类型" prop="sealType">
|
||
<el-select
|
||
v-model="form.sealType"
|
||
filterable
|
||
allow-create
|
||
default-first-option
|
||
clearable
|
||
placeholder="选择或输入用印类型"
|
||
style="width: 100%"
|
||
>
|
||
<el-option
|
||
v-for="dictItem in (dict.type.hrm_stamp_image || [])"
|
||
:key="dictItem.value"
|
||
:label="dictItem.label"
|
||
:value="dictItem.label"
|
||
/>
|
||
</el-select>
|
||
<div class="hint-text">优先从字典选择;若字典未配置,可直接输入</div>
|
||
</el-form-item>
|
||
|
||
<div class="block-title">用途与材料</div>
|
||
<el-form-item label="用途说明" prop="purpose">
|
||
<el-input v-model="form.purpose" type="textarea" :rows="4" placeholder="请说明用印用途、对象、份数等" show-word-limit maxlength="200" />
|
||
</el-form-item>
|
||
|
||
<el-form-item label="待盖章PDF" prop="applyFileIds">
|
||
<file-upload
|
||
v-model="form.applyFileIds"
|
||
:limit="1"
|
||
:file-size="50"
|
||
:file-type="['pdf']"
|
||
/>
|
||
<div class="hint-text">仅支持 PDF,单个文件不超过 50MB</div>
|
||
</el-form-item>
|
||
|
||
<el-form-item label="盖章页码" prop="pageNo" v-if="form.applyFileIds">
|
||
<el-input-number
|
||
v-model="form.pageNo"
|
||
:min="1"
|
||
:max="999"
|
||
controls-position="right"
|
||
placeholder="请输入需要盖章的页码(从第1页开始)"
|
||
style="width: 100%"
|
||
/>
|
||
<div class="hint-text">请输入需要盖章的页码,从第1页开始计数</div>
|
||
</el-form-item>
|
||
|
||
<el-form-item label="需要回执" prop="receiptRequired">
|
||
<el-switch v-model="form.receiptRequired" :active-value="1" :inactive-value="0" />
|
||
<div class="hint-text">开启后,盖章完成通常需要回传回执文件</div>
|
||
</el-form-item>
|
||
|
||
<el-form-item label="备注">
|
||
<el-input v-model="form.remark" type="textarea" :rows="2" placeholder="可选:补充说明" show-word-limit maxlength="200" />
|
||
</el-form-item>
|
||
|
||
<div class="form-actions">
|
||
<el-button @click="$router.back()">取消</el-button>
|
||
<el-button type="primary" :loading="submitting" @click="submit">提交申请</el-button>
|
||
</div>
|
||
</el-form>
|
||
</el-card>
|
||
</el-col>
|
||
<el-col :span="16">
|
||
<el-card class="list-card" shadow="never">
|
||
<div slot="header" class="card-header">
|
||
<span>我的用印申请</span>
|
||
<div class="actions">
|
||
<el-button size="mini" icon="el-icon-refresh" @click="getList">刷新</el-button>
|
||
</div>
|
||
</div>
|
||
<el-table v-loading="listLoading" :data="sealList" border>
|
||
<el-table-column label="状态" align="center" width="100">
|
||
<template slot-scope="scope">
|
||
<el-tag :type="statusType(scope.row.status)">{{ statusText(scope.row.status) }}</el-tag>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column label="用印类型" align="center" prop="sealType" />
|
||
<el-table-column label="用途说明" align="center" prop="purpose" show-overflow-tooltip />
|
||
<el-table-column label="申请时间" align="center" prop="createTime" width="160">
|
||
<template slot-scope="scope">
|
||
<span>{{ parseTime(scope.row.createTime, '{y}-{m}-{d} {h}:{i}') }}</span>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column label="操作" align="center" width="200">
|
||
<template slot-scope="scope">
|
||
<el-button size="mini" type="text" @click="goDetail(scope.row)">查看</el-button>
|
||
<el-button v-if="canPreviewReceipt(scope.row)" size="mini" type="text" @click="previewReceipt(scope.row)">预览</el-button>
|
||
<el-button v-if="canPreviewReceipt(scope.row)" size="mini" type="text" @click="downloadReceipt(scope.row)">下载</el-button>
|
||
</template>
|
||
</el-table-column>
|
||
</el-table>
|
||
<pagination
|
||
v-show="total > 0"
|
||
:total="total"
|
||
:page.sync="queryParams.pageNum"
|
||
:limit.sync="queryParams.pageSize"
|
||
@pagination="getList"
|
||
/>
|
||
</el-card>
|
||
</el-col>
|
||
</el-row>
|
||
</div>
|
||
</template>
|
||
|
||
<script>
|
||
import { addSealReq, listSealReq } from '@/api/wms/seal'
|
||
import { listDept } from '@/api/wms/dept'
|
||
import FileUpload from '@/components/FileUpload'
|
||
|
||
export default {
|
||
name: 'WmsSealRequest',
|
||
dicts: ['hrm_stamp_image'],
|
||
components: { FileUpload },
|
||
data() {
|
||
return {
|
||
submitting: false,
|
||
listLoading: false,
|
||
deptOptions: [],
|
||
sealList: [],
|
||
total: 0,
|
||
queryParams: {
|
||
pageNum: 1,
|
||
pageSize: 10,
|
||
createBy: this.$store.getters.name
|
||
},
|
||
form: {
|
||
empId: this.$store.getters.id,
|
||
deptId: '',
|
||
sealType: '',
|
||
purpose: '',
|
||
applyFileIds: '',
|
||
pageNo: 1,
|
||
receiptRequired: 0,
|
||
remark: ''
|
||
},
|
||
rules: {
|
||
deptId: [{ required: true, message: '请选择审批部门', trigger: 'change' }],
|
||
sealType: [{ required: true, message: '请选择/输入用印类型', trigger: 'change' }],
|
||
purpose: [{ required: true, message: '请填写用途说明', trigger: 'blur' }],
|
||
applyFileIds: [{ required: true, message: '请上传 PDF 附件', trigger: 'change' }],
|
||
pageNo: [{ required: true, message: '请输入盖章页码', trigger: 'blur' }],
|
||
receiptRequired: [{ required: true, message: '请选择是否需要回执', trigger: 'change' }]
|
||
}
|
||
}
|
||
},
|
||
computed: {
|
||
currentApplicantText() {
|
||
const user = this.$store?.state?.user || {}
|
||
return user.nickName || user.userName || '当前用户'
|
||
}
|
||
},
|
||
created() {
|
||
this.loadDeptList()
|
||
this.getList()
|
||
},
|
||
methods: {
|
||
async loadDeptList() {
|
||
try {
|
||
const res = await listDept()
|
||
this.deptOptions = res.data || []
|
||
} catch (e) {
|
||
this.deptOptions = []
|
||
}
|
||
},
|
||
onDeptChange() {},
|
||
statusText(status) {
|
||
const map = { running: '审批中', draft: '草稿', approved: '已通过', rejected: '已驳回', canceled: '已撤销', pending: '待审批' }
|
||
return map[status] || status || '-'
|
||
},
|
||
statusType(status) {
|
||
const map = { running: 'warning', draft: 'info', approved: 'success', rejected: 'danger', canceled: 'info', pending: 'warning' }
|
||
return map[status] || 'info'
|
||
},
|
||
getList() {
|
||
this.listLoading = true
|
||
listSealReq(this.queryParams)
|
||
.then(res => {
|
||
this.sealList = res.rows || []
|
||
this.total = res.total || 0
|
||
})
|
||
.finally(() => {
|
||
this.listLoading = false
|
||
})
|
||
},
|
||
goDetail(row) {
|
||
this.$router.push({ path: '/job/sealDetail', query: { bizId: row.bizId } })
|
||
},
|
||
canPreviewReceipt(row) {
|
||
return row.status === 'approved' && row.receiptFileIds
|
||
},
|
||
previewReceipt(row) {
|
||
if (row.receiptFileIds) {
|
||
window.open(row.receiptFileIds, '_blank')
|
||
}
|
||
},
|
||
downloadReceipt(row) {
|
||
if (row.receiptFileIds) {
|
||
window.open(row.receiptFileIds, '_blank')
|
||
}
|
||
},
|
||
async submit() {
|
||
try {
|
||
await this.$refs.formRef.validate()
|
||
this.submitting = true
|
||
let remark = this.form.remark || ''
|
||
if (this.form.pageNo) {
|
||
remark = remark ? `${remark}\n[盖章页码:第${this.form.pageNo}页]` : `[盖章页码:第${this.form.pageNo}页]`
|
||
}
|
||
const payload = {
|
||
empId: this.form.empId,
|
||
deptId: this.form.deptId,
|
||
sealType: this.form.sealType,
|
||
purpose: this.form.purpose,
|
||
applyFileIds: this.form.applyFileIds,
|
||
receiptRequired: this.form.receiptRequired,
|
||
remark,
|
||
status: 'pending'
|
||
}
|
||
await addSealReq(payload)
|
||
this.$message.success('提交成功')
|
||
this.getList()
|
||
} finally {
|
||
this.submitting = false
|
||
}
|
||
}
|
||
}
|
||
}
|
||
</script>
|
||
|
||
<style lang="scss" scoped>
|
||
.request-page {
|
||
padding: 16px 20px 32px;
|
||
background: transparent;
|
||
}
|
||
.form-card {
|
||
max-width: 980px;
|
||
margin: 0 auto;
|
||
border: 1px solid #eef0f4;
|
||
border-radius: 10px;
|
||
background: #ffffff;
|
||
box-shadow: none;
|
||
}
|
||
.list-card {
|
||
border: 1px solid #eef0f4;
|
||
border-radius: 10px;
|
||
box-shadow: none;
|
||
background: #ffffff;
|
||
}
|
||
.card-header {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
font-weight: 600;
|
||
color: #2b2f36;
|
||
}
|
||
.actions {
|
||
display: flex;
|
||
gap: 8px;
|
||
}
|
||
.metal-form { padding-right: 8px; }
|
||
.block-title {
|
||
margin: 18px 0 10px;
|
||
padding-left: 10px;
|
||
font-weight: 600;
|
||
color: #2f3440;
|
||
border-left: 2px solid #cbd1db;
|
||
}
|
||
.hint-text {
|
||
margin-top: 6px;
|
||
font-size: 12px;
|
||
color: #8a8f99;
|
||
line-height: 1.4;
|
||
}
|
||
.form-summary {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
gap: 12px;
|
||
padding: 12px 12px;
|
||
margin-bottom: 12px;
|
||
border: 1px solid #eef0f4;
|
||
border-radius: 10px;
|
||
background: transparent;
|
||
}
|
||
.summary-title { font-size: 15px; font-weight: 700; color: #2b2f36; }
|
||
.summary-sub { margin-top: 4px; font-size: 12px; color: #8a8f99; }
|
||
.summary-right { display: flex; gap: 16px; }
|
||
.summary-item .k { font-size: 12px; color: #8a8f99; }
|
||
.summary-item .v { margin-top: 2px; font-weight: 600; color: #2b2f36; }
|
||
.form-actions {
|
||
display: flex;
|
||
justify-content: flex-end;
|
||
gap: 12px;
|
||
margin-top: 24px;
|
||
}
|
||
@media (max-width: 1200px) {
|
||
.summary-right { display: none; }
|
||
}
|
||
</style>
|