You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

506 lines
13 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<template>
<div class="card">
<div style="padding: 15px">
<el-radio-group v-model="select.year">
<el-radio v-for="item in years" :label="item" border>{{ item }}</el-radio>
</el-radio-group>
</div>
<div class="info">
<p class="info__title">
{{ title }}
</p>
<div class="info__status">
正常填报 <div class="cir1"></div> {{ static.count_normal }},迟报 <div class="cir2"></div> {{ static.count_delayed }},逾期未报 <div class="cir3"></div> {{ static.count_missed }}
</div>
</div>
<xy-table
ref="xyTable"
height=""
:isHandlerKey="false"
:is-page="false"
:list="categories"
res-prop=""
:indent="20"
:row-key="(row) => row._index"
:table-item="table"
:auths="[]"
>
</xy-table>
<el-drawer
title="填报清单"
:visible.sync="isShowDrawer"
position="rtl"
size="750px"
:wrapper-closable="false"
>
<div style="padding: 20px 40px">
<el-form
class="form"
ref="elForm"
:model="form"
:rules="rules"
label-width="80px"
size="small"
>
<el-form-item label="标题" prop="title">
<el-input v-model="form.title" placeholder="请填写标题"></el-input>
</el-form-item>
<el-form-item label="内容" required prop="content">
<el-input
type="textarea"
:autosize="{ minRows: 30 }"
v-model="form.content"
></el-input>
</el-form-item>
<el-form-item label="附件" prop="files">
<el-upload
class="upload-demo"
:action="action"
multiple
:limit="10"
:headers="{
'Authorization': 'Bearer ' + getToken(true)
}"
:before-upload="beforeUpload"
:on-success="uploadSuccess"
:file-list="fileList"
>
<el-button size="small" type="primary">点击上传</el-button>
</el-upload>
</el-form-item>
<el-form-item label="所属周期" prop="_week">
<el-input
placeholder="请选择所属周期"
readonly
v-model="form._week"
></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="onSubmit">立即{{ type === 'add' ? '创建' : '修改' }}</el-button>
<el-button @click="isShowDrawer = false">取消</el-button>
</el-form-item>
</el-form>
</div>
</el-drawer>
<detail ref="show" @edit="editShow"></detail>
</div>
</template>
<script>
import detail from "@/views/h5/form/show.vue";
import { category, recordStore, getYears, show, save } from "@/api/h5/form";
import { getToken } from "@/utils/auth";
export default {
components: {
detail
},
inject: ['myInfo', 'statics'],
data() {
return {
isShowDrawer: false,
formInfo: [],
customForm: {
customFormId: 11,
tableName: "asd",
},
fileList: [],
action: `${process.env.VUE_APP_BASE_API}/api/person/upload-file`,
select: {
year: this.$moment().format("YYYY"),
},
years: [],
categories: [],
table: [
{
type: "",
label: "",
prop: "index",
customFn: row => {
return row._type === 'type' ? row._text : row._index;
}
},
{
prop: "title",
label: "清单类型名称",
minWidth: 300,
renderHeader: col => {
return (
<div>{ this.title ? this.title.substring(0, this.title.length - 2) + '清单' : '清单类型名称' }</div>
)
},
align: "left",
customFn: (row) => {
return row._type === "type" ? (
<span>
<i
style="padding: 0 8px;color: rgb(239, 216, 117);"
class="el-icon-folder-opened"
></i>
<span>{row.title}</span>
</span>
) : (
<span>
<i style="padding: 0 8px;" class="el-icon-document"></i>
<span>{row.title}</span>
</span>
);
},
},
{
fixed: "right",
prop: "records_count",
label: "填报要求",
width: 240,
customFn: row => {
return(<div>
{
row.rules.map(item => (<div>{item.start_at} ~ {item.end_at}不少于{item.quantity}条</div>))
}
</div>)
}
},
{
fixed: "right",
prop: "records_count",
label: "填报情况",
showOverflowTooltip: false,
width: 150,
customFn: (row) => {
return row._is_end ? (
<div>
<Button type="primary" size="small" ghost on={{
['click']:_ => {
this.pickRule = row.rules
this.$refs['show'].setId(row.id)
this.$refs['show'].show()
}
}}>
查看
<Icon type="ios-search"></Icon>
</Button>
<el-dropdown size="small" disabled={!(row.rules instanceof Array && row.rules.length > 0)} style="margin-left: 10px" on={{
['command']: e => {
this.type = "add"
this.isShowDrawer = true;
this.form.category_rule_id = e;
this.form.category_id = row.id;
let rule = row.rules.find(item => (item.id === e))
this.form._week = `${rule.start_at} ~ ${rule.end_at}`
}
}}>
<Button type="primary" size="small">
填报
<Icon type="ios-arrow-down"></Icon>
</Button>
<el-dropdown-menu slot="dropdown">
{
row.rules.map(item => (<el-dropdown-item command={item.id}>{item.start_at} ~ {item.end_at}</el-dropdown-item>))
}
</el-dropdown-menu>
</el-dropdown>
</div>
) : '';
},
},
{
fixed: "right",
label: "系统预警",
width: 116,
customFn: row => {
let color = ['#377e22', '#f2a93c', '#ea3423']
let nums = [
row.rules.reduce((pre, cur) => (pre + (cur.record_count?.count_normal ?? 0)),0),
row.rules.reduce((pre, cur) => (pre + (cur.record_count?.count_delayed ?? 0)),0),
row.rules.reduce((pre, cur) => (pre + (cur.record_count?.count_missed ?? 0)),0)
]
return row._is_end ? (
<div style="display: flex;">
{
Array.from({ length: 3 },_ => undefined).map((i, index) => (
<div style="display: flex;align-items: center;">
<div style={{
'color': '#fff',
'background': color[index],
'padding': '10px',
'border-radius': '100%'
}}></div>
<span style="padding: 4px;">{ nums[index] }</span>
</div>
))
}
</div>
) : ''
}
},
],
type: "add",
pickRule: [],
form: {
category_rule_id: "",
category_id: "",
title: "",
content: "",
files: "",
myindex: "",
_week: ""
},
rules: {
content: [{ required: true, message: "请填写内容" }]
},
};
},
methods: {
getToken,
beforeUpload(file) {
if (file.size / 1000 > 20 * 1024) {
this.$message({
type: "warning",
message: "上传大小超过20Mb",
});
return false;
}
},
uploadSuccess (response, file, fileList) {
this.fileList = fileList
},
async getDetail (id) {
const res = await show({
id
})
this.$integrateData(this.form, res)
this.form.id = id
},
async editShow (id) {
this.type = 'edit'
await this.getDetail(id)
let rule = this.pickRule.find(i => i.id === this.form.category_rule_id)
this.form._week = `${rule.start_at} ~ ${rule.end_at}`
this.isShowDrawer = true
},
toChineseNum(number) {
const chineseNum = [
"零",
"一",
"二",
"三",
"四",
"五",
"六",
"七",
"八",
"九",
];
const chineseUnit = ["", "十", "百", "千", "万", "亿"];
let numStr = number.toString();
let len = numStr.length;
let str = "";
for (let i = 0; i < len; i++) {
str += chineseNum[parseInt(numStr[i])] + chineseUnit[len - 1 - i];
}
str = str.replace(/零[十百千]/g, "零");
str = str.replace(/零+/g, "零");
str = str.replace(/^零+/, "");
str = str.replace(/零+$/, "");
if (str[str.length - 1] === "零") {
str = str.slice(0, -1);
}
return str;
},
formatList(data = [], pid) {
data.forEach((item, index) => {
if (item.hasOwnProperty('categories_tree')) {
item._id = item.id
delete item.id;
item._disabled = true
item._type = 'type'
item.children = item.categories_tree
item._text = this.toChineseNum(index + 1)
} else {
item._type = 'doc'
item._index = pid ? `${pid}-${index+1}` : (index + 1)
// item._index = pid ? (index+1) : (index + 1)
}
if (item.children instanceof Array && item.children.length > 0) {
this.formatList(item.children, item._index ? item._index : false)
} else {
item._is_end = 1
}
})
},
async getCategories() {
const res = await category(this.select, false);
this.formatList(res);
this.categories = res;
},
async getYears () {
const res = await getYears();
this.select.year = res.selected_year;
this.years = res.years;
},
onSubmit() {
this.$refs["elForm"].validate((res) => {
if (res) {
this.form.files = this.fileList.map((i) => i.response.id).toString();
if (this.type === 'add') {
recordStore(this.form).then((res) => {
this.$message({
type: "success",
message: "填报成功",
});
this.isShowDrawer = false;
this.getCategories()
});
} else {
save(this.form).then((res) => {
this.$message({
type: "success",
message: "修改成功",
});
this.isShowDrawer = false;
this.getCategories()
this.$refs['show'].getData()
});
}
}
});
},
},
computed: {
title () {
return `${this.me?.department?.name ?? ''}-${this.me?.name ?? ''}-${this.me?.category_type?.title ?? ''}-${this.select.year}年填报总览`
},
me () {
return this.myInfo()
},
static () {
return this.statics()
}
},
watch: {
type (newVal) {
if (newVal === 'add') {
delete this.form.id
}
},
isShowDrawer (newVal) {
if (newVal) {
} else {
this.fileList = [];
this.form = {
category_rule_id: "",
category_id: "",
title: "",
content: "",
files: "",
myindex: "",
_week: ""
}
this.$refs['elForm'].clearValidate()
}
}
},
created() {
this.getYears();
this.getCategories();
},
};
</script>
<style lang="scss">
.el-cascader-node__label {
max-width: 300px;
}
</style>
<style scoped lang="scss">
.card {
height: 100%;
background-color: #fff;
margin: 40px;
}
.info {
border-top: 1px solid #EBEEF5;
background: #faf0e9;
padding: 10px 15px;
&__title {
font-size: 22px;
font-weight: 600;
padding-bottom: 8px;
}
&__status {
$color: #377e22,#f2a93c,#ea3423;
display: flex;
align-items: center;
font-size: 12px;
@mixin cir {
padding: 8px;
border-radius: 100%;
margin: 0 6px;
}
@for $i from 1 through length($color) {
.cir#{$i} {
@include cir;
background: nth($color, $i);
}
}
}
}
::v-deep .table-tree {
height: 100%;
background: #f0f2f8;
}
::v-deep .el-radio__input.is-checked + .el-radio__label {
color: #c4312b;
}
::v-deep .el-radio__input.is-checked .el-radio__inner {
background-color: #c4312b;
border-color: #c4312b;
}
::v-deep .el-radio__inner {
width: 18px;
height: 18px;
}
::v-deep .el-radio__input.is-checked .el-radio__inner:after {
content: "";
width: 12px;
height: 6px;
margin-top: -1px;
border: 2px solid white;
border-top: transparent;
border-right: transparent;
text-align: center;
display: block;
position: absolute;
top: 50%;
left: 50%;
vertical-align: middle;
transform: translate(-50%, -50%) rotate(-45deg);
border-radius: 0px;
background: none;
}
::v-deep .el-tabs__nav-wrap::after {
background-color: #ebeef5;
}
</style>