master
xy 11 months ago
parent c751db6d73
commit 9b7f936b27

@ -2,10 +2,10 @@
ENV = 'development'
# base api
VUE_APP_BASE_API='https://cz-hjjc.115.langye.net'
VUE_APP_UPLOAD_API='https://cz-hjjc.115.langye.net/api/upload-file'
VUE_APP_BASE_API='https://cz-hjjc-test.115.langye.net'
VUE_APP_UPLOAD_API='https://cz-hjjc-test.115.langye.net/api/upload-file'
VUE_APP_PREVIEW=//view.langye.net/preview/onlinePreview
VUE_APP_OUT_OLD=https://cz-hjjc.115.langye.net/oa
VUE_APP_OUT_URL=https://cz-hjjc.115.langye.net/oa
VUE_APP_OUT_OLD=https://cz-hjjc-test.115.langye.net/oa
VUE_APP_OUT_URL=https://cz-hjjc-test.115.langye.net/oa
VUE_APP_MODULE_NAME=ht

@ -15,7 +15,7 @@ export function listdept() {
})
}
export function listdeptNoAuth(params = {show_tree:1}){
export function listdeptNoAuth(params = {page: 1,page_size: 999,sort_name:'sortnumber',sort_type:'asc'}){
return request({
url:'/api/ht/other/admin-department-list',
method:'get',

@ -215,7 +215,7 @@ export default {
getDepartment() {
listdeptNoAuth().then((res) => {
this.departments = res;
this.departments = res.data;
});
},
async getPlanTypes() {

@ -397,7 +397,7 @@ export default {
},
getDepartment() {
listdeptNoAuth().then((res) => {
this.departments = res;
this.departments = res.data;
});
},
async getPlanTypes() {

@ -535,7 +535,7 @@ export default {
//
getDepartment() {
listdeptNoAuth().then((res) => {
this.departments = res;
this.departments = res.data;
});
},

@ -48,6 +48,16 @@
</span>
</div>
<div>
<span>数据类型</span>
<span>
<Select v-model="select.auth_type" style="width:70px">
<Option :value="1">自己</Option>
<Option :value="2">部门</Option>
</Select>
</span>
</div>
<div>
<Button
type="primary"
@ -82,9 +92,8 @@
>
<template #default="{ row }" v-if="!/Finance/g.test($route.path)">
<Button v-if="row.flow_list.find(i => i.tag === 'chuchai')" style="margin: 2px;" size="small" type="primary" @click="printFlow(row)"></Button>
<template v-if="row.away_status === 1 && row.expense_status === 1">
<template v-if="row.flow_list.length === 0">
<Poptip
v-if="isAuthEdit(row)"
:transfer="true"
confirm
placement="bottom"
@ -244,6 +253,7 @@ export default {
keyword: '',
start_year: "",
end_year: "",
auth_type: 1,
page: 1,
page_size: 10
},

@ -110,18 +110,6 @@
:align="item.align"
:formatter="item.formatter"
>
<!-- <template slot-scope="scope">-->
<!-- <span v-if="item.formatter">-->
<!-- {{ item.formatter(scope.row, scope.row, scope.row[item.prop]) }}-->
<!-- </span>-->
<!-- <span v-else>-->
<!-- {{-->
<!-- item.prop.indexOf(".") > -1-->
<!-- ? scope.row[item.prop.split(".")[0]][item.prop.split(".")[1]]-->
<!-- : scope.row[item.prop]-->
<!-- }}-->
<!-- </span>-->
<!-- </template>-->
</el-table-column>
<el-table-column
fixed="right"
@ -320,18 +308,6 @@
style="width: 300px"
@change="(e) => (form.type = e[e.length - 1] || '')"
/>
<!-- <el-select-->
<!-- v-model="form.type"-->
<!-- clearable-->
<!-- placeholder="请选择预算类型"-->
<!-- style="width: 300px"-->
<!-- >-->
<!-- <el-option-->
<!-- v-for="item in types"-->
<!-- :label="item.value"-->
<!-- :value="item.id"-->
<!-- ></el-option>-->
<!-- </el-select>-->
</div>
</div>
</template>
@ -379,6 +355,30 @@
</div>
</div>
</template>
<template #dimension>
<div class="xy-table-item">
<div class="xy-table-item-label">
资金隶属维度
</div>
<div class="xy-table-item-content">
<el-select
placeholder="隶属维度选择"
clearable
size="small"
v-model="form.dimension"
style="width: 300px"
>
<el-option
v-for="item in dimensions"
:label="item.remark"
:value="item.value"
:key="item.id"
>
</el-option>
</el-select>
</div>
</div>
</template>
<template v-slot:department>
<div class="xy-table-item">
<div class="xy-table-item-label">
@ -487,6 +487,26 @@
</div>
</div>
</template>
<template #middle_special>
<div class="xy-table-item">
<div class="xy-table-item-label">
是否年中专项资金
</div>
<div class="xy-table-item-content">
<el-switch v-model="form.middle_special" :active-value="1" :inactive-value="0" active-text="是" inactive-text="否"></el-switch>
</div>
</div>
</template>
<template #is_chart>
<div class="xy-table-item">
<div class="xy-table-item-label">
是否参与执行率统计
</div>
<div class="xy-table-item-content">
<el-switch v-model="form.is_chart" :active-value="1" :inactive-value="0" active-text="是" inactive-text="否"></el-switch>
</div>
</div>
</template>
<template v-slot:remark>
<div class="xy-table-item">
<div class="xy-table-item-label">备注</div>
@ -550,18 +570,6 @@
style="width: 300px"
@change="(e) => (editorForm.type = e[e.length - 1] || '')"
/>
<!-- <el-select-->
<!-- v-model="editorForm.type"-->
<!-- clearable-->
<!-- placeholder="请选择预算类型"-->
<!-- style="width: 300px"-->
<!-- >-->
<!-- <el-option-->
<!-- v-for="item in types"-->
<!-- :label="item.value"-->
<!-- :value="item.id"-->
<!-- ></el-option>-->
<!-- </el-select>-->
</div>
</div>
</template>
@ -609,6 +617,30 @@
</div>
</div>
</template>
<template #dimension>
<div class="xy-table-item">
<div class="xy-table-item-label">
资金隶属维度
</div>
<div class="xy-table-item-content">
<el-select
placeholder="隶属维度选择"
clearable
size="small"
v-model="editorForm.dimension"
style="width: 300px"
>
<el-option
v-for="item in dimensions"
:label="item.remark"
:value="item.value"
:key="item.id"
>
</el-option>
</el-select>
</div>
</div>
</template>
<template v-slot:department>
<div class="xy-table-item">
<div class="xy-table-item-label">
@ -632,15 +664,6 @@
>
</el-option>
</el-select>
<!-- <el-cascader-->
<!-- :options="departments"-->
<!-- :props="{ checkStrictly: true, label: 'name', value: 'id' }"-->
<!-- :value="editorForm.department"-->
<!-- clearable-->
<!-- size="small"-->
<!-- style="width: 300px"-->
<!-- @change="(e) => (editorForm.department = e[e.length - 1] || '')"-->
<!-- />-->
</div>
</div>
</template>
@ -748,6 +771,26 @@
</div>
</div>
</template>
<template #middle_special>
<div class="xy-table-item">
<div class="xy-table-item-label">
是否年中专项资金
</div>
<div class="xy-table-item-content">
<el-switch v-model="editorForm.middle_special" :active-value="1" :inactive-value="0" active-text="是" inactive-text="否"></el-switch>
</div>
</div>
</template>
<template #is_chart>
<div class="xy-table-item">
<div class="xy-table-item-label">
是否参与执行率统计
</div>
<div class="xy-table-item-content">
<el-switch v-model="editorForm.is_chart" :active-value="1" :inactive-value="0" active-text="是" inactive-text="否"></el-switch>
</div>
</div>
</template>
<template v-slot:remark>
<div class="xy-table-item">
<div class="xy-table-item-label">备注</div>
@ -845,10 +888,13 @@ export default {
name: "",
type: "",
flow_mod_id: "",
dimension: '',
year: "",
department: "",
money: "",
content: "",
middle_special: 0,
is_chart: 1,
remark: "",
plan_department_link_id: [],
plan_department_links: [],
@ -979,6 +1025,7 @@ export default {
},
departments: [], //
users: [],
dimensions: [],
//
isShowEditor: false,
@ -1122,8 +1169,8 @@ export default {
},
//
getDepartment() {
listCommondepartment({show_tree:1}).then((res) => {
this.departments = res;
listCommondepartment({ page: 1,page_size: 999,sort_name: 'sortnumber',sort_type: 'asc' }).then((res) => {
this.departments = res.data;
});
},
async getUsers () {
@ -1133,6 +1180,17 @@ export default {
})
this.users = res.data;
},
//
async getDimensions() {
try {
const res = await getparameter({
number: "dimensions"
})
this.dimensions = res.detail
} catch (err) {
console.error(err)
}
},
//
async getFlowIds () {
let copy = deepCopy(this.flowIds)
@ -1209,7 +1267,10 @@ export default {
plan_admin_links: this.form.plan_admin_links,
remark: this.form.remark,
pid: this.form.pid,
flow_mod_id: this.form.flow_mod_id
flow_mod_id: this.form.flow_mod_id,
dimension: this.form.dimension,
middle_special: this.form.middle_special,
is_chart: this.form.is_chart
}).then((res) => {
Message({
message: "操作成功",
@ -1264,7 +1325,10 @@ export default {
plan_department_links: plan_department_links,
plan_admin_links: this.editorForm.plan_admin_links,
pid: this.editorForm.pid,
flow_mod_id: this.editorForm.flow_mod_id
flow_mod_id: this.editorForm.flow_mod_id,
dimension: this.editorForm.dimension,
middle_special: this.editorForm.middle_special,
is_chart: this.editorForm.is_chart
}).then((res) => {
this.isShowEditor = false;
Message({
@ -1291,6 +1355,7 @@ export default {
name: res.name,
type: res.type,
flow_mod_id: res.flow_mod_id,
dimension: res.dimension,
department: res.plan_department_id,
money: moneyFormatter(res.money),
update_money: moneyFormatter(res.update_money),
@ -1300,6 +1365,8 @@ export default {
plan_department_links: res.plan_department_links,
plan_admin_links: res.plan_admin_links.map(i=> ({admin_id: i.admin_id})),
pid: res.pid,
is_chart: res.is_chart,
middle_special: res.middle_special
};
let ids = [];
res.plan_department_links.map((item) => {
@ -1314,6 +1381,10 @@ export default {
},
},
created() {
this.getUsers();
this.getTypes();
this.getDepartment();
this.getDimensions();
this.getFlowIds();
this.table = this.tableItem;
this.initLoad();
@ -1321,10 +1392,7 @@ export default {
this.select.year = this.$moment().format("YYYY");
},
mounted() {
this.getTypes();
this.getDepartment();
this.getBudgets();
this.getUsers();
},
};
</script>

@ -274,7 +274,7 @@
//
getDepartment() {
listdeptNoAuth().then(res => {
this.departments = res
this.departments = res.data
})
},
//

@ -142,7 +142,7 @@ export default {
},
methods: {
async getDept() {
const res = await listdeptNoAuth({ page: 1, page_size: 999 });
const res = await listdeptNoAuth({ page: 1, page_size: 999,sort_name:'sortnumber',sort_type: 'asc' });
this.depts = res.data;
},
async getList() {

@ -28,7 +28,7 @@
<span style="flex: 1; text-align: right">无需采购流程如水电邮寄费等</span>
</el-form-item>
<el-form-item prop="flow_mod_id" label="事前流程">
<el-form-item prop="flow_mod_id" label="事前流程" v-if="!form.is_simple">
<template v-if="!form.is_common_purchase">
<el-select v-model="form.flow_mod_id" style="width: 100%">
<el-option v-for="item in flowIdsFormat" :key="item.id" :value="item.id" :label="item.name"></el-option>
@ -69,7 +69,6 @@
multiple
size="small"
clearable
disabled
placeholder="请选择资金渠道"
:value="
form.money_way_id
@ -770,7 +769,7 @@ export default {
type: [
{
validator: (rule, value, callback) => {
if (!this.form.is_simple || !this.isNeedMore) {
if (!this.form.is_simple || !this.isNeedMore || !this.form.is_common_purchase) {
if (!this.hasValue(value)) {
callback(new Error("必填"));
} else {
@ -786,7 +785,7 @@ export default {
purchase_type_id: [
{
validator: (rule, value, callback) => {
if (!this.form.is_simple || !this.isNeedMore) {
if (!this.form.is_simple || !this.isNeedMore || !this.form.is_common_purchase) {
if (!this.hasValue(value)) {
callback(new Error("必填"));
} else {
@ -802,7 +801,7 @@ export default {
purchase_way_id: [
{
validator: (rule, value, callback) => {
if (!this.form.is_simple || !this.isNeedMore) {
if (!this.form.is_simple || !this.isNeedMore || !this.form.is_common_purchase) {
if (!this.hasValue(value)) {
callback(new Error("必填"));
} else {
@ -838,7 +837,7 @@ export default {
plan_money: [
{
validator: (rule, value, callback) => {
if (!this.form.is_simple) {
if (!this.form.is_simple || !this.form.is_common_purchase) {
if (!this.hasValue(value)) {
callback(new Error("必填"));
} else {
@ -858,7 +857,7 @@ export default {
money_way_id: [
{
validator: (rule, value, callback) => {
if (!this.hasValue(value)) {
if (!this.hasValue(value) || !this.form.is_common_purchase) {
callback(new Error("必填"));
} else {
callback();

@ -209,7 +209,7 @@
/>
</el-form-item>
<el-form-item prop="flow_mod_id" label="事前流程">
<el-form-item prop="flow_mod_id" label="事前流程" v-if="!form.is_simple">
<el-select v-model="form.flow_mod_id" style="width: 100%">
<el-option v-for="item in flowIdsFormat" :key="item.id" :value="item.id" :label="item.name"></el-option>
</el-select>
@ -1433,7 +1433,7 @@ export default {
getDepartment() {
listdeptNoAuth().then((res) => {
this.departments = res;
this.departments = res.data;
});
},
async getPlanTypes() {
@ -1538,24 +1538,6 @@ export default {
keyword: this.form.name,
},
})
getContract({
page: 1,
page_size: 1,
sort_name: "created_at"
},true).then(res => {
const openData = res.list.data[0]
if (openData) {
if (
openData.is_simple !== 1 &&
openData.purchase_status === 1 &&
((openData.req_status === 3 && openData.is_plan === 0) ||
openData.is_plan === 1) &&
!openData.is_substitute
) {
this.buyProcess(openData)
}
}
})
}).catch(_ => this.btnLoading = false)
}
if (this.type === 'edit') {

@ -327,15 +327,7 @@
<Button ghost size="small" type="primary">更多</Button>
<div slot="content">
<template
v-if="
!(
scope.row.req_status != 1 ||
scope.row.join_status != 1 ||
scope.row.invite_status != 1 ||
scope.row.purchase_status != 1 ||
scope.row.status === 2
)
"
v-if="scope.row.flow_list.length === 0"
>
<Poptip
:transfer="true"
@ -2088,7 +2080,7 @@ export default {
},
//
async getDepartment() {
this.departments = await listdeptNoAuth();
this.departments = (await listdeptNoAuth())?.data;
},
//
async getPurchaseType() {

@ -376,15 +376,7 @@
<Button ghost size="small" type="primary">更多</Button>
<div slot="content">
<template
v-if="
!(
scope.row.req_status != 1 ||
scope.row.join_status != 1 ||
scope.row.invite_status != 1 ||
scope.row.purchase_status != 1 ||
scope.row.status === 2
)
"
v-if="scope.row.flow_list.length === 0"
>
<Poptip
:transfer="true"
@ -1795,7 +1787,7 @@ export default {
},
//
async getDepartment() {
this.departments = await listdeptNoAuth();
this.departments = (await listdeptNoAuth())?.data;
},
//
async getGroupType() {
@ -2108,7 +2100,7 @@ export default {
if (item.is_contract) {
//
flowStatus["shenpi"].setStatus(shenpi?.flow_status ?? 2)
if ((!shenpi?.flow_status || shenpi?.flow_status === 2) && ((item.is_tender_audit && item.invite_status === 1) || (!item.is_tender_audit && (caigou?.flow_status === 1 || common_purchase?.flow_status === 1)))) {
if ((!shenpi?.flow_status || shenpi?.flow_status === 2) && ((item.is_tender_audit && item.invite_status === 1) && (caigou?.flow_status === 1 || common_purchase?.flow_status === 1))) {
//
flowStatus["shenpi"].setExecutable(true)
}
@ -2120,7 +2112,7 @@ export default {
}
}
} else {
if (item.flow_mod_id) {
if (item.flow_mod_id && item.is_simple !== 1) {
//
flowStatus["other"].setStatus(other?.flow_status ?? 2)
if (!other || other.flow_status === 2) {
@ -2133,9 +2125,8 @@ export default {
//
if (
(item.is_purchase === 0 && other?.flow_status === 1) ||
item.status === 2 ||
(!item.is_contract && item.is_simple) ||
(item.is_tender_audit && !item.is_contract && item.invite_status === 1) ||
(item.is_tender_audit && !item.is_contract && item.invite_status === 1 && (caigou?.flow_status === 1 || common_purchase?.flow_status === 1)) ||
(!item.is_tender_audit && !item.is_contract && (caigou?.flow_status === 1 || common_purchase?.flow_status === 1))
) {
//

@ -1222,7 +1222,7 @@ export default {
},
//
async getDepartment() {
this.departments = await listdeptNoAuth();
this.departments = (await listdeptNoAuth()?.data);
},
//
async getPurchaseType() {

@ -72,7 +72,7 @@
header-align="center"
>
<template slot-scope="scope">
<template v-if="scope.row.status === 0 && type == 1 && scope.row.flow_status === 1">
<template v-if="scope.row.status === 0 && type == 1 && scope.row.flow_list.length === 0">
<Poptip
placement="bottom"
confirm

File diff suppressed because it is too large Load Diff

@ -726,7 +726,7 @@ import {listdeptNoAuth} from "@/api/system/department";
//
getDepartment() {
listdeptNoAuth().then((res) => {
this.departments = res;
this.departments = res.data;
});
},
},

@ -210,8 +210,9 @@
<div style="display: flex; justify-content: flex-end">
<Page
:total="planTotal"
:page-size="planSearch.page_size"
show-elevator
@on-change="e => {planSearch.p = e; getOutBudgets()}"
@on-change="e => {planSearch.page = e; getOutBudgets()}"
/>
</div>
</template>
@ -233,6 +234,7 @@ import {
} from "@/api/contract/contract";
import { httpCurl } from "@/api/out"
import { getBudget } from '@/api/budget/budget'
import axios from "axios";
export default {
props: {
report_types: {
@ -264,9 +266,11 @@ export default {
planTotal: 0,
isShowPlan: false,
planSearch: {
mod_name: '出差审批',
list_rows: 10,
p: 1
page: 1,
page_size: 20,
is_simple: 1,
is_auth: 1,
custom_model_id: 72
},
budgets: [],
budgetTotal: 0,
@ -303,10 +307,10 @@ export default {
},
{
label: '创建时间',
prop: 'create_time',
prop: 'created_at',
width: 180,
formatter: (cell,data,value)=> {
return this.$moment(new Date(Number(value)*1000)).format('YYYY-MM-DD')
return value ? this.$moment(new Date(value)).format('YYYY-MM-DD') : ''
}
}
],
@ -627,15 +631,25 @@ export default {
},
//
async getOutBudgets() {
let res = await httpCurl(this.planSearch, false, '/Api/flowList');
this.plans = res.list
this.planTotal = Number(res.total)
let res = await axios.get(`${process.env.VUE_APP_BASE_API}/api/oa/flow/list/all`,{
headers: {
Authorization: `Bearer ${getToken()}`
},
params: this.planSearch
})
if (res.status === 200) {
if (res.data.code) {
return
}
this.plans = res.data?.data?.data?.data
this.planTotal = Number(res.data?.data?.data?.total)
this.plans.forEach(i => {
if (this.form.oa.find(oa => oa.id === i.id)) {
this.$refs['planTable'].toggleRowSelection(i)
}
})
}
},
},

@ -444,7 +444,7 @@ export default {
},
async getDepartment() {
this.departments = await listdeptNoAuth();
this.departments = (await listdeptNoAuth())?.data;
},
async getOtherType() {

@ -362,7 +362,7 @@ export default {
},
async getDepartment() {
this.departments = await listdeptNoAuth();
this.departments = (await listdeptNoAuth())?.data;
},
async getList() {
const res = await index(this.select);

@ -253,7 +253,7 @@
//
getDepartment() {
listdeptNoAuth().then(res => {
this.departments = res
this.departments = res.data
})
},

@ -1,242 +0,0 @@
<template>
<div style="padding: 0 10px 20px 10px">
<el-row :gutter="4">
<el-col :span="4">
<Card style="height: 100%;" :style="{'opacity':isDrag ? '0.4' : '1' }">
<template v-slot:title>
<p>组件</p>
</template>
<div
class="cpn-name__item"
:class="{ 'cpn-name__item--disable': statusFormat(item.i) }"
v-for="item in layout"
:draggable="!statusFormat(item.i)"
@dragstart="isDrag = true"
@dragend="dragEnd(item, $event)"
>
<i class="el-icon-folder-remove"></i>
<span>{{ item.name }}</span>
<Button
v-show="statusFormat(item.i)"
type="error"
size="small"
ghost
@click="removeLayout(item.i)"
>移除</Button
>
</div>
</Card>
</el-col>
<el-col :span="20">
<Card :class="{'drag-body':isDrag}">
<template v-slot:title>
<div style="display: flex;justify-content: space-between;align-items: center;">
<p>布局</p>
<Button type="primary" style="float: right;margin-right: 10px;" @click="sync"></Button>
<Button type="primary" style="float: right;" @click="save"></Button>
</div>
</template>
<grid-layout
id="grid-card"
class="gird-card"
:layout.sync="layoutList"
:col-num="12"
:row-height="40"
:is-draggable="true"
:is-resizable="true"
:is-mirrored="false"
:vertical-compact="true"
:margin="[10, 10]"
:autoSize="true"
:use-css-transforms="true"
>
<grid-item
v-for="item in layoutList"
:x="item.x"
:y="item.y"
:w="item.w"
:h="item.h"
:i="item.i"
:key="item.i"
style="touch-action: none"
>
<component
style="position: absolute; inset: 0 0 0 0;"
:is="item.component"
></component>
</grid-item>
</grid-layout>
</Card>
</el-col>
</el-row>
</div>
</template>
<script>
import { save } from "@/api/system/expand"
import VueGridLayout from "vue-grid-layout";
import path from "path";
const files = require.context(
"@/views/system/workerComponents",
false,
/.vue$/
);
let cpns = files.keys().map((key) => {
return files(key).default || files(key);
});
let layout = cpns.map((item) => {
return {
...item.layout,
component: item,
};
});
export default {
components: {
"GridLayout": VueGridLayout.GridLayout,
"GridItem": VueGridLayout.GridItem
},
data() {
return {
layout,
layoutList: [],
isDrag: false,
grid: {
x: 0,
y: 0,
},
};
},
methods: {
dragEnd(item, e) {
this.isDrag = false
if (e.clientX >= this.grid.x && e.clientY >= this.grid.y) {
this.layoutList.push(item);
}
},
removeLayout(i) {
let temp = -1;
this.layoutList.forEach((item, index) => {
if (i === item.i) {
temp = index;
}
});
this.layoutList.splice(temp, 1);
},
async sync() {
await this.$store.dispatch("app/setLayout")
this.$store.dispatch('app/getLayout').then(res => {
this.layoutList = res.map(item => {
layout.forEach(lay => {
lay.i === item.i ? item.component = lay.component : ''
})
return item
})
})
},
save(){
let layout = this.layoutList.map(item => {
return {
x:item.x,
y:item.y,
w:item.w,
h:item.h,
i:item.i
}
})
this.$store.dispatch('app/saveLayout',layout)
}
},
computed: {
statusFormat() {
return function (i) {
let iArr = this.layoutList.map((item) => item.i);
return iArr.indexOf(i) !== -1;
};
},
},
mounted() {
this.grid = document.getElementById("grid-card").getBoundingClientRect();
},
created() {
this.$store.dispatch('app/getLayout').then(res => {
this.layoutList = res.map(item => {
layout.forEach(lay => {
lay.i === item.i ? item.component = lay.component : ''
})
return item
})
})
}
};
</script>
<style scoped lang="scss">
.gird-card {
min-height: 200px;
}
.cpn-name__item {
display: flex;
align-items: center;
justify-content: space-between;
color: rgb(100, 100, 100);
border-radius: 4px;
background-color: rgba(94, 181, 218, 0.3);
cursor: move;
padding: 6px 6px;
& > i {
padding-right: 6px;
}
& > span {
flex: 1;
}
& + div {
margin-top: 10px;
}
&--disable {
cursor: no-drop;
background-color: rgba(218, 94, 98, 0.3);
}
}
.drag-body{
transition: all .4s;
background: rgba(32, 160, 255, 0.3);
opacity: .7;
}
.fade-in {
animation: fade-in 800ms cubic-bezier(0.39, 0.575, 0.565, 1) both;
}
@keyframes fade-in {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
.fade-out {
animation: fade-out 600ms ease-out both;
}
@keyframes fade-out {
0% {
opacity: 1;
}
100% {
opacity: 0;
}
}
::v-deep .el-card__header {
padding: 10px 20px;
}
</style>

@ -1,146 +0,0 @@
<template>
<el-card class="box-card" shadow="hover">
<div slot="header" class="clearfix">
<SvgIcon style="color: #3171f4;width: 22px;height: 22px;" icon-class="tushu"></SvgIcon>
<span style="padding-left: 15px"
>图书统计</span
>
<DatePicker
transfer
:value="select.date"
placeholder="选择所属年份"
placement="bottom"
style="width: 130px; margin-left: auto;"
type="month"
format
@on-change="changeMonth"
></DatePicker>
</div>
<div class="progress-card">
<MyProgress width="213px" height="213px" :chart-data="chartData"></MyProgress>
<!-- <div class="progress-card-item">-->
<!-- <div class="progress-card-item__num">{{totalData.book.total}}</div>-->
<!-- <div class="progress-card-item__label">总计</div>-->
<!-- </div>-->
<!-- <div class="progress-card-item">-->
<!-- <div class="progress-card-item__num">{{totalData.book.no_return}}</div>-->
<!-- <div class="progress-card-item__label">未归还</div>-->
<!-- </div>-->
<!-- <div class="progress-card-item">-->
<!-- <div class="progress-card-item__num">{{totalData.book.rate+'%'}}</div>-->
<!-- <div class="progress-card-item__label">{{(totalData.book.rate>0?'上升':(totalData.book.rate===0?'-':'下降'))}}</div>-->
<!-- </div>-->
</div>
</el-card>
</template>
<script>
import MyProgress from "@/components/Progress"
import { httpCurl } from "@/api/out";
import SvgIcon from "@/components/SvgIcon/index.vue";
export default {
components: {
SvgIcon,
MyProgress
},
name: "card5",
layout: {
x: 0,
y: 0,
w: 4,
h: 5,
i: "6",
name: "图书统计",
},
data() {
return {
select: {
token: '',
date: this.$moment(new Date()).format('YYYY-MM'),
},
statistic: {
progress: {},
},
totalData: {
book: {
no_return: 0,
total: 0,
rate: 0
}
}
};
},
methods: {
changeMonth (e) {
this.date = e;
this.getStatic();
},
async getToken () {
if(/^\/system/.test(this.$route.path)) return
const token = await httpCurl({
auth_token: this.$store.getters.oa_token
},true,"","POST",`${process.env['VUE_APP_OUT_Book']}/api/admin/auth/oss-login`)
this.token = token.access_token
},
async getStatic() {
if(/^\/system/.test(this.$route.path)) return
const res = await httpCurl(
{
token: this.token,
date: this.date
},
true,
"",
"post",
`${process.env['VUE_APP_OUT_Book']}/api/admin/other/chart-total`
);
this.totalData = res;
},
},
computed: {
chartData () {
return [
{
name:'已归还',
value: this.totalData.book.total??0-this.totalData.book.no_return??0
},
{
name:'未归还',
value: this.totalData.book.no_return??0
}
]
}
},
async created() {
await this.getToken();
await this.getStatic();
},
};
</script>
<style scoped lang="scss">
.clearfix {
display: flex;
align-items: center;
}
.progress-card {
display: flex;
justify-content: center;
align-items: center;
&-item {
text-align: center;
flex: 1;
&__label {
font-size: 14px;
}
&__num {
font-size: 20px;
font-weight: 600;
padding: 6px 0;
}
}
}
</style>

@ -1,131 +0,0 @@
<template>
<el-card class="box-card" shadow="hover">
<div slot="header" class="clearfix">
<SvgIcon style="color: #3171f4;width: 22px;height: 22px;" icon-class="book"></SvgIcon>
<span style="padding-left: 15px"
>图书借阅统计</span
>
<DatePicker
transfer
:value="select.date"
placeholder="选择所属年份"
placement="bottom"
style="width: 130px; margin-left: auto;"
type="month"
format
@on-change="changeMonth"
></DatePicker>
</div>
<div class="progress-card">
<MyProgress class="progress-card-item" width="213px" height="213px" title="借出量" :percent="totalData.borrow.rate"></MyProgress>
</div>
</el-card>
</template>
<script>
import MyProgress from "@/components/Progress/index.vue";
import SvgIcon from "@/components/SvgIcon/index.vue";
import { httpCurl } from "@/api/out";
export default {
components: {
SvgIcon,
MyProgress
},
name: "card6",
layout: {
x: 0,
y: 0,
w: 4,
h: 5,
i: "7",
name: "图书借阅统计",
},
data() {
return {
select: {
token: "",
date: this.$moment(new Date()).format("YYYY-MM"),
},
statistic: {
progress: {},
},
totalData: {
borrow: {
no_return: 0,
total: 0,
rate: 0,
},
},
};
},
methods: {
changeMonth(e) {
this.date = e;
this.getStatic();
},
async getToken() {
if (/^\/system/.test(this.$route.path)) return;
const token = await httpCurl(
{
auth_token: this.$store.getters.oa_token
},
true,
"",
"POST",
`${process.env["VUE_APP_OUT_Book"]}/api/admin/auth/oss-login`
);
this.token = token.access_token;
},
async getStatic() {
if (/^\/system/.test(this.$route.path)) return;
const res = await httpCurl(
{
token: this.token,
date: this.date,
},
true,
"",
"post",
`${process.env["VUE_APP_OUT_Book"]}/api/admin/other/chart-total`
);
console.log(res);
this.totalData = res;
},
},
computed: {},
async created() {
await this.getToken();
await this.getStatic();
},
};
</script>
<style scoped lang="scss">
.progress-card {
display: flex;
&-item {
display: flex;
justify-content: center;
align-items: center;
text-align: center;
flex: 1;
&__label {
font-size: 14px;
}
&__num {
font-size: 20px;
font-weight: 600;
padding: 6px 0;
}
}
}
.clearfix {
display: flex;
align-items: center;
}
</style>

@ -1,274 +0,0 @@
<template>
<el-card class="box-card" shadow="hover" id="department-card">
<div slot="header" class="clearfix">
<SvgIcon style="color: #3171f4;width: 22px;height: 22px;" icon-class="form"></SvgIcon>
<span style=" padding-left: 15px"
>科室执行情况</span
>
<i class="el-icon-more" style="margin-left: auto; font-size: 20px"></i>
</div>
<div style="position: relative;height: 100%;width: 100%;">
<div id="department-chart"></div>
</div>
</el-card>
</template>
<script>
import * as echarts from "echarts";
import { moneyFormatter } from "@/utils";
import ElementResize from 'element-resize-detector'
import SvgIcon from "@/components/SvgIcon/index.vue";
export default {
components: {
SvgIcon
},
name: "card3",
layout: {
x: 0,
y: 5,
w: 6,
h: 4,
i: "3",
name: "科室执行情况",
},
inject: {
getStatistic: {
default: () => {
return () => {
return {
statistic: {
departmentList: [
{
money_total_1: "1900000.00",
money_total_2: "0.00",
ids: "11",
plan_department_id: 2,
use_money_total: 0,
money_total: "0.00",
end_money: 0,
plan_department: {
id: 2,
pid: 0,
name: "办公室(党建作风办)",
manager_id: 7,
leader_id: 4,
sortnumber: 1,
created_at: "2021-06-22 07:01:41",
updated_at: "2023-03-22 14:56:51",
deleted_at: null,
},
},
],
},
};
}
},
},
},
data() {
return {
chart: "",
tableHeight: 200,
table: [
{
title: "科室",
width: 100,
key: "plan_department.name",
fixed: "left",
render:(h,{row}) => {
return h('span',{},row.plan_department?.name)
}
},
{
title: "执行情况",
minWidth: 160,
fixed: "right",
render: (h, { row }) => {
let m2 = row?.money_total_2 || 0;
let m1 = row?.money_total_1 || 0;
let m3 = row?.use_money_total || 0;
let per = 0;
if (m2 != 0) {
per = ((m3 / m2) * 100).toFixed(2);
} else if (m1 != 0) {
per = ((m3 / m1) * 100).toFixed(2);
}
return h("el-progress", {
props: {
percentage: Number(per),
},
});
},
},
{
title: "年初预算合计金额(元)",
width: 170,
align: "right",
key: "money_total_1",
render: (h, { row }) => {
return h("span", {}, moneyFormatter(row.money_total_1));
},
},
{
title: "调整后预算合计金额(元)",
width: 170,
align: "right",
key: "money_total_2",
render: (h, { row }) => {
return h("span", {}, moneyFormatter(row.money_total_2));
},
},
{
title: "已使用(元)",
width: 120,
align: "right",
key: "use_money_total",
render: (h, { row }) => {
return h("span", {}, moneyFormatter(row.use_money_total));
},
},
],
};
},
methods: {
setOptions() {
this.chart.setOption({
grid: {
left: "15%"
},
tooltip: {
show: true
},
legend: {
show: true
},
xAxis: {
data: this.departmentList.map((item) => item.plan_department.name),
},
yAxis: {
axisLabel: {
color: '#999'
}
},
series: [
{
barWidth: 30,
type: 'bar',
stack: "a",
name: "合计金额(元)",
itemStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{ offset: 1, color: '#83bff6' },
{ offset: 0.5, color: '#188df0' },
{ offset: 0, color: '#188df0' }
]),
},
emphasis: {
itemStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{ offset: 1, color: '#4f86f5' },
{ offset: 0.3, color: '#3f79f1' },
{ offset: 0, color: '#3171f4' }
])
}
},
data: this.departmentList.map(item => (parseFloat(item.money_total_2) ? parseFloat(item.money_total_2) : parseFloat(item.money_total_1) - parseFloat(item.use_money_total))),
},
{
barWidth: 30,
type: "bar",
stack: "a",
name: "已使用金额(元)",
label: {
show: true,
color: "#188df0",
position: "top",
formatter: (params) => {
console.log(params)
let m2 = this.departmentList[params.dataIndex]?.money_total_2 || 0;
let m1 = this.departmentList[params.dataIndex]?.money_total_1 || 0;
let m3 = this.departmentList[params.dataIndex]?.use_money_total || 0;
let per = 0;
if (m2 != 0) {
per = ((m3 / m2) * 100).toFixed(2);
} else if (m1 != 0) {
per = ((m3 / m1) * 100).toFixed(2);
}
return Number(per) + "%";
},
},
itemStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{ offset: 0, color: '#b4cef3' },
{ offset: 0.5, color: '#aecbf5' },
{ offset: 1, color: '#9fc4f9' }
]),
borderRadius: [20, 20, 0, 0]
},
data: this.departmentList.map(item => parseFloat(item.use_money_total))
}
]
})
},
init() {
this.chart = echarts.init(document.getElementById("department-chart"));
this.setOptions();
let cardDom = document.getElementById('department-card');
let cardTitleH = 58;
const elementResize = ElementResize({
strategy:'scroll'
})
elementResize.listenTo(cardDom,ele => {
//this.setOptions()
this.chart.resize();
// this.tableHeight = cardDom.getBoundingClientRect().height - 40 - cardTitleH
})
}
},
computed: {
departmentList() {
if (this.getStatistic)
return this.getStatistic()?.statistic?.departmentList || [];
},
},
watch: {
departmentList: {
handler: function (newVal) {
this.setOptions()
},
immediate: false
}
},
created() {},
mounted() {
this.init();
}
};
</script>
<style scoped lang="scss">
.clearfix {
display: flex;
align-items: center;
}
::v-deep .el-progress--line {
display: flex;
align-items: center;
}
::v-deep .el-progress__text {
word-break: keep-all;
}
::v-deep .el-card__body {
width: 100%;
height: calc(100% - 58px);
}
#department-chart {
width: 100%;
height: 100%;
min-height: 200px;
}
</style>

@ -1,360 +0,0 @@
<template>
<el-card class="box-card" shadow="hover">
<div slot="header" class="clearfix">
<SvgIcon style="color: #3171f4;width: 22px;height: 22px;" icon-class="caidan"></SvgIcon>
<span style="padding-left: 15px">快捷菜单</span>
<Button v-if="/^\/system+/.test($route.path)" style="margin-left: auto;" size="small" type="primary" @click="isShow = true"></Button>
</div>
<div class="menu-container">
<div v-for="(item, index) in myMenus" :key="item.id" class="menu-item" :class="`quick-btn${(index+1)%4}`">
<div style="display: flex;align-items: center;" @click="linkTo(item)">
<el-image v-if="item.image" style="max-width: 26px;margin-right: 6px;" fit="contain" :src="item.image ? item.image.url : ''">
<template #error>
<Icon type="ios-alert" />
</template>
</el-image>
{{ item.name }}
</div>
<div class="operate-btn" v-if="/^\/system+/.test($route.path)">
<Icon color="#4d8bdc" class="operate-btn__item" type="ios-create-outline" @click="editMenu(item)"/>
<Icon color="#4d8bdc" class="operate-btn__item" type="ios-trash-outline" @click="destroyMenu(item)"/>
</div>
</div>
</div>
<template v-if="/^\/system+/.test($route.path)">
<xy-dialog title="快捷菜单" type="form" :is-show.sync="isShow" :form="form" :rules="rule" @submit="submit">
<template #url>
<div class="xy-table-item">
<div class="xy-table-item-label">
<span style="color: red; font-weight: 600; padding-right: 4px"
>*</span
>菜单
</div>
<div class="xy-table-item-content">
<el-cascader :value="form.url"
:show-all-levels="false"
ref="cascaderInput"
:options="menus"
style="width: 300px;"
@change="cascaderPick"
:props="{ label: 'name',value: 'path' }">
</el-cascader>
</div>
</div>
</template>
<template #name>
<div class="xy-table-item">
<div class="xy-table-item-label">
描述
</div>
<div class="xy-table-item-content">
<el-input v-model="form.name" clearable style="width: 300px;">
</el-input>
</div>
</div>
</template>
<template #sort>
<div class="xy-table-item">
<div class="xy-table-item-label">
排序
</div>
<div class="xy-table-item-content">
<el-input-number :controls="false" :precision="0" v-model="form.sort" clearable style="width: 300px;">
</el-input-number>
</div>
</div>
</template>
<template #status>
<div class="xy-table-item">
<div class="xy-table-item-label">
状态
</div>
<div class="xy-table-item-content">
<el-switch style="width: 300px;" v-model="form.status" :inactive-value="0" :active-value="1" inactive-text="禁用" active-text="启用"></el-switch>
</div>
</div>
</template>
<template #method>
<div class="xy-table-item">
<div class="xy-table-item-label">
打开方式
</div>
<div class="xy-table-item-content">
<el-select v-model="form.method" style="width: 300px;">
<el-option v-for="(item) in [{ label: '跳转',value: 'self' },{ label: '新页面',value: 'blank' }]" :value="item.value" :label="item.label">
</el-option>
</el-select>
</div>
</div>
</template>
<template #image_id>
<div class="xy-table-item">
<div class="xy-table-item-label">
图标
</div>
<div class="xy-table-item-content">
<el-upload
style="width: 300px"
ref="upload"
:limit="1"
:on-success="successHandle"
:before-upload="uploadBefore"
accept=".jpg,.png,.gif"
:action="action"
:file-list="fileList"
:auto-upload="false"
:on-remove="removeHande"
>
<el-button slot="trigger" size="small" type="primary"
>选取文件</el-button
>
<el-button
style="margin-left: 10px"
size="small"
type="success"
@click="$refs['upload'].submit()"
>开始上传</el-button
>
<div slot="tip" class="el-upload__tip">
支持文件格式 .jpg .png .gif
<br />单个文件不能超过50M
</div>
</el-upload>
</div>
</div>
</template>
</xy-dialog>
</template>
</el-card>
</template>
<script>
import { index, show, save, destroy } from "@/api/system/diyMenu";
import { listmenu } from "@/api/system/menu";
import { deepCopy } from '@/utils';
import { getAuthMenu } from "@/api/me"
import SvgIcon from "@/components/SvgIcon/index.vue";
export default {
components: {
SvgIcon,
},
name: "card7",
layout: {
x: 0,
y: 0,
w: 4,
h: 5,
i: "8",
name: "快捷菜单",
},
data() {
return {
fileList: [],
action: process.env.VUE_APP_UPLOAD_API,
myMenus: [],
isShow: false,
menus: [],
form: {
url: "",
name: "",
sort: "",
status: "",
method: "",
image_id: "",
fileList: [],
},
rule: {
url: [
{
required: true,
message: "请选择菜单",
},
]
}
}
},
methods: {
linkTo (item) {
if (item.method === 'self') {
this.$router.push(item.url)
return
}
if (item.method === 'blank') {
window.open(this.$router.resolve({
path: item.url
}).href,'_blank')
}
},
//
successHandle(response, file, fileList) {
this.fileList = fileList;
},
removeHande(file, fileList) {
this.fileList = fileList;
},
uploadBefore(file) {
console.log(file);
if (file.size / 1000 > 50 * 1024) {
this.$message({
type: "warning",
message: "上传图片大小超过50M",
});
return false;
}
},
async getMenu () {
const formatMenu = (arr) => {
arr.forEach(item => {
if (item.children) {
item.children.length === 0 ? delete item.children : formatMenu(item.children)
}
})
}
this.menus = (await getAuthMenu())
formatMenu(this.menus)
},
async getDiymenu () {
this.myMenus = (await index({
page: 1,
page_size: 999,
sort_name: "sort"
},true)).data
},
cascaderPick (e) {
const pathHandler = (path) => {
if(!path || path?.includes('#') || path == ''){
return '/'
}
if(/^\^/.test(path)){
return path.replace(/^\^+/g,"")
}
if(/^\$/.test(path)){
return path.replace(/^\$+/g,"")
}
return path
}
this.form.url = pathHandler(e?.at(-1)) || ''
this.$nextTick(() => {
this.form.name = this.$refs['cascaderInput']?.presentText
})
},
async submit () {
this.form.image_id = this.fileList[0]?.response?.id
await save(this.form)
this.$message({
type: "success",
message: "保存成功"
})
await this.getDiymenu()
this.isShow = false;
this.form = {
url: "",
name: "",
sort: "",
status: "",
method: ""
}
},
destroyMenu (item) {
this.$confirm('确认要删除, 是否继续?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
destroy({
id: item.id
}).then(res => {
this.$message({
type: 'success',
message: '删除成功!'
});
this.getDiymenu()
})
})
},
async editMenu (item) {
const res = deepCopy(item)
this.form = Object.assign({
url: "",
name: "",
sort: "",
status: "",
method: ""
},res)
this.isShow = true;
}
},
computed: {
},
created() {
this.getMenu()
this.getDiymenu()
}
}
</script>
<style scoped lang="scss">
$colors: linear-gradient(90deg, #ffa175 0%, #fd635d 99%, #fd635d 100%),linear-gradient(90deg, #d38ff3 0%, #c359fb 99%, #c359fb 100%),linear-gradient(90deg, #ffb737 0%, #ff9f3b 100%),linear-gradient(90deg, #4bcbf1 0%, #3ba7ef 99%, #3ba7ef 100%), linear-gradient(to left, #b3ffab, #12fff7);
$shadow: rgba(254,102,94,0.35),rgba(195,89,251,0.35),rgba(255,159,60,0.35),rgba(11,196,208,0.35),rgba(179,255,171,0.35);
@for $index from 1 through length($colors) {
.quick-btn#{$index} {
filter: drop-shadow(1.462px 4.782px 10px nth($shadow, $index));
background: nth($colors, $index);
}
}
.clearfix {
display: flex;
align-items: center;
}
::v-deep .el-input__inner {
text-align: left;
}
.xy-table-item-label {
width: 158px;
}
.menu-container {
display: flex;
flex-wrap: wrap;
.menu-item {
//background: $primaryColor;
color: #fff;
border-radius: 10px;
font-weight: 600;
padding: 14px 20px;
position: relative;
margin: 5px;
.operate-btn {
display: flex;
position: absolute;
top: -10px;
left: 8%;
&__item {
background: #fff;
zoom: .95;
border: 1px $primaryColor solid;
padding: 3px;
border-radius: 100%;
cursor: pointer;
margin-right: 8px;
}
}
}
}
</style>

@ -1,309 +0,0 @@
<template>
<el-card class="box-card" shadow="hover">
<div slot="header" class="clearfix">
<SvgIcon style="color: #3171f4;width: 22px;height: 22px;" icon-class="wengao"></SvgIcon>
<span style="padding-left: 15px"
>项目支出</span
>
<i class="el-icon-more" style="margin-left: auto; font-size: 20px"></i>
</div>
<div class="progress-card">
<div class="progress-card-item">
<div class="worker-progress__icon icon-yuan">
<SvgIcon icon-class="yuan"></SvgIcon>
</div>
<div class="progress-card-item__num">{{ moneyFormatter(statistic.progress.money_total_1 || 0) }}</div>
<div class="progress-card-item__label">年初预算合计金额</div>
</div>
<div class="progress-card-item">
<div class="worker-progress__icon icon-zhangdan">
<SvgIcon icon-class="zhangdan"></SvgIcon>
</div>
<div class="progress-card-item__num">{{ moneyFormatter(statistic.progress.money_total_2 || 0) }}</div>
<div class="progress-card-item__label">调整后预算合计金额</div>
</div>
<div class="progress-card-item">
<div class="worker-progress__icon icon-zhifu">
<SvgIcon icon-class="zhifu"></SvgIcon>
</div>
<div class="progress-card-item__num">{{moneyFormatter(statistic.progress.use_money_total || 0)}}</div>
<div class="progress-card-item__label">已支付金额</div>
</div>
<div class="progress-card-item">
<MyProgress width="145px" height="145px" title="执行率" :chart-data="[{value:statistic.progress.money_total_2 ? statistic.progress.money_total_2 : statistic.progress.money_total_1,name:''},{value:statistic.progress.use_money_total,name:''}]" ></MyProgress>
</div>
</div>
<Table style="margin-top: 20px;" :data="departments" size="small" :columns="table" :max-height="280"></Table>
</el-card>
</template>
<script>
import ElementResize from "element-resize-detector";
import { moneyFormatter } from "@/utils";
import echarts from 'echarts'
import SvgIcon from "@/components/SvgIcon/index.vue";
import MyProgress from "@/components/Progress/index.vue";
import {statistic} from "@/api/dashboard/notice";
export default {
components: {
MyProgress,
SvgIcon
},
name: "card8",
layout: {
x: 0,
y: 5,
w: 6,
h: 4,
i: "9",
name: "项目支出",
},
inject: {
getStatistic: {
default: () => {
return () => {
return {
statistic: {
departmentList: [
{
money_total_1: "1900000.00",
money_total_2: "0.00",
ids: "11",
plan_department_id: 2,
use_money_total: 0,
money_total: "0.00",
end_money: 0,
plan_department: {
id: 2,
pid: 0,
name: "办公室(党建作风办)",
manager_id: 7,
leader_id: 4,
sortnumber: 1,
created_at: "2021-06-22 07:01:41",
updated_at: "2023-03-22 14:56:51",
deleted_at: null,
},
},
],
},
};
}
},
},
},
data() {
return {
tableHeight: 200,
statistic: {
progress: {
money_total_1: 0,
money_total_2: 0,
use_money_total: 0
}
},
list: [],
table: [
{
title: "序号",
type: "index",
width: 60,
fixed: "left",
align: "center",
},
{
title: "部门",
key: "plan_department.name",
minWidth: 180,
align: "center",
fixed: "left",
render: (h, params) => {
return h("p",{ style: { "text-align": "left" } }, params.row.plan_department.name);
}
},
{
title: "年初预算数(元)",
key: "money_total_1",
align: "center",
width: 160,
render: (h, params) => {
return h("p",{ style: { "text-align": "right" } }, moneyFormatter(params.row.money_total_1));
}
},
{
title: "调整后预算数(元)",
key: "money_total_2",
align: "center",
width: 160,
render: (h, params) => {
return h("p",{ style: { "text-align": "right" } }, moneyFormatter(params.row.money_total_2));
}
},
{
title: "已使用(元)",
key: "money_total",
align: "center",
width: 140,
render: (h, params) => {
return h("p",{ style: { "text-align": "right" } }, moneyFormatter(params.row.money_total));
}
},
{
title: "进展情况",
key: "rate",
align: "center",
width: 160,
render: (h, row) => {
let m2 = row?.money_total_2 || 0;
let m1 = row?.money_total_1 || 0;
let m3 = row?.use_money_total || 0;
let per = 0;
if (m2 != 0) {
per = ((m3 / m2) * 100).toFixed(2);
} else if (m1 != 0) {
per = ((m3 / m1) * 100).toFixed(2);
}
return h("el-progress", {
props: {
percentage: Number(per),
},
});
}
},
{
title: "操作",
key: "action",
align: "center",
minWidth: 100,
render: (h, params) => {
return h("Button", {
props: {
size: "small"
}
} , "查看")
}
}
]
};
},
methods: {
moneyFormatter,
init() {
let cardDom = this.$el;
let cardTitleH = 58;
const elementResize = ElementResize({
strategy:'scroll'
})
elementResize.listenTo(cardDom,ele => {
this.tableHeight = cardDom.getBoundingClientRect().height - 40 - cardTitleH
})
},
async getStatistics() {
if(/^\/system/.test(this.$route.path)) return
const res = await statistic(this.select,true)
this.statistic = res
this.$emit('send-data',res)
},
},
computed: {
departments () {
return this.getStatistics()?.statistic?.departmentList
}
},
created() {
this.getStatistic();
},
mounted() {
this.init();
}
};
</script>
<style scoped lang="scss">
.clearfix {
display: flex;
align-items: center;
}
::v-deep .el-card__body {
width: 100%;
height: calc(100% - 58px);
}
::v-deep .ivu-table th,::v-deep .ivu-table td {
border-bottom-style: dashed;
}
.progress-card {
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-gap: 20px;
&-item {
display: flex;
flex-direction: column;
align-items: center;
text-align: center;
&__label {
font-size: 15px;
color: #000000;
padding-top: 20px;
}
&__num {
font-size: 20px;
line-height: 7px;
color: #000000;
font-weight: bold;
padding-top: 18px;
}
.worker-progress__icon {
border-radius: 20px;
display: flex;
align-items: center;
justify-content: center;
width: 72px;
height: 72px;
svg {
border-radius: 100%;
width: 40px;
height: 40px;
}
}
.icon-yuan {
background: #56b7f9;
color: #fff;
filter: drop-shadow(0px 6px 6px rgba(43,188,255,0.5));
svg {
color: #56b7f9;
background: #fff;
}
}
.icon-zhangdan {
background: #446df6;
filter: drop-shadow(0px 6px 6px rgba(54,117,255,0.5));
svg {
color: #fff;
width: 36px;
}
}
.icon-zhifu {
background: #f2a93f;
filter: drop-shadow(0px 6px 6px rgba(255,164,45,0.5));
svg {
color: #fff;
width: 36px;
}
}
}
}
::v-deep .el-progress--circle .el-progress__text {
white-space: break-spaces;
}
</style>

@ -1,274 +0,0 @@
<template>
<el-card class="box-card" shadow="hover" id="todo-card">
<div slot="header" class="clearfix">
<SvgIcon style="color: #3171f4;width: 22px;height: 22px;" icon-class="notice"></SvgIcon>
<span style="padding-left: 15px"
>待办事项</span
>
<i class="el-icon-more" style="margin-left: auto; font-size: 20px"></i>
</div>
<div style="position: relative;height: 100%;width: 100%;">
<div style="position: absolute;top: 0;left: 0;right: 0;bottom: 0;">
<Table
:show-header="false"
:height="tableHeight"
:loading="loading"
size="small"
:data="/^\/system/.test(this.$route.path) ? example : list"
:columns="table"
></Table>
</div>
</div>
</el-card>
</template>
<script>
import SvgIcon from "@/components/SvgIcon/index.vue";
import { getNotice2, readNotice } from "@/api/dashboard/notice";
import ElementResize from "element-resize-detector";
export default {
components: {
SvgIcon
},
name: "card2",
layout: {
x: 4,
y: 0,
w: 6,
h: 4,
i: "2",
name: "待办事项",
},
data() {
return {
window: {
width: 0,
height: 0,
top: 0,
left: 0,
},
example: [
{
type: 1,
content: "示例1",
created_at: this.$moment().format("YYYY-MM-DD HH:mm:ss"),
read_count: true,
},
{
type: 2,
content: "示例2",
created_at: this.$moment().format("YYYY-MM-DD HH:mm:ss"),
read_count: false,
},
],
select: {
page: 1,
page_size: 10,
},
tableHeight: 120,
loading: false,
list: [],
total: 0,
table: [
{
type: "index",
title: " ",
align: "center",
width: 46,
},
{
title: "收件时间",
key: "created_at",
width: 160,
align: "center",
render: (h, { row }) => {
return h("span",{ style: { color: "#4d8bdc" } }, this.$moment(row.created_at).format("YYYY-MM-DD HH:mm:ss"));
},
},
{
title: "内容",
key: "title",
align: "left",
ellipsis: true,
tooltip: true,
minWidth: 200,
},
{
title: "查看",
key: "show",
width: 180,
render: (h, { row }) => {
return h('div',[
h(
"Button",
{
props: {
type: "default",
size: "small",
},
style: {
background: "#f0f3fa",
color: "#333",
border: "1px solid #dae1f0",
fontSize: "13px"
},
on: {
["click"]: (_) => {
if(row.from_type === 'contract') {
this.$router.push({
path: '/contract/contract/contractList',
query: {
keyword:/\[(.*?)\]/.exec(row.title) ? /\[(.*?)\]/.exec(row.title)[1] : ''
}
})
} else {
window.open(
`${process.env.VUE_APP_OUT_OLD}/flow/view/${row.id}?auth_token=${this.$store.getters.oa_token}`,
"edit",
`top=${this.window.top},left=${this.window.left},width=${this.window.width},height=${this.window.height},location=0`
);
}
},
},
},
"查看"
),
h(
"Button",
{
props: {
type: "primary",
size: "small",
},
style: {
"margin-left": "6px",
fontSize: "13px"
},
on: {
["click"]: (_) => {
if(row.from_type === 'contract') {
this.$router.push({
path: '/contract/contract/contractList',
query: {
keyword:/\[(.*?)\]/.exec(row.title) ? /\[(.*?)\]/.exec(row.title)[1] : ''
}
})
} else {
window.open(
`${process.env.VUE_APP_OUT_OLD}/flow/deal/${row.id}?auth_token=${this.$store.getters.oa_token}`,
"edit",
`top=${this.window.top},left=${this.window.left},width=${this.window.width},height=${this.window.height},location=0`
);
}
},
},
},
"办理"
)
]);
},
},
// {
// title: "",
// key: "read_count",
// width: 120,
// render: (h, { row }) => {
// return row.read_count
// ? h(
// "el-link",
// {
// props: {
// type: "success",
// underline: false,
// },
// },
// ""
// )
// : h(
// "Button",
// {
// props: {
// type: "error",
// size: "small",
// ghost: true
// },
// on: {
// ['click']:e => {
// if(/^\/system/.test(this.$route.path)) return
//
// readNotice({
// id: row.id
// }).then(res => {
// this.$message({
// type: 'success',
// message: ''
// })
// this.getNotices()
// })
// }
// }
// },
// ""
// );
// },
// },
],
};
},
methods: {
async getNotices() {
if (/^\/system/.test(this.$route.path)) return;
try {
this.loading = true;
const res = await getNotice2(this.select, true);
this.list = res;
this.total = res.length;
this.loading = false;
} catch (e) {
this.loading = false;
}
},
init() {
let cardDom = document.getElementById("todo-card");
let cardTitleH = 58;
const elementResize = ElementResize({
strategy: "scroll",
});
elementResize.listenTo(cardDom, (ele) => {
this.tableHeight =
cardDom.getBoundingClientRect().height -
40 -
cardTitleH
});
},
},
computed: {},
created() {
this.window.width = screen.availWidth * 0.95;
this.window.height = screen.availHeight * 0.95;
this.window.top = (window.screen.height - 30 - this.window.height) / 2;
this.window.left = (window.screen.width - 10 - this.window.width) / 2;
this.getNotices();
},
mounted() {
this.init();
},
};
</script>
<style scoped lang="scss">
::v-deep .el-card__body {
width: 100%;
height: calc(100% - 58px);
}
::v-deep .ivu-table th,::v-deep .ivu-table td {
border-bottom-style: dashed;
}
.clearfix {
display: flex;
align-items: center;
}
</style>

@ -1,186 +0,0 @@
<template>
<el-card class="box-card" shadow="hover">
<div slot="header" class="clearfix">
<SvgIcon style="color: #3171f4;width: 22px;height: 22px;" icon-class="calendar-check"></SvgIcon>
<span style="padding-left: 15px;">预算总体执行情况</span>
<DatePicker transfer :value="select.year" placeholder="选择所属年份" placement="bottom" style="width: 130px;margin-left: auto;"
type="year" @on-change="changeYear"></DatePicker>
</div>
<div class="progress-card">
<div class="progress-card-item">
<div class="worker-progress__icon icon-yuan">
<SvgIcon icon-class="yuan"></SvgIcon>
</div>
<div class="progress-card-item__num">{{moneyFormatter(statistic.progress.money_total_1 || 0)}}</div>
<div class="progress-card-item__label">年初预算合计金额</div>
</div>
<div class="progress-card-item">
<div class="worker-progress__icon icon-zhangdan">
<SvgIcon icon-class="zhangdan"></SvgIcon>
</div>
<div class="progress-card-item__num">{{moneyFormatter(statistic.progress.money_total_2 || 0)}}</div>
<div class="progress-card-item__label">调整后预算合计金额</div>
</div>
<div class="progress-card-item">
<div class="worker-progress__icon icon-zhifu">
<SvgIcon icon-class="zhifu"></SvgIcon>
</div>
<div class="progress-card-item__num">{{moneyFormatter(statistic.progress.use_money_total || 0)}}</div>
<div class="progress-card-item__label">已支付金额</div>
</div>
<div class="progress-card-item">
<MyProgress width="145px" height="145px" title="执行率" :chart-data="[{value:statistic.progress.money_total_2 ? statistic.progress.money_total_2 : statistic.progress.money_total_1,name:''},{value:statistic.progress.use_money_total,name:''}]" ></MyProgress>
<!-- <el-progress :width="145" type="circle" stroke-width="20" :format="per => `${per}%\n执行率`" :percentage="40"></el-progress>-->
<!-- <div class="progress-card-item__num">-->
<!-- {{toper(statistic.progress.money_total_1 || 0,statistic.progress.money_total_2 || 0,statistic.progress.use_money_total || 0)}}%-->
<!-- </div>-->
<!-- <div class="progress-card-item__label">执行率</div>-->
</div>
</div>
</el-card>
</template>
<script>
import MyProgress from "@/components/Progress";
import SvgIcon from "@/components/SvgIcon";
import { moneyFormatter } from "@/utils"
import { statistic } from '@/api/dashboard/notice'
export default {
components: {
SvgIcon,
MyProgress
},
name:"card1",
layout:{
x:0,
y:0,
w:4,
h:5,
i:"1",
name:"预算统计",
},
data() {
return {
select: {
year: new Date().getFullYear().toString()
},
statistic: {
progress: {
money_total_1: 0,
money_total_2: 0,
use_money_total: 0
}
}
}
},
methods: {
moneyFormatter,
toper(m1, m2, m3) {
if (m2 != 0) {
return ((m3 / m2) * 100).toFixed(2);
} else if (m1 != 0) {
return ((m3 / m1) * 100).toFixed(2);
} else
return 0
},
changeYear(e) {
this.select.year = e;
this.getStatistic()
},
async getStatistic() {
if(/^\/system/.test(this.$route.path)) return
const res = await statistic(this.select,true)
this.statistic = res
this.$emit('send-data',res)
},
},
computed: {},
created() {
this.getStatistic();
}
}
</script>
<style scoped lang="scss">
.clearfix {
display: flex;
align-items: center;
}
.progress-card {
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-gap: 20px;
&-item {
display: flex;
flex-direction: column;
align-items: center;
text-align: center;
&__label {
font-size: 15px;
color: #000000;
padding-top: 20px;
}
&__num {
font-size: 20px;
line-height: 7px;
color: #000000;
font-weight: bold;
padding-top: 18px;
}
.worker-progress__icon {
border-radius: 20px;
display: flex;
align-items: center;
justify-content: center;
width: 72px;
height: 72px;
svg {
border-radius: 100%;
width: 40px;
height: 40px;
}
}
.icon-yuan {
background: #56b7f9;
color: #fff;
filter: drop-shadow(0px 6px 6px rgba(43,188,255,0.5));
svg {
color: #56b7f9;
background: #fff;
}
}
.icon-zhangdan {
background: #446df6;
filter: drop-shadow(0px 6px 6px rgba(54,117,255,0.5));
svg {
color: #fff;
width: 36px;
}
}
.icon-zhifu {
background: #f2a93f;
filter: drop-shadow(0px 6px 6px rgba(255,164,45,0.5));
svg {
color: #fff;
width: 36px;
}
}
}
}
::v-deep .el-progress--circle .el-progress__text {
white-space: break-spaces;
}
</style>
<style>
.progress-card-item > .icon-yuan > svg > use {
transform: scale(0.55);
transform-origin: center;
}
</style>

@ -1,305 +0,0 @@
<template>
<el-card class="box-card" shadow="hover" id="type-card">
<div slot="header" class="clearfix">
<SvgIcon style="color: #3171f4;width: 22px;height: 22px;" icon-class="wengao"></SvgIcon>
<span style="padding-left: 15px"
>预算类型执行情况</span
>
<i class="el-icon-more" style="margin-left: auto; font-size: 20px"></i>
</div>
<div id="type-card-body" style="position: relative;height: 100%;width: 100%;">
<div style="position: absolute;top: 0;left: 0;right: 0;bottom: 0;">
<Table style="width: 100%;" :height="tableHeight" size="small" :data="departmentList" :columns="table"></Table>
</div>
</div>
</el-card>
</template>
<script>
import ElementResize from "element-resize-detector";
import { moneyFormatter } from "@/utils";
import echarts from 'echarts'
import SvgIcon from "@/components/SvgIcon/index.vue";
export default {
components: {
SvgIcon
},
name: "card3",
layout: {
x: 0,
y: 5,
w: 6,
h: 4,
i: "5",
name: "预算类型执行情况",
},
inject: {
getStatistic: {
default: () => {
return () => {
return {
statistic: {
typeList: [
{
money_total_1: "17549700.00",
money_total_2: "0.00",
ids: "23,39,38,36,35,33,32,30,28,26,25,6,22,20,17,16,14,13,12,11,9,8",
type: 7,
use_money_total: "1150000.00",
type_text: "项目经费",
money_total: "0.00",
end_money: 0,
},{
money_total_1: "17549700.00",
money_total_2: "0.00",
ids: "23,39,38,36,35,33,32,30,28,26,25,6,22,20,17,16,14,13,12,11,9,8",
type: 7,
use_money_total: "50000.00",
type_text: "项目经费",
money_total: "0.00",
end_money: 0,
},{
money_total_1: "17549700.00",
money_total_2: "0.00",
ids: "23,39,38,36,35,33,32,30,28,26,25,6,22,20,17,16,14,13,12,11,9,8",
type: 7,
use_money_total: "50000.00",
type_text: "项目经费",
money_total: "0.00",
end_money: 0,
},{
money_total_1: "17549700.00",
money_total_2: "0.00",
ids: "23,39,38,36,35,33,32,30,28,26,25,6,22,20,17,16,14,13,12,11,9,8",
type: 7,
use_money_total: "50000.00",
type_text: "项目经费",
money_total: "0.00",
end_money: 0,
},{
money_total_1: "17549700.00",
money_total_2: "0.00",
ids: "23,39,38,36,35,33,32,30,28,26,25,6,22,20,17,16,14,13,12,11,9,8",
type: 7,
use_money_total: "50000.00",
type_text: "项目经费",
money_total: "0.00",
end_money: 0,
},{
money_total_1: "17549700.00",
money_total_2: "0.00",
ids: "23,39,38,36,35,33,32,30,28,26,25,6,22,20,17,16,14,13,12,11,9,8",
type: 7,
use_money_total: "50000.00",
type_text: "项目经费",
money_total: "0.00",
end_money: 0,
},{
money_total_1: "17549700.00",
money_total_2: "0.00",
ids: "23,39,38,36,35,33,32,30,28,26,25,6,22,20,17,16,14,13,12,11,9,8",
type: 7,
use_money_total: "50000.00",
type_text: "项目经费",
money_total: "0.00",
end_money: 0,
},{
money_total_1: "17549700.00",
money_total_2: "0.00",
ids: "23,39,38,36,35,33,32,30,28,26,25,6,22,20,17,16,14,13,12,11,9,8",
type: 7,
use_money_total: "50000.00",
type_text: "项目经费",
money_total: "0.00",
end_money: 0,
},{
money_total_1: "17549700.00",
money_total_2: "0.00",
ids: "23,39,38,36,35,33,32,30,28,26,25,6,22,20,17,16,14,13,12,11,9,8",
type: 7,
use_money_total: "50000.00",
type_text: "项目经费",
money_total: "0.00",
end_money: 0,
},{
money_total_1: "17549700.00",
money_total_2: "0.00",
ids: "23,39,38,36,35,33,32,30,28,26,25,6,22,20,17,16,14,13,12,11,9,8",
type: 7,
use_money_total: "50000.00",
type_text: "项目经费",
money_total: "0.00",
end_money: 0,
},{
money_total_1: "17549700.00",
money_total_2: "0.00",
ids: "23,39,38,36,35,33,32,30,28,26,25,6,22,20,17,16,14,13,12,11,9,8",
type: 7,
use_money_total: "50000.00",
type_text: "项目经费",
money_total: "0.00",
end_money: 0,
},{
money_total_1: "17549700.00",
money_total_2: "0.00",
ids: "23,39,38,36,35,33,32,30,28,26,25,6,22,20,17,16,14,13,12,11,9,8",
type: 7,
use_money_total: "50000.00",
type_text: "项目经费",
money_total: "0.00",
end_money: 0,
},{
money_total_1: "17549700.00",
money_total_2: "0.00",
ids: "23,39,38,36,35,33,32,30,28,26,25,6,22,20,17,16,14,13,12,11,9,8",
type: 7,
use_money_total: "50000.00",
type_text: "项目经费",
money_total: "0.00",
end_money: 0,
},{
money_total_1: "17549700.00",
money_total_2: "0.00",
ids: "23,39,38,36,35,33,32,30,28,26,25,6,22,20,17,16,14,13,12,11,9,8",
type: 7,
use_money_total: "50000.00",
type_text: "项目经费",
money_total: "0.00",
end_money: 0,
},{
money_total_1: "17549700.00",
money_total_2: "0.00",
ids: "23,39,38,36,35,33,32,30,28,26,25,6,22,20,17,16,14,13,12,11,9,8",
type: 7,
use_money_total: "50000.00",
type_text: "项目经费",
money_total: "0.00",
end_money: 0,
},{
money_total_1: "17549700.00",
money_total_2: "0.00",
ids: "23,39,38,36,35,33,32,30,28,26,25,6,22,20,17,16,14,13,12,11,9,8",
type: 7,
use_money_total: "50000.00",
type_text: "项目经费",
money_total: "0.00",
end_money: 0,
},
],
},
};
};
},
},
},
data() {
return {
tableHeight: 200,
table: [
{
title: "预算类别",
width: 100,
key: "type_text",
ellipsis: true,
tooltip: true,
fixed: "left",
},
{
title: "执行情况",
minWidth: 120,
fixed: "right",
render: (h, { row }) => {
let m2 = row?.money_total_2 || 0;
let m1 = row?.money_total_1 || 0;
let m3 = row?.use_money_total || 0;
let per = 0;
if (m2 != 0) {
per = ((m3 / m2) * 100).toFixed(2);
} else if (m1 != 0) {
per = ((m3 / m1) * 100).toFixed(2);
}
return h("el-progress", {
props: {
"stroke-width": 13,
percentage: Number(per),
},
});
},
},
{
title: "年初预算合计金额(元)",
width: 170,
align: "right",
key: "money_total_1",
render: (h, { row }) => {
return h("span", {}, moneyFormatter(row.money_total_1));
},
},
{
title: "调整后预算合计金额(元)",
width: 170,
align: "right",
key: "money_total_2",
render: (h, { row }) => {
return h("span", {}, moneyFormatter(row.money_total_2));
},
},
{
title: "已使用(元)",
width: 120,
align: "right",
key: "use_money_total",
render: (h, { row }) => {
return h("span", {}, moneyFormatter(row.use_money_total));
},
},
],
};
},
methods: {
init() {
let cardDom = document.getElementById('type-card');
let cardTitleH = 58;
const elementResize = ElementResize({
strategy:'scroll'
})
elementResize.listenTo(cardDom,ele => {
this.tableHeight = cardDom.getBoundingClientRect().height - 40 - cardTitleH
})
}
},
computed: {
departmentList() {
if (this.getStatistic)
return this.getStatistic()?.statistic?.typeList || [];
},
},
created() {},
mounted() {
this.init();
}
};
</script>
<style scoped lang="scss">
.clearfix {
display: flex;
align-items: center;
}
::v-deep .el-card__body {
width: 100%;
height: calc(100% - 58px);
}
::v-deep .ivu-table th,::v-deep .ivu-table td {
border-bottom-style: dashed;
}
::v-deep .el-progress {
white-space: nowrap;
}
::v-deep .el-progress__text {
color: rgb(77, 139, 220);
}
</style>
Loading…
Cancel
Save