Browse Source

优化内容

changchun
zhouhaibin 3 months ago
parent
commit
4420daa215
  1. 2
      .vscode/settings.json
  2. 15
      apps/test-server/README.md
  3. 18
      apps/test-server/controller/FileController.ts
  4. 15
      apps/test-server/controller/UserController.ts
  5. 18
      apps/test-server/ecosystem.config.js
  6. 63
      apps/test-server/index.ts
  7. 8
      apps/test-server/nodemon.json
  8. 36
      apps/test-server/package.json
  9. 23
      apps/test-server/routes.ts
  10. 54
      apps/test-server/service/FileService.ts
  11. 25
      apps/test-server/service/UserService.ts
  12. 7
      apps/test-server/tsconfig.json
  13. 9
      apps/test-server/utils.ts
  14. 2
      internal/ts-config/package.json
  15. 11
      package.json
  16. 22
      src/api/common/api.ts
  17. 241
      src/api/common/base64.min.js
  18. 99
      src/views/ProcessApprovalSubPage/component/ApprovalPageModel.vue
  19. 19
      src/views/ProcessApprovalSubPage/component/PlanFileDetail.vue
  20. 29
      src/views/ProcessApprovalSubPage/planFileApproval.vue
  21. 21
      src/views/ProcessApprovalSubPage/uploadURTfileApproval.vue
  22. 5
      src/views/Regulation/RegulationLab/index.vue
  23. 2
      src/views/dashboard/workbench/components/basic_bar.vue
  24. 36
      src/views/dashboard/workbench/components/projectDetail.vue
  25. 128
      src/views/dashboard/workbench/index.vue
  26. 6
      src/views/informationSub/monthlyJournal/index.vue
  27. 2
      src/views/myWork/inComplete/inComplete.api.ts
  28. 6
      src/views/projectBoard/liangShaiKanBan/liangShaiKanBan.data.ts
  29. 4
      src/views/projectBoard/urt/qingkuang/index.vue
  30. 32
      src/views/projectBoard/urt/qingkuang/qingkuang.data.ts
  31. 65
      src/views/projectBoard/urt/urt/index.vue
  32. 4
      src/views/projectBoard/urt/urt/urt.api.ts
  33. 133
      src/views/projectBoard/urt/urt/urt.data.ts
  34. 2
      src/views/projectLib/projectInfo/index.vue
  35. 4
      src/views/projectLib/projectInfo/projectInfo.api.ts
  36. 2
      src/views/projectLib/projectPlan/addPlan.vue
  37. 43
      src/views/projectLib/projectPlan/addPlanFile.vue
  38. 4
      src/views/projectLib/projectPlan/index.vue
  39. 16
      src/views/projectLib/projectPlan/projectPlan.api.ts
  40. 73
      src/views/projectLib/projectPlan/viewPlanDetail.vue
  41. 32
      src/views/projectLib/projectProgress/index.vue
  42. 4
      src/views/projectLib/workReport/detaiWorkReport.vue
  43. 12
      src/views/projectLib/workReport/index.vue
  44. 2
      src/views/projectSummary/planSummary/planSummary.api.ts
  45. 135
      src/views/projectSummary/planSummary/planSummary.data.ts
  46. 262
      src/views/projectSummary/planSummary/shouyeindex.vue
  47. 1
      src/views/workSystem/organizationStructure/organizationStructure.api.ts

2
.vscode/settings.json

@ -92,7 +92,7 @@
"source.fixAll.eslint": "explicit",
"source.fixAll.stylelint": "explicit"
},
"editor.defaultFormatter": "Vue.volar"
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"i18n-ally.localesPaths": ["src/locales/lang"],
"i18n-ally.keystyle": "nested",

15
apps/test-server/README.md

@ -1,15 +0,0 @@
# Test Server
It is used to start the test interface service, which can test the upload, websocket, login and other interfaces.
## Usage
```bash
cd ./test/server
pnpm install
pnpm run start
```

18
apps/test-server/controller/FileController.ts

@ -1,18 +0,0 @@
import FileService from '../service/FileService';
class FileController {
private service: FileService = new FileService();
upload = async (ctx) => {
const files = ctx.request.files.file;
console.log(files);
if (files.length === undefined) {
this.service.upload(ctx, files, false);
} else {
this.service.upload(ctx, files, true);
}
};
}
export default new FileController();

15
apps/test-server/controller/UserController.ts

@ -1,15 +0,0 @@
import UserService from '../service/UserService';
class UserController {
private service: UserService = new UserService();
login = async (ctx) => {
ctx.body = await this.service.login();
};
getUserInfoById = async (ctx) => {
ctx.body = await this.service.getUserInfoById();
};
}
export default new UserController();

18
apps/test-server/ecosystem.config.js

@ -1,18 +0,0 @@
const { name } = require('./package.json');
const path = require('path');
module.exports = {
apps: [
{
name,
script: path.resolve(__dirname, './dist/index.js'),
instances: require('os').cpus().length,
autorestart: true,
watch: true,
env_production: {
NODE_ENV: 'production',
PORT: 8080,
},
},
],
};

63
apps/test-server/index.ts

@ -1,63 +0,0 @@
import Koa from 'koa';
import path from 'path';
import Router from 'koa-router';
import body from 'koa-body';
import cors from 'koa2-cors';
import koaStatic from 'koa-static';
import websockify from 'koa-websocket';
import route from 'koa-route';
import AppRoutes from './routes';
const PORT = 3300;
const app = websockify(new Koa());
app.ws.use(function (ctx, next) {
ctx.websocket.send('connection succeeded!');
return next(ctx);
});
app.ws.use(
route.all('/test', function (ctx) {
// ctx.websocket.send('Hello World');
ctx.websocket.on('message', function (message) {
// do something with the message from client
if (message !== 'ping') {
const data = JSON.stringify({
id: Math.ceil(Math.random() * 1000),
time: new Date().getTime(),
res: `${message}`,
});
ctx.websocket.send(data);
}
console.log(message);
});
}),
);
const router = new Router();
// router
AppRoutes.forEach((route) => router[route.method](route.path, route.action));
app.use(cors());
app.use(
body({
encoding: 'gzip',
multipart: true,
formidable: {
// uploadDir: path.join(__dirname, '/upload/'), // 设置文件上传目录
keepExtensions: true,
maxFieldsSize: 20 * 1024 * 1024,
},
}),
);
app.use(router.routes());
app.use(router.allowedMethods());
app.use(koaStatic(path.join(__dirname)));
app.listen(PORT, () => {
console.log(`Application started successfully: http://localhost:${PORT}`);
});

8
apps/test-server/nodemon.json

@ -1,8 +0,0 @@
{
"watch": ["src"],
"ext": "ts",
"exec": "ts-node -r tsconfig-paths/register index.ts",
"events": {
"restart": "clear"
}
}

36
apps/test-server/package.json

@ -1,36 +0,0 @@
{
"name": "server",
"version": "1.0.0",
"license": "MIT",
"scripts": {
"compile": "rimraf ./dist && tsup ./index.ts --dts --format cjs,esm ",
"prod": "npx pm2 start ecosystem.config.js --env production",
"restart": "pm2 restart ecosystem.config.js --env production",
"start": "nodemon",
"stop": "npx pm2 stop ecosystem.config.js"
},
"dependencies": {
"fs-extra": "^11.1.1",
"koa": "^2.14.2",
"koa-body": "^6.0.1",
"koa-bodyparser": "^4.4.1",
"koa-route": "^3.2.0",
"koa-router": "^12.0.0",
"koa-static": "^5.0.0",
"koa-websocket": "^7.0.0",
"koa2-cors": "^2.0.6"
},
"devDependencies": {
"@types/koa": "^2.13.6",
"@types/koa-bodyparser": "^5.0.2",
"@types/koa-router": "^7.4.4",
"@types/node": "^20.4.0",
"nodemon": "^2.0.22",
"pm2": "^5.3.0",
"rimraf": "^5.0.1",
"ts-node": "^10.9.1",
"tsconfig-paths": "^4.2.0",
"tsup": "^7.1.0",
"typescript": "^5.1.6"
}
}

23
apps/test-server/routes.ts

@ -1,23 +0,0 @@
import UserController from './controller/UserController';
import FileController from './controller/FileController';
export default [
// user
{
path: '/login',
method: 'post',
action: UserController.login,
},
{
path: '/getUserInfoById',
method: 'get',
action: UserController.getUserInfoById,
},
// file
{
path: '/upload',
method: 'post',
action: FileController.upload,
},
];

54
apps/test-server/service/FileService.ts

@ -1,54 +0,0 @@
import path from 'path';
import fs from 'fs-extra';
const uploadUrl = 'http://localhost:3300/static/upload';
const filePath = path.join(__dirname, '../static/upload/');
fs.ensureDir(filePath);
export default class UserService {
async upload(ctx, files, isMultiple) {
let fileReader, fileResource, writeStream;
const fileFunc = function (file) {
fileReader = fs.createReadStream(file.path);
fileResource = filePath + `/${file.name}`;
console.log(fileResource);
writeStream = fs.createWriteStream(fileResource);
fileReader.pipe(writeStream);
};
const returnFunc = function (flag) {
if (flag) {
let url = '';
for (let i = 0; i < files.length; i++) {
url += uploadUrl + `/${files[i].name},`;
}
url = url.replace(/,$/gi, '');
ctx.body = {
url: url,
code: 0,
message: 'upload Success!',
};
} else {
ctx.body = {
url: uploadUrl + `/${files.name}`,
code: 0,
message: 'upload Success!',
};
}
};
console.log(isMultiple, files.length);
if (isMultiple) {
for (let i = 0; i < files.length; i++) {
const f1 = files[i];
fileFunc(f1);
}
} else {
fileFunc(files);
}
fs.ensureDir(filePath);
returnFunc(isMultiple);
}
}

25
apps/test-server/service/UserService.ts

@ -1,25 +0,0 @@
import { Result } from '../utils';
const fakeUserInfo = {
userId: '1',
username: 'vben',
realName: 'Vben Admin',
desc: 'manager',
password: '123456',
token: 'fakeToken1',
roles: [
{
roleName: 'Super Admin',
value: 'super',
},
],
};
export default class UserService {
async login() {
return Result.success(fakeUserInfo);
}
async getUserInfoById() {
return Result.success(fakeUserInfo);
}
}

7
apps/test-server/tsconfig.json

@ -1,7 +0,0 @@
{
"$schema": "https://json.schemastore.org/tsconfig",
"extends": "@vben/ts-config/node-server.json",
"compilerOptions": {
"noImplicitAny": false
}
}

9
apps/test-server/utils.ts

@ -1,9 +0,0 @@
export class Result {
static success(data: any) {
return {
code: 0,
success: true,
result: data,
};
}
}

2
internal/ts-config/package.json

@ -20,6 +20,6 @@
],
"dependencies": {
"@types/node": "^20.4.0",
"vite": "^4.4.0"
"vite": "^4.5.2"
}
}

11
package.json

@ -77,10 +77,10 @@
"@vueuse/shared": "^10.2.1",
"@zxcvbn-ts/core": "^3.0.2",
"ant-design-vue": "^4.0.6",
"axios": "^1.4.0",
"axios": "1.7.4",
"codemirror": "^5.65.12",
"cropperjs": "^1.5.13",
"crypto-js": "^4.1.1",
"crypto-js": "^4.2.0",
"dayjs": "^1.11.10",
"driver.js": "^1.3.0",
"echarts": "^5.4.2",
@ -121,7 +121,7 @@
"@iconify/json": "^2.2.87",
"@purge-icons/generated": "^0.9.0",
"@types/codemirror": "^5.60.8",
"@types/crypto-js": "^4.1.1",
"@types/crypto-js": "^4.2.2",
"@types/lodash-es": "^4.17.7",
"@types/mockjs": "^1.0.7",
"@types/nprogress": "^0.2.0",
@ -147,9 +147,10 @@
"turbo": "^1.10.7",
"typescript": "^5.2.2",
"unbuild": "^1.2.1",
"vite": "^4.4.0",
"vite": "^4.5.2",
"vite-plugin-mock": "^2.9.6",
"vue-tsc": "^1.8.4"
"vue-tsc": "^1.8.4",
"js-base64":"3.7.7"
},
"packageManager": "pnpm@8.1.0",
"engines": {

22
src/api/common/api.ts

@ -1,11 +1,12 @@
import { defHttp } from '@/utils/http/axios';
import { message } from 'ant-design-vue';
import * as streamSaver from "streamsaver"
import { getToken } from '@/utils/auth';
import { useGlobSetting } from '@/hooks/setting';
import { Base64 } from "js-base64";
import { buildUUID } from '@/utils/uuid';
const { apiUrl } = useGlobSetting();
import axios from 'axios';
/**
*
* @param url
@ -30,13 +31,26 @@ export const downloadFile = (url, fileName?, parameter?) => {
document.body.appendChild(link);
link.click();
document.body.removeChild(link); //下载完成移除元素
window.URL.revokeObjectURL(url); //释放掉blob对象
window.URL.revokeObjectURL(url); //释放掉blob对象window.btoa(unescape(encodeURIComponent('我是一段需要处理的字符')))
}
});
};
export const downloadonlinePreview = async (url, fileName,parameter) =>{
let originUrl="http://218.246.6.165:8080"+apiUrl + url+"?path="+parameter.path+"&fileName="+parameter.fileName
// let fileType=parameter.fileName.substring(parameter.fileName.lastIndexOf(".")+1)
// let uuid= buildUUID()
let previewUrl = originUrl + "&fullfilename=" +parameter.path.substring(parameter.path.lastIndexOf("/")+1); //带上文件名(带后缀)
console.log(previewUrl,'previewUrl')
window.open( 'http://218.246.6.173:9002' + "/onlinePreview?url=" + encodeURIComponent(Base64.encode(previewUrl)))
}
export const downloadResource = async (url, fileName,parameter) =>{
// let originUrl="http://localhost:3100"+apiUrl + url+"?path="+parameter.path+"&fileName="+parameter.fileName
// let previewUrl = originUrl + "&fullfilename=" + parameter.fileName; //带上文件名(带后缀)
// window.open( 'http://218.246.6.173:9002' + "/onlinePreview?url=" + encodeURIComponent(Base64.encode(previewUrl)))
url = apiUrl + url+"?path="+encodeURIComponent(parameter.path)+"&fileName="+parameter.fileName
console.log(apiUrl ,url,'previewUrl')
let filename = fileName
if (!fileName) {
filename = url.substring(url.lastIndexOf('/') + 1);

241
src/api/common/base64.min.js

@ -0,0 +1,241 @@
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined'
? (module.exports = factory(global))
: typeof define === 'function' && define.amd
? define(factory)
: factory(global);
})(
typeof self !== 'undefined'
? self
: typeof window !== 'undefined'
? window
: typeof global !== 'undefined'
? global
: this,
function (global) {
global = global || {};
var _Base64 = global.Base64;
var version = '2.6.3';
var b64chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
var b64tab = (function (bin) {
var t = {};
for (var i = 0, l = bin.length; i < l; i++) {
t[bin.charAt(i)] = i;
}
return t;
})(b64chars);
var fromCharCode = String.fromCharCode;
var cb_utob = function (c) {
if (c.length < 2) {
var cc = c.charCodeAt(0);
return cc < 128
? c
: cc < 2048
? fromCharCode(192 | (cc >>> 6)) + fromCharCode(128 | (cc & 63))
: fromCharCode(224 | ((cc >>> 12) & 15)) +
fromCharCode(128 | ((cc >>> 6) & 63)) +
fromCharCode(128 | (cc & 63));
} else {
var cc = 65536 + (c.charCodeAt(0) - 55296) * 1024 + (c.charCodeAt(1) - 56320);
return (
fromCharCode(240 | ((cc >>> 18) & 7)) +
fromCharCode(128 | ((cc >>> 12) & 63)) +
fromCharCode(128 | ((cc >>> 6) & 63)) +
fromCharCode(128 | (cc & 63))
);
}
};
var re_utob = /[\uD800-\uDBFF][\uDC00-\uDFFFF]|[^\x00-\x7F]/g;
var utob = function (u) {
return u.replace(re_utob, cb_utob);
};
var cb_encode = function (ccc) {
var padlen = [0, 2, 1][ccc.length % 3],
ord =
(ccc.charCodeAt(0) << 16) |
((ccc.length > 1 ? ccc.charCodeAt(1) : 0) << 8) |
(ccc.length > 2 ? ccc.charCodeAt(2) : 0),
chars = [
b64chars.charAt(ord >>> 18),
b64chars.charAt((ord >>> 12) & 63),
padlen >= 2 ? '=' : b64chars.charAt((ord >>> 6) & 63),
padlen >= 1 ? '=' : b64chars.charAt(ord & 63),
];
return chars.join('');
};
var btoa =
global.btoa && typeof global.btoa == 'function'
? function (b) {
return global.btoa(b);
}
: function (b) {
if (b.match(/[^\x00-\xFF]/)) {
throw new RangeError('The string contains invalid characters.');
}
return b.replace(/[\s\S]{1,3}/g, cb_encode);
};
var _encode = function (u) {
return btoa(utob(String(u)));
};
var mkUriSafe = function (b64) {
return b64
.replace(/[+\/]/g, function (m0) {
return m0 == '+' ? '-' : '_';
})
.replace(/=/g, '');
};
var encode = function (u, urisafe) {
return urisafe ? mkUriSafe(_encode(u)) : _encode(u);
};
var encodeURI = function (u) {
return encode(u, true);
};
var fromUint8Array;
if (global.Uint8Array) {
fromUint8Array = function (a, urisafe) {
var b64 = '';
for (var i = 0, l = a.length; i < l; i += 3) {
var a0 = a[i],
a1 = a[i + 1],
a2 = a[i + 2];
var ord = (a0 << 16) | (a1 << 8) | a2;
b64 +=
b64chars.charAt(ord >>> 18) +
b64chars.charAt((ord >>> 12) & 63) +
(typeof a1 != 'undefined' ? b64chars.charAt((ord >>> 6) & 63) : '=') +
(typeof a2 != 'undefined' ? b64chars.charAt(ord & 63) : '=');
}
return urisafe ? mkUriSafe(b64) : b64;
};
}
var re_btou = /[\xC0-\xDF][\x80-\xBF]|[\xE0-\xEF][\x80-\xBF]{2}|[\xF0-\xF7][\x80-\xBF]{3}/g;
var cb_btou = function (cccc) {
switch (cccc.length) {
case 4:
var cp =
((7 & cccc.charCodeAt(0)) << 18) |
((63 & cccc.charCodeAt(1)) << 12) |
((63 & cccc.charCodeAt(2)) << 6) |
(63 & cccc.charCodeAt(3)),
offset = cp - 65536;
return fromCharCode((offset >>> 10) + 55296) + fromCharCode((offset & 1023) + 56320);
case 3:
return fromCharCode(
((15 & cccc.charCodeAt(0)) << 12) |
((63 & cccc.charCodeAt(1)) << 6) |
(63 & cccc.charCodeAt(2)),
);
default:
return fromCharCode(((31 & cccc.charCodeAt(0)) << 6) | (63 & cccc.charCodeAt(1)));
}
};
var btou = function (b) {
return b.replace(re_btou, cb_btou);
};
var cb_decode = function (cccc) {
var len = cccc.length,
padlen = len % 4,
n =
(len > 0 ? b64tab[cccc.charAt(0)] << 18 : 0) |
(len > 1 ? b64tab[cccc.charAt(1)] << 12 : 0) |
(len > 2 ? b64tab[cccc.charAt(2)] << 6 : 0) |
(len > 3 ? b64tab[cccc.charAt(3)] : 0),
chars = [fromCharCode(n >>> 16), fromCharCode((n >>> 8) & 255), fromCharCode(n & 255)];
chars.length -= [0, 0, 2, 1][padlen];
return chars.join('');
};
var _atob =
global.atob && typeof global.atob == 'function'
? function (a) {
return global.atob(a);
}
: function (a) {
return a.replace(/\S{1,4}/g, cb_decode);
};
var atob = function (a) {
return _atob(String(a).replace(/[^A-Za-z0-9\+\/]/g, ''));
};
var _decode = function (a) {
return btou(_atob(a));
};
var _fromURI = function (a) {
return String(a)
.replace(/[-_]/g, function (m0) {
return m0 == '-' ? '+' : '/';
})
.replace(/[^A-Za-z0-9\+\/]/g, '');
};
var decode = function (a) {
return _decode(_fromURI(a));
};
var toUint8Array;
if (global.Uint8Array) {
toUint8Array = function (a) {
return Uint8Array.from(atob(_fromURI(a)), function (c) {
return c.charCodeAt(0);
});
};
}
var noConflict = function () {
var Base64 = global.Base64;
global.Base64 = _Base64;
return Base64;
};
global.Base64 = {
VERSION: version,
atob: atob,
btoa: btoa,
fromBase64: decode,
toBase64: encode,
utob: utob,
encode: encode,
encodeURI: encodeURI,
btou: btou,
decode: decode,
noConflict: noConflict,
fromUint8Array: fromUint8Array,
toUint8Array: toUint8Array,
};
if (typeof Object.defineProperty === 'function') {
var noEnum = function (v) {
return { value: v, enumerable: false, writable: true, configurable: true };
};
global.Base64.extendString = function () {
Object.defineProperty(
String.prototype,
'fromBase64',
noEnum(function () {
return decode(this);
}),
);
Object.defineProperty(
String.prototype,
'toBase64',
noEnum(function (urisafe) {
return encode(this, urisafe);
}),
);
Object.defineProperty(
String.prototype,
'toBase64URI',
noEnum(function () {
return encode(this, true);
}),
);
};
}
if (global['Meteor']) {
Base64 = global.Base64;
}
if (typeof module !== 'undefined' && module.exports) {
module.exports.Base64 = global.Base64;
} else {
if (typeof define === 'function' && define.amd) {
define([], function () {
return global.Base64;
});
}
}
return { Base64: global.Base64 };
},
);

99
src/views/ProcessApprovalSubPage/component/ApprovalPageModel.vue

@ -1,45 +1,70 @@
<template>
<BasicModal v-bind="$attrs" @register="registerModal" width="1200px" :showOkBtn="false" :title="processName">
<initiatesProjectsApproval :record="record" @close="exit" v-if="record.stage=='creatProjectinfo'"/>
<uploadfileApproval :record="record" @close="exit" v-if="record.stage=='supervisionFile'"/>
<projectPlanApproval :record="record" @close="exit" v-if="record.stage=='createPlaninfo'"/>
<planFileApproval :record="record" @close="exit" v-if="planfileNames.includes(record.stage)"/>
<fieldChangeApproval :record="record" @close="exit" v-if="record.stage=='fieldChange'"/>
<contractApproval :record="record" @close="exit" v-if="record.stage=='createContract'"/>
<uploadURTfileApproval :record="record" @close="exit" v-if="record.stage=='createURT'||record.stage=='createURT2'"/>
<MergeProjectApprova :record="record" @close="exit" v-if="record.stage=='MergeProject'"/>
<SplitProjectApprova :record="record" @close="exit" v-if="record.stage=='SplitProject'"/>
</BasicModal>
<BasicModal
v-bind="$attrs"
@register="registerModal"
width="1200px"
:showOkBtn="false"
:title="processName"
>
<initiatesProjectsApproval
:record="record"
@close="exit"
v-if="record.stage == 'creatProjectinfo'"
/>
<uploadfileApproval :record="record" @close="exit" v-if="record.stage == 'supervisionFile'" />
<projectPlanApproval :record="record" @close="exit" v-if="record.stage == 'createPlaninfo'" />
<planFileApproval :record="record" @close="exit" v-if="planfileNames.includes(record.stage)" />
<fieldChangeApproval :record="record" @close="exit" v-if="record.stage == 'fieldChange'" />
<contractApproval :record="record" @close="exit" v-if="record.stage == 'createContract'" />
<uploadURTfileApproval
:record="record"
@close="exit"
v-if="record.stage == 'createURT' || record.stage == 'createURT2'"
/>
<MergeProjectApprova :record="record" @close="exit" v-if="record.stage == 'MergeProject'" />
<SplitProjectApprova :record="record" @close="exit" v-if="record.stage == 'SplitProject'" />
</BasicModal>
</template>
<script lang="ts" name="ApprovalPageModel" setup>
import {ref} from "vue"
import { BasicModal, useModalInner } from '@/components/Modal';
import { ref } from 'vue';
import { BasicModal, useModalInner } from '@/components/Modal';
import initiatesProjectsApproval from "../initiatesProjectsApproval.vue"
import planFileApproval from '@/views/ProcessApprovalSubPage/planFileApproval.vue'
import uploadfileApproval from '../uploadfileApproval.vue'
import projectPlanApproval from '../projectPlanApproval.vue'
import fieldChangeApproval from '../fieldChangeApproval.vue'
import contractApproval from '../contractApproval.vue'
import uploadURTfileApproval from '../uploadURTfileApproval.vue'
import MergeProjectApprova from '../MergeProjectApprova.vue'
import SplitProjectApprova from '../SplitProjectApprova.vue'
import initiatesProjectsApproval from '../initiatesProjectsApproval.vue';
import planFileApproval from '@/views/ProcessApprovalSubPage/planFileApproval.vue';
import uploadfileApproval from '../uploadfileApproval.vue';
import projectPlanApproval from '../projectPlanApproval.vue';
import fieldChangeApproval from '../fieldChangeApproval.vue';
import contractApproval from '../contractApproval.vue';
import uploadURTfileApproval from '../uploadURTfileApproval.vue';
import MergeProjectApprova from '../MergeProjectApprova.vue';
import SplitProjectApprova from '../SplitProjectApprova.vue';
const planfileNames = ["projectApprovalStage","feasibilityTechReviewConfirm","finalFeasibilityReportDraft","centralizedCheck","createPlaninfoFile","bidDocumentsPreparation","costEvalReportConfirm"]
const [registerModal, { closeModal }] = useModalInner(init);
defineProps(["record"])
let processName= ref()
let emit = defineEmits(["close"])
function exit(){
closeModal()
console.log("ApprovalPageModel")
emit("close")
}
function init(initData){
processName.value=initData.record.processName
}
const planfileNames = [
'projectApprovalStage',
'feasibilityTechReviewConfirm',
'finalFeasibilityReportDraft',
'centralizedCheck',
'createPlaninfoFile',
'bidDocumentsPreparation',
'costEvalReportConfirm',
"chuBuSheJiShenPi",
"zhongYanJieDuan",
"chuYanJieDuan",
"shouFuZhiFu",
"heTongQianDing"
];
const [registerModal, { closeModal }] = useModalInner(init);
defineProps(['record']);
let processName = ref();
let emit = defineEmits(['close']);
function exit() {
closeModal();
console.log('ApprovalPageModel');
emit('close');
}
function init(initData) {
processName.value = initData.record.processName;
}
</script>
<style></style>

19
src/views/ProcessApprovalSubPage/component/PlanFileDetail.vue

@ -15,7 +15,7 @@ import { BasicTable, ActionItem, TableAction, useTable } from '@/components/Tabl
import { PlaninfoFiletableColumns } from '@/views/projectLib/projectPlan/projectPlan.data';
import { planFilePageList ,getplaninfoByid } from '@/views/projectLib/projectPlan/projectPlan.api'
import { BasicColumn } from '@/components/Table';
import { downloadFile,downloadResource } from "@/api/common/api"
import { downloadFile,downloadResource,downloadonlinePreview } from "@/api/common/api"
let dataTo = defineProps(["stage", "planinfoid"])
//
@ -51,9 +51,26 @@ function getTableAction(record): ActionItem[] {
label: '下载',
ifShow: true,
onClick: handleDetailpage.bind(null, record),
},
{
label: '预览',
ifShow: true,
onClick: handlePreview.bind(null, record),
}
];
}
function handlePreview(record) {
console.log("我这一行的数据是", record)
let param = {
path: record.documentPath,
fileName: record.documentName
}
//
console.log("我这一行的数据是", param)
// downloadFile("/huzhouUploadfileinfo/downloadfile", record.documentName, param)
downloadonlinePreview("/huzhouUploadfileinfo/downloadfile", record.documentName,param)
}
function handleDetailpage(record) {
console.log("我这一行的数据是", record)
let param = {

29
src/views/ProcessApprovalSubPage/planFileApproval.vue

@ -1,5 +1,6 @@
<template>
<!-- 自定义表单 -->
<el-divider content-position="left">项目阶段名称 {{ stageName }}<a-button type="link" @click="hdDetail">详情</a-button></el-divider>
<el-divider content-position="left">项目名称 {{ dataTo.record.projectName }} </el-divider>
<BasicForm @register="registerApprovalMoneyForm" v-if="taskName == '立项审批'" />
<BasicForm @register="registerContractMoneyForm" v-if="taskName == '合同签订'" />
@ -71,9 +72,14 @@
</div>
</div>
</ApprovalFromPage>
<BasicModal @register="registerProjectPlan" title="发起项目计划审批" width="1200px" :showOkBtn="false"
:showCancelBtn="false">
<showtu :res="showtuList" />
</BasicModal>
</template>
<script lang="ts" name="planFileApproval" setup>
import { onMounted, ref, reactive } from 'vue';
import { onMounted, ref, reactive, h } from 'vue';
import { useModal, BasicModal } from '@/components/Modal';
import { BasicTable, ActionItem, TableAction, useTable } from '@/components/Table';
import { approvePlanFile, getActionParam } from '../myWork/inComplete/inComplete.api';
import {
@ -90,13 +96,15 @@
import ApprovalFromPage from '../ProcessApprovalSubPage/component/ApprovalFromPage.vue';
import PlanFileDetail from '@/views/ProcessApprovalSubPage/component/PlanFileDetail.vue';
import { queryProjectInfoById } from '@/views/projectLib/projectInfo/projectInfo.api';
import showtu from "@/views/projectLib/projectPlan/showtu.vue"
import { useForm, BasicForm } from '@/components/Form';
import { getProjectinfoMoneyInfo } from '@/views/projectLib/projectPlan/projectPlan.api';
import { getProjectinfoMoneyInfo,queryPlanInfoMainTimeline } from '@/views/projectLib/projectPlan/projectPlan.api';
import {
ApprovalMoneyFormSchemas,
ContractMoneyFormSchemas,
} from '@/views/projectLib/projectPlan/projectPlan.data';
const [registerProjectPlan, { openModal: openProjectPlan}] = useModal();//
const [
registerApprovalMoneyForm,
{
@ -159,6 +167,8 @@
let ApprovalFromPageRef = ref();
let tableDataFiles = ref();
let planFileDetailKey = ref(0);
let stageName = ref('');
let showtuList = ref<Array<Object>>()
let resButton = reactive({
showApprovalForm: false,
isEdit: false,
@ -176,6 +186,16 @@
});
showApprovalForm.value = resButton.showApprovalForm;
planFileDetailKey.value+=1
let resList = await getplaninfoByid({ planinfoid: planinfoid });
let taskLevel = resList[0].taskLevel.split(".")[0]
console.log('taskLevel', taskLevel,resList);
let res2 = await queryPlanInfoMainTimeline({projectid: resList[0].projectId})
for(let i=0;i<res2.length;i++){
if(res2[i].taskLevel == taskLevel){
stageName.value = res2[i].taskName
}
}
showtuList.value =res2
});
const [registerplaninfoTable, { getDataSource }] = useTable({
@ -237,6 +257,9 @@
params.stage = '1';
},
});
function hdDetail(){
openProjectPlan()
}
function getTableAction(record): ActionItem[] {
return [
{

21
src/views/ProcessApprovalSubPage/uploadURTfileApproval.vue

@ -1,5 +1,6 @@
<template>
<div>
<el-divider content-position="left">项目阶段名称 {{ stageName }} </el-divider>
<el-divider content-position="left">项目名称 {{ dataTo.record.projectName }} </el-divider>
<BasicForm @register="registerMoneyForm" />
<el-divider content-position="left">联合技术审查文件详情</el-divider>
@ -68,7 +69,7 @@
import PlanFileDetail from '@/views/ProcessApprovalSubPage/component/PlanFileDetail.vue';
import { EstimateAmountFormSchemas } from '@/views/projectLib/projectPlan/projectPlan.data';
import { queryProjectInfoById } from '@/views/projectLib/projectInfo/projectInfo.api';
import { getplaninfoByid } from '@/views/projectLib/projectPlan/projectPlan.api';
import { getplaninfoByid,queryPlanInfoMainTimeline } from '@/views/projectLib/projectPlan/projectPlan.api';
import { useForm, BasicForm } from '@/components/Form';
import { message } from 'ant-design-vue';
@ -78,6 +79,7 @@
let processInstanceId = dataTo.record.processInstanceId;
let taskid = dataTo.record.taskId as string;
let procesType = dataTo.record.procesType;
let planFileDetailKey = ref(0);
const emit = defineEmits(['close']);
let showApprovalForm = ref();
@ -87,6 +89,8 @@
isEdit: false,
buttons: [],
});
//
let stageName = ref('');
let fileList = reactive<Array<any>>([]);
let fileAdviceList = reactive<Array<any>>([]);
const [
@ -125,6 +129,15 @@
setMoneyFieldsValue(res);
setProps({ disabled: resButton.isEdit == true ? false : true });
planFileDetailKey.value += 1;
let taskLevel = resList[0].taskLevel.split(".")[0]
console.log('taskLevel', taskLevel,resList);
//
let res2 = await queryPlanInfoMainTimeline({projectid: resList[0].projectId})
for(let i=0;i<res2.length;i++){
if(res2[i].taskLevel == taskLevel){
stageName.value = res2[i].taskName
}
}
});
function removeFile(option) {
@ -191,6 +204,12 @@
fileList.forEach((x) => {
params.append('file', x.file);
});
}else{
if(dataTo.record.taskName=="发起人"){
message.error('请上传文件');
return;
}
}
if (fileAdviceList.length > 0) {
fileAdviceList.forEach((x) => {

5
src/views/Regulation/RegulationLab/index.vue

@ -22,7 +22,7 @@
import { ref } from 'vue';
import { ActionItem, BasicTable, TableAction, useTable } from '@/components/Table';
import { useModal, BasicModal } from '@/components/Modal';
import { downloadFile } from "../../../api/common/api"
import { downloadResource } from "../../../api/common/api"
import { isShowByRoles } from '@/views/projectLib/projectInfo/projectInfo.api';
import { RegulationLabcolumns, searchFormSchema } from './RegulationLab.data';
@ -92,8 +92,9 @@ function handleSubmit(record) {
function handledown(record) {
let param = {
path: record.documentPath,
fileName: record.documentName
}
downloadFile("/huzhouUploadfileinfo/downloadfile", record.documentName, param)
downloadResource("/huzhouUploadfileinfo/downloadfile", record.documentName, param)
}
async function handleDelete(record) {

2
src/views/dashboard/workbench/components/basic_bar.vue

@ -40,7 +40,7 @@ option = {
show: true,
position: 'right', //
formatter: function (params) {
const total = option.series[0].data[params.dataIndex] + option.series[1].data[params.dataIndex];
const total = option.series[2].data[params.dataIndex] + option.series[1].data[params.dataIndex];
return total; //
},
color:"black"

36
src/views/dashboard/workbench/components/projectDetail.vue

@ -33,11 +33,31 @@
<div class="flex items-center gap-1 w-full h-full">
<div class="w-1/28 bg-[#91ACE0] h-full"></div>
<div class="w-17/28 flex items-center justify-center h-full text-2xl font-semibold"
>配套项目数量</div
>未入库项目数量</div
>
<div class="w-10/28 flex items-center justify-center h-full text-4xl font-bold">{{
<!-- <div class="w-10/28 flex items-center justify-center h-full text-4xl font-bold">{{
supportingNumber.total
}}</div>
}}</div> -->
<div class="flex flex-col">
<div class="text-center">
<div class="text-2xl font-bold">{{supportingNumber.total}}</div>
</div>
<div class="text-center">
<div class="text-1xl ">配套项目</div>
</div>
</div>
<div class="flex flex-col">
<div class="text-center">
<div class="text-2xl font-bold">{{ stopNumber.total }}</div>
<div class="text-center">
<div class="text-1xl ">已停止项目</div>
</div>
</div>
</div>
</div>
</div></div
>
@ -66,6 +86,7 @@
getProjectNumber,
getStoragedNumber,
getSupportingNumber,
getStopNumber,
getStoragedFound,
getSupportingFound,
} from '@/views/projectSummary/planSummary/planSummary.api';
@ -94,6 +115,11 @@ import { number } from 'vue-types';
countyNum: 0,
total: 0,
});
let stopNumber = ref({
cityNum: 0,
countyNum: 0,
total: 0,
});
getProjectNumber().then((res) => {
console.log('getProjectNumber', res);
projectNumber.value = res;
@ -106,6 +132,10 @@ import { number } from 'vue-types';
console.log('getSupportingNumber', res);
supportingNumber.value = res;
});
getStopNumber().then((res) => {
console.log('getStopNumber', res);
stopNumber.value = res;
});
onMounted(async()=>{
let storData=await getStoragedFound();
let supData=await getSupportingFound();

128
src/views/dashboard/workbench/index.vue

@ -7,72 +7,80 @@
<ProjectCard :loading="loading" class="enter-y" />
<!-- <DynamicInfo :loading="loading" class="!my-4 enter-y" /> -->
</div>
<div class="card-container" v-if="true">
<!-- <projectDetail></projectDetail> -->
<div v-if="isShowByRoles('中医处,妇幼处,医政处,财审处,体改处,组织人事处,机关党委,规信处')">
<div class="card-container">
<projectDetail></projectDetail>
</div>
<div>
<planSummary />
</div>
</div>
<div>
<planSummary />
<div class="card-container" v-else>
<planSummary1></planSummary1>
</div>
</PageWrapper>
</template>
<script lang="ts" setup>
import { ref, reactive, onMounted } from 'vue';
import { PageWrapper } from '@/components/Page';
import { count } from '@/views/projectLib/projectInfo/projectInfo.api';
import WorkbenchHeader from './components/WorkbenchHeader.vue';
import ProjectCard from './components/ProjectCard.vue';
import projectDetail from './components/projectDetail.vue'
import planSummary from '@/views/projectSummary/planSummary/indeForDashboard.vue';
import { ref, reactive, onMounted } from 'vue';
import { PageWrapper } from '@/components/Page';
import { count } from '@/views/projectLib/projectInfo/projectInfo.api';
import WorkbenchHeader from './components/WorkbenchHeader.vue';
import ProjectCard from './components/ProjectCard.vue';
// import projectDetail1 from './components/projectDetail.vue'
import planSummary1 from '@/views/projectSummary/planSummary/indeForDashboard.vue';
import projectDetail from '@/views/dashboard/workbench/components/projectDetail.vue';
import planSummary from '@/views/projectSummary/planSummary/shouyeindex.vue';
import { isShowByRoles } from '@/views/projectLib/projectInfo/projectInfo.api';
const loading = ref(true);
const activeKey = ref('0');
let data = reactive({
xiangmZJD: {
fininshNum: 1,
unfininshNum: 2,
},
xiangmuZJ: {
fininshNum: 1,
unfininshNum: 2,
},
xiangmuZT: [{ name: '已建', value: 100 }],
ssggrw: [
{ name: '2+N紧密型城市医疗集团建设', fininshNum: 100, unfininshNum: 30 },
{ name: '2+9+9+N县域医共体建设', fininshNum: 140, unfininshNum: 20 },
{ name: '市县公立医院妇幼能力建设', fininshNum: 140, unfininshNum: 120 },
{ name: '高水平县级医院建设 ', fininshNum: 140, unfininshNum: 90 },
{ name: '打造长三角市域医学高地', fininshNum: 140, unfininshNum: 90 },
{ name: '公立医院院前急救与院内救治服务融合发展', fininshNum: 170, unfininshNum: 90 },
{ name: '医共体下三医联动改革', fininshNum: 170, unfininshNum: 90 },
{ name: '智慧医院服务能力提档升级', fininshNum: 100, unfininshNum: 30 },
{ name: '数字健康大脑建设', fininshNum: 140, unfininshNum: 270 },
{ name: '舒心就医', fininshNum: 140, unfininshNum: 270 },
{ name: '中医药固本培元', fininshNum: 140, unfininshNum: 210 },
{ name: '公立医院运营管理', fininshNum: 140, unfininshNum: 80 },
{ name: '公立医院党建全行业引领改革工程 ', fininshNum: 140, unfininshNum: 40 },
{ name: '高质量临床重点专科建设 ', fininshNum: 140, unfininshNum: 80 },
],
xxqy: [
{ name: '南浔区', fininshNum: 100, unfininshNum: 30 },
{ name: '吴兴区', fininshNum: 140, unfininshNum: 20 },
{ name: '市本级', fininshNum: 140, unfininshNum: 120 },
{ name: '安吉县', fininshNum: 140, unfininshNum: 90 },
{ name: '德清县', fininshNum: 140, unfininshNum: 90 },
{ name: '长兴县', fininshNum: 170, unfininshNum: 90 },
],
dwsx: [
{ name: '卫生行政部门', fininshNum: 1000, unfininshNum: 3000 },
{ name: '医疗机构 ', fininshNum: 1400, unfininshNum: 2000 },
],
});
const loading = ref(true);
const activeKey = ref('0');
let data = reactive({
xiangmZJD: {
fininshNum: 1,
unfininshNum: 2,
},
xiangmuZJ: {
fininshNum: 1,
unfininshNum: 2,
},
xiangmuZT: [{ name: '已建', value: 100 }],
ssggrw: [
{ name: '2+N紧密型城市医疗集团建设', fininshNum: 100, unfininshNum: 30 },
{ name: '2+9+9+N县域医共体建设', fininshNum: 140, unfininshNum: 20 },
{ name: '市县公立医院妇幼能力建设', fininshNum: 140, unfininshNum: 120 },
{ name: '高水平县级医院建设 ', fininshNum: 140, unfininshNum: 90 },
{ name: '打造长三角市域医学高地', fininshNum: 140, unfininshNum: 90 },
{ name: '公立医院院前急救与院内救治服务融合发展', fininshNum: 170, unfininshNum: 90 },
{ name: '医共体下三医联动改革', fininshNum: 170, unfininshNum: 90 },
{ name: '智慧医院服务能力提档升级', fininshNum: 100, unfininshNum: 30 },
{ name: '数字健康大脑建设', fininshNum: 140, unfininshNum: 270 },
{ name: '舒心就医', fininshNum: 140, unfininshNum: 270 },
{ name: '中医药固本培元', fininshNum: 140, unfininshNum: 210 },
{ name: '公立医院运营管理', fininshNum: 140, unfininshNum: 80 },
{ name: '公立医院党建全行业引领改革工程 ', fininshNum: 140, unfininshNum: 40 },
{ name: '高质量临床重点专科建设 ', fininshNum: 140, unfininshNum: 80 },
],
xxqy: [
{ name: '南浔区', fininshNum: 100, unfininshNum: 30 },
{ name: '吴兴区', fininshNum: 140, unfininshNum: 20 },
{ name: '市本级', fininshNum: 140, unfininshNum: 120 },
{ name: '安吉县', fininshNum: 140, unfininshNum: 90 },
{ name: '德清县', fininshNum: 140, unfininshNum: 90 },
{ name: '长兴县', fininshNum: 170, unfininshNum: 90 },
],
dwsx: [
{ name: '卫生行政部门', fininshNum: 1000, unfininshNum: 3000 },
{ name: '医疗机构 ', fininshNum: 1400, unfininshNum: 2000 },
],
});
onMounted(() => {
console.log('datadatadatadatadatadata', data);
});
setTimeout(async () => {
data = await count();
loading.value = false;
activeKey.value = '1';
}, 10);
onMounted(() => {
console.log('datadatadatadatadatadata', data);
});
setTimeout(async () => {
data = await count();
loading.value = false;
activeKey.value = '1';
}, 10);
</script>

6
src/views/informationSub/monthlyJournal/index.vue

@ -21,12 +21,13 @@
import { ref } from 'vue';
import { ActionItem, BasicTable, TableAction, useTable } from '@/components/Table';
import { useModal } from '@/components/Modal';
import { downloadFile } from "../../../api/common/api"
import { downloadResource } from "../../../api/common/api"
import { isShowByRoles } from '@/views/projectLib/projectInfo/projectInfo.api';
import { monthlyJournalcolumns, searchFormSchema } from './monthlyJournal.data';
import addAndModify from "./addAndModify.vue"
import { periodicallabPageList, batchdownloadPeriodicallabFiles, deletePeriodicallab } from './monthlyJournal.api';
import { fi } from 'element-plus/es/locale';
const [registerSubmitProjectArchive, { openModal }] = useModal();
const [registerTable, { reload, getForm }] = useTable({
title: '月度期刊信息',
@ -91,8 +92,9 @@ function handleSubmit(record) {
function handledown(record) {
let param = {
path: record.documentPath,
fileName: record.documentName
}
downloadFile("/huzhouUploadfileinfo/downloadfile", record.documentName, param)
downloadResource("/huzhouUploadfileinfo/downloadfile", record.documentName, param)
}
async function handleDelete(record) {

2
src/views/myWork/inComplete/inComplete.api.ts

@ -33,7 +33,7 @@ export const approveUploadFile = (params) => defHttp.post({ url: Api.approveUplo
export const modifyProjectInfo = (params) => defHttp.post({ url: Api.modifyProjectInfo, params })
export const approvePlanFile = (params) => defHttp.post({ url: Api.approvePlanFile, headers: { "Content-Type": "multipart/form-data" }, params })
export const approveURTFile = (params) => defHttp.post({ url: Api.approveURTFile, headers: { "Content-Type": "multipart/form-data" }, params })
export const approveURTFile = (params) => defHttp.post({ url: Api.approveURTFile, headers: { "Content-Type": "multipart/form-data" }, params,timeout:10*60*1000 })
export const approvalMergeProject = (params) => defHttp.post({ url: Api.approvalMergeProject, headers: { "Content-Type": "multipart/form-data" }, params })
export const approvalSplitProject = (params) => defHttp.post({ url: Api.approvalSplitProject, headers: { "Content-Type": "multipart/form-data" }, params })

6
src/views/projectBoard/liangShaiKanBan/liangShaiKanBan.data.ts

@ -31,7 +31,7 @@ export const huizongcolumns: BasicColumn[] = [
resizable: true,
},
{
title: '项目总数',
title: '入库项目总数',
dataIndex: 'projectNum',
},
{
@ -62,6 +62,10 @@ export const huizongcolumns: BasicColumn[] = [
title: '项目验收阶段数量',
dataIndex: 'acceptanceNum',
},
{
title: '未入库项目数量',
dataIndex: 'closeNum',
},
];
export const liangshaicolumns: BasicColumn[] = [

4
src/views/projectBoard/urt/qingkuang/index.vue

@ -30,7 +30,7 @@
import { getSuperLeaderApproveInfo, getURTUnApprovedDaysPage } from './qingkuang.api';
const activeKey = ref('1');
const [registerTable, { reload }] = useTable({
title: '详情',
title: '各上级指导处室未审批流程总数',
api: getSuperLeaderApproveInfo,
columns: qingkuangcolumns,
useSearchForm: false,
@ -40,7 +40,7 @@
// }
});
const [registerURTTable, { reload: urtreload }] = useTable({
title: '详情',
title: '七部门未审批流程总数',
api: getURTUnApprovedDaysPage,
columns: qingkuangUrtcolumns,
useSearchForm: false,

32
src/views/projectBoard/urt/qingkuang/qingkuang.data.ts

@ -27,18 +27,18 @@ export const qingkuangcolumns: BasicColumn[] = [
title: '未审批流程数',
dataIndex: 'unapprovedCount',
},
{
title: '2天未审批流程数',
dataIndex: 'unapprovedCount2d',
},
// {
// title: '2天未审批流程数',
// dataIndex: 'unapprovedCount2d',
// },
{
title: '3天未审批流程数',
dataIndex: 'unapprovedCount3d',
},
{
title: '5天未审批流程数',
dataIndex: 'unapprovedCount5d',
},
// {
// title: '5天未审批流程数',
// dataIndex: 'unapprovedCount5d',
// },
{
title: '超过5天未审批流程数',
dataIndex: 'unapprovedCountOver5d',
@ -65,18 +65,18 @@ export const qingkuangUrtcolumns: BasicColumn[] = [
title: '未审批流程数',
dataIndex: 'unapprovedCount',
},
{
title: '2天未审批流程数',
dataIndex: 'unapprovedCount2d',
},
// {
// title: '2天未审批流程数',
// dataIndex: 'unapprovedCount2d',
// },
{
title: '3天未审批流程数',
dataIndex: 'unapprovedCount3d',
},
{
title: '5天未审批流程数',
dataIndex: 'unapprovedCount5d',
},
// {
// title: '5天未审批流程数',
// dataIndex: 'unapprovedCount5d',
// },
{
title: '超过5天未审批流程数',
dataIndex: 'unapprovedCountOver5d',

65
src/views/projectBoard/urt/urt/index.vue

@ -1,11 +1,53 @@
<template>
<div>
<!--引用表格-->
<BasicTable @register="registerTable">
<BasicTable @register="registerTable" @fetch-success="fetchSuccess">
<template #action="{ record }">
<!-- <TableAction :actions="getTableAction(record)" /> -->
<TableAction :actions="getTableAction(record)"/>
</template>
<template #headerTop>
<div class="container mx-auto mt-4 mb-4 h-20">
<div class="grid grid-cols-4 gap-4 h-full">
<div class="bg-[#1890FF] opacity-100 h-full">
<div class="grid grid-cols-4 gap-1 h-full">
<div class="col-span-3 mt-4 ml-4 text-white">项目数量</div>
<div
class="col-span-1 flex justify-center items-center text-white text-4xl font-bold "
>{{ summary.totalNum }}</div
>
</div>
</div>
<div class="bg-[#1890FF] opacity-90 h-full">
<div class="grid grid-cols-4 gap-1 h-full">
<div class="col-span-3 mt-4 ml-4 text-white">未开始项目数量</div>
<div
class="col-span-1 flex justify-center items-center text-white text-4xl font-bold mr-20"
>{{summary.unfinishedNum }}</div
>
</div>
</div>
<div class="bg-[#1890FF] opacity-85 h-full">
<div class="grid grid-cols-5 gap-1 h-full">
<div class="col-span-2 mt-4 ml-4 text-white">审批中项目数量</div>
<div
class="col-span-2 flex justify-center items-center text-white text-4xl font-bold"
>{{ summary.approvalNum }}</div
>
</div>
</div>
<div class="bg-[#1890FF] opacity-80 h-full">
<div class="grid grid-cols-5 gap-1 h-full">
<div class="col-span-2 mt-4 ml-4 text-white">已完成项目数量</div>
<div
class="col-span-2 flex justify-center items-center text-white text-4xl font-bold "
>{{ summary.finishedNum }}</div
>
</div>
</div>
</div>
</div>
</template>
</BasicTable>
<planinfoFileDetail @register="registerFileInfo" />
@ -17,12 +59,16 @@
import { ref } from 'vue';
import { ActionItem, BasicTable, TableAction, useTable } from '@/components/Table';
import { useModal, BasicModal } from '@/components/Modal';
import { urtgcolumns, urtFormSchema } from './urt.data';
import { getURTProcessPage } from './urt.api';
import { getURTProcessPage,getUrtTaskStatusNum } from './urt.api';
const [registerFileInfo, { openModal: openFileInfo }] = useModal(); //
import planinfoFileDetail from '@/views/projectLib/projectPlan/planinfoFileDetail.vue';
let summary = ref<any>({
totalNum: '',
unfinishedNum: '',
finishedNum: '',
approvalNum: '',
});
const [registerTable, { reload, getForm }] = useTable({
title: '详情',
api: getURTProcessPage,
@ -80,13 +126,10 @@ function handleDetail(record) {
// ];
// }
function handleAdd() {
openModal(true, { id: null })
}
function handleModify(record) {
openModal(true, { id: record.id })
}
async function fetchSuccess() {
let formdata = await getForm().getFieldsValue();
summary.value = await getUrtTaskStatusNum(formdata);
}
function handleSubmit(record) {

4
src/views/projectBoard/urt/urt/urt.api.ts

@ -8,12 +8,16 @@ export enum Api {
getDimensionPageSorted= "/huzhouProject/getDimensionPageSorted",
getPageSorted = "/huzhouProject/getPageSorted",
getUrtTaskStatusNum = "/huzhouProject/getUrtTaskStatusNum",
}
/**
*
*/
export const getURTProcessPage = (params?) => defHttp.get({ url: Api.getURTProcessPage,params})
export const getUrtTaskStatusNum = (params?) => defHttp.get({ url: Api.getUrtTaskStatusNum,params})
// export const showCountBoardByAdminDivision = (params?) => defHttp.get({ url: Api.showCountBoardByAdminDivision,params})
// export const getDimensionPageSorted = (params) => defHttp.get({ url: Api.getDimensionPageSorted,params })
// export const getPageSorted = (params) => defHttp.get({ url: Api.getPageSorted,params })

133
src/views/projectBoard/urt/urt/urt.data.ts

@ -1,6 +1,22 @@
import { FormSchema } from '@/components/Form';
import { BasicColumn } from '@/components/Table';
import { getDutyWorkplaceList } from '@/views/informationSub/countStatistics/countStatistics.api';
async function getDutyWorkplaceOptions() {
const dutyWorkplaceOption = await getDutyWorkplaceList();
const uniqueList = [...new Set(dutyWorkplaceOption)];
const res = uniqueList.map((item) => {
return {
label: item,
value: item,
};
});
console.log('wwres', res);
return res;
}
export const urtgcolumns: BasicColumn[] = [
{
title: '项目名称',
@ -12,43 +28,51 @@ export const urtgcolumns: BasicColumn[] = [
title: '市卫生健康委',
dataIndex: 'shwjk',
ellipsis: false,
format: 'dict|approvalResult',
// filters: 'dict|approvalResult',
},
{
title: '市财政局',
dataIndex: 'sczj',
ellipsis: false,
format: 'dict|approvalResult',
// filters: 'dict|approvalResult',
},
{
title: '市发展改革委',
dataIndex: 'sfzgw',
ellipsis: false,
format: 'dict|approvalResult',
// filters: 'dict|approvalResult',
},
{
title: '市数据局',
dataIndex: 'ssjj',
ellipsis: false,
format: 'dict|approvalResult',
// filters: 'dict|approvalResult',
},
{
title: '市委网信办',
dataIndex: 'swxb',
ellipsis: false,
format: 'dict|approvalResult',
// filters: 'dict|approvalResult',
},
{
title: '市密码管理局',
dataIndex: 'smmglj',
ellipsis: false,
format: 'dict|approvalResult',
// filters: 'dict|approvalResult',
},
{
title: '市公安局',
dataIndex: 'sgaj',
ellipsis: false,
format: 'dict|approvalResult',
// filters: 'dict|approvalResult',
},
{
title: '是否完成',
@ -59,7 +83,7 @@ export const urtgcolumns: BasicColumn[] = [
} else if (record.isfinish == 2) {
return "已完成"
} else {
return "未完成"
return "未上传"
}
},
@ -67,13 +91,100 @@ export const urtgcolumns: BasicColumn[] = [
];
export const urtFormSchema: FormSchema[] = [
{
//标题名称
label: '项目名称',
//字段
field: 'projectName',
//组件 支持组件详见 components/Form/src/types/index.ts 中的 ComponentType
component: 'Input',
labelWidth: 'auto'
labelWidth: 'auto',
//colProps: { span: 6 },
},
{
label: '行政区划',
field: 'adminDivision',
component: 'Select',
labelWidth: 'auto',
componentProps: {
options: [
{
label: '市本级',
value: '市本级',
},
{
label: '吴兴区',
value: '吴兴区',
},
{
label: '南浔区',
value: '南浔区',
},
{
label: '德清县',
value: '德清县',
},
{
label: '长兴县',
value: '长兴县',
},
{
label: '安吉县',
value: '安吉县',
},
],
},
//colProps: { span: 6 },
},
{
//标题名称
label: '责任单位',
//字段
field: 'dutyWorkplace',
//组件 支持组件详见 components/Form/src/types/index.ts 中的 ComponentType
component: 'ApiSelect',
componentProps: () => {
return {
api: () => getDutyWorkplaceOptions(),
};
},
labelWidth: 'auto',
},
{
//标题名称
label: '单位属性',
//字段
field: 'workplaceProperties',
//组件 支持组件详见 components/Form/src/types/index.ts 中的 ComponentType
component: 'Select',
componentProps: {
options: [
{
label: '医疗机构',
value: '医疗机构',
},
{
label: '卫生行政部门',
value: '卫生行政部门',
},
],
},
labelWidth: 'auto',
},
{
field: 'reformName',
label: '改革所属项目',
component: 'DictSelect',
componentProps: {
dictType: 'reformTasks',
},
itemProps: { validateTrigger: 'blur' },
labelWidth: 'auto',
},
{
field: 'superLeader',
label: '上级指导处室',
component: 'DictSelect',
componentProps: {
dictType: 'superLeader',
},
labelWidth: 'auto',
},
];

2
src/views/projectLib/projectInfo/index.vue

@ -13,7 +13,9 @@
</template>
<template #projectName="{ record }">
<el-tag v-if="record.type==2||record.stage==-1" color="bule">未入库项目</el-tag>
{{ record.projectName }}
<Tooltip
placement="bottom"
title="缺失子项目,子项目总金额和主项目不一致"

4
src/views/projectLib/projectInfo/projectInfo.api.ts

@ -1,4 +1,4 @@
import { downloadFile } from '@/api/common/api';
import { downloadResource } from '@/api/common/api';
import { defHttp } from '@/utils/http/axios';
import { useUserStore } from '@/store/modules/user';
@ -103,7 +103,7 @@ export const batchImportProjects = (params?) =>
});
export const batchdownloadProject = (params?) =>
downloadFile(Api.batchdownloadProject, '项目申报数据.xlsx', params);
downloadResource(Api.batchdownloadProject, '项目申报数据.xlsx', params);
export const isShowByRoles = (roles: string) => {
const roleList = userStore.getUserInfo.roleList;

2
src/views/projectLib/projectPlan/addPlan.vue

@ -42,8 +42,6 @@ function downexcel() {
fileName: "项目计划模板.xlsx"
}
downloadFile("/huzhouUploadfileinfo/downloadfile", "项目计划模板.xlsx", param)
}

43
src/views/projectLib/projectPlan/addPlanFile.vue

@ -39,6 +39,26 @@
<div slot="tip" class="el-upload__tip">只能上传{{ item }}且不超过500M</div>
</el-upload>
</el-form-item>
<div v-if="projectStages.includes(dataTo.taskName)">
<el-divider content-position="left">如项目未有以上文件请上传证明材料</el-divider>
<el-upload
class="upload-demo"
ref="upload"
action
:http-request="httpRequest"
:before-upload="
(file) => {
return beforeUpload(file, 'all');
}
"
:on-exceed="handleExceed"
:limit="5"
:on-remove="removeFile"
>
<el-button slot="trigger" size="small" type="primary">选取文件</el-button>
<div slot="tip" class="el-upload__tip">只能上传证明材料且不超过500M</div>
</el-upload>
</div>
<el-form-item>
<el-button type="primary" @click="submitImportForm" :disabled="isSubmitting"
>开始导入</el-button
@ -59,6 +79,18 @@
ContractMoneyFormSchemas,
} from '@/views/projectLib/projectPlan/projectPlan.data';
import { useForm, BasicForm } from '@/components/Form';
const projectStages = [
"招标结果确认",
"项目启动会议",
"组建项目实施专班",
"需求调研",
"系统设计",
"数据库设计",
"软件开发阶段",
"软件测试阶段",
"项目部署阶段",
"培训阶段"
];
const [
registerApprovalMoneyForm,
{
@ -159,12 +191,17 @@
message.error('最大上传500M');
return false;
}
//
if(item == 'all'){
return true;
}
let geShi = ['xlx', 'xlsx', 'docx', 'doc', 'pdf'] as Array<string>;
if (geShi.indexOf(file.name.substring(file.name.lastIndexOf('.') + 1)) == -1) {
message.error('文件格式错误!仅支持' + 'xlx,xlsx, docx, doc, pdf');
console.log('文件格式错误!仅支持' + 'xlsx', 'docx', 'doc', 'pdf');
return false;
}
if (item.indexOf(file.name.substring(0, file.name.indexOf('.'))) == -1) {
message.error('请上传文件:' + item);
return false;
@ -190,7 +227,11 @@
dataTo.taskName.indexOf('可研报告送审稿编制') >= 0
) {
//
} else {
}
else if (projectStages.includes(dataTo.taskName)){
}
else {
if (fileList.length != dataTo.files.length && dataTo.type == 0) {
message.error('上传的文件数量与项目计划资料数量不一致,请检查');
return;

4
src/views/projectLib/projectPlan/index.vue

@ -13,7 +13,7 @@
</BasicTable>
<BasicModal @register="registeViewPlanDetail" title="项目计划详情" width="1200px" :showOkBtn="false">
<viewPlanDetail :projectId="projectId" :projectStage="projectStage" />
<viewPlanDetail :projectId="projectId" :projectStage="projectStage" :projectName="projectName"/>
</BasicModal>
<BasicModal @register="registerProjectPlan" title="发起项目计划审批" width="1200px" :showOkBtn="false"
:showCancelBtn="false">
@ -43,6 +43,7 @@ const router = useRouter();
let projectId = ref();
let type = ref();
let projectStage = ref();
let projectName= ref();
const [registeViewPlanDetail, { openModal: openViewPlanDetail }] = useModal();//
const [registerProjectPlan, { openModal: openProjectPlan, closeModal: closeProjectPlan }] = useModal();//
@ -106,6 +107,7 @@ function getTableAction(record): ActionItem[] {
function handleDetailpage(record) {
projectId.value = record.id
projectStage.value = record.stage
projectName.value = record.projectName
openViewPlanDetail()
}

16
src/views/projectLib/projectPlan/projectPlan.api.ts

@ -1,5 +1,5 @@
import { defHttp } from '@/utils/http/axios';
import { downloadFile } from "@/api/common/api"
import { downloadResource } from "@/api/common/api"
import { e } from 'unocss';
export enum Api {
@ -13,6 +13,7 @@ export enum Api {
queryProjectPlan="/huzhouPlan/queryProjectPlan",
submitplaninfoUploadFile="/huzhouPlan/submitplaninfoUploadFile",
queryPlanInfoMainTimeline="/huzhouPlan/queryPlanInfoMainTimeline",
queryPlanInfoMainTimelineByPlaninfoid="/huzhouPlan/queryPlanInfoMainTimelineByPlaninfoid",
queryPlanInfoMainTimelineOffline="/huzhouPlan/queryPlanInfoMainTimelineOffline",
planUploadFile="/huzhouPlaninfofile/planUploadFile",
queryPlaninfoFilePageByid="/huzhouPlaninfofile/queryPlaninfoFilePageByid",
@ -31,6 +32,7 @@ export enum Api {
planREUploadFile="/huzhouPlaninfofile/planREUploadFile",
getProcessDetailByPlaninfoid="/huzhouPlaninfofile/getProcessDetailByPlaninfoid",
setPlaninfoIsoffline="/huzhouPlaninfofile/setPlaninfoIsoffline",
}
/**
*
@ -43,18 +45,20 @@ export const getProcessName = (params) => defHttp.get({ url: Api.getProcessName,
export const queryPlanModuleDetailPage = (params) => defHttp.get({ url: Api.queryPlanModuleDetailPage, params })
export const queryPlanModuleone = (params) => defHttp.get({ url: Api.queryPlanModuleone, params })
export const getPlanFileApprovalInfoByPlaninfoId = (params) => defHttp.get({ url: Api.getPlanFileApprovalInfoByPlaninfoId, params })
export const downloadPlanInfo = (params) => downloadFile(Api.downloadPlanInfo,"项目计划数据.xlsx",params)
export const downloadPlanInfo = (params) => downloadResource(Api.downloadPlanInfo,"项目计划数据.xlsx",params)
export const saveProjectPlan = (params) => defHttp.post({ url: Api.saveProjectPlan, params })
export const queryProjectPlan = (params) => defHttp.get({ url: Api.queryProjectPlan, params })
export const submitplaninfoUploadFile = (params?) =>defHttp.post({ url: Api.submitplaninfoUploadFile,headers:{ "Content-Type": "multipart/form-data" }, params })
export const submitplaninfoUploadFile = (params?) =>defHttp.post({ url: Api.submitplaninfoUploadFile,headers:{ "Content-Type": "multipart/form-data" }, params,timeout:10*60*1000 })
export const queryPlanInfoMainTimeline = (params) => defHttp.get({ url: Api.queryPlanInfoMainTimeline, params })
export const planUploadFile = (params?) =>defHttp.post({ url: Api.planUploadFile,headers:{ "Content-Type": "multipart/form-data" }, params })
export const planREUploadFile = (params?) =>defHttp.post({ url: Api.planREUploadFile,headers:{ "Content-Type": "multipart/form-data" }, params })
export const queryPlanInfoMainTimelineByPlaninfoid = (params) => defHttp.get({ url: Api.queryPlanInfoMainTimelineByPlaninfoid, params })
export const planUploadFile = (params?) =>defHttp.post({ url: Api.planUploadFile,headers:{ "Content-Type": "multipart/form-data" }, params,timeout:10*60*1000 })
export const planREUploadFile = (params?) =>defHttp.post({ url: Api.planREUploadFile,headers:{ "Content-Type": "multipart/form-data" }, params,timeout:10*60*1000 })
export const queryPlaninfoFilePageByid = (params) => defHttp.get({ url: Api.queryPlaninfoFilePageByid, params })
export const planUploadModifyFile = (params?) =>defHttp.post({ url: Api.planUploadModifyFile,headers:{ "Content-Type": "multipart/form-data" }, params })
export const planUploadModifyFile = (params?) =>defHttp.post({ url: Api.planUploadModifyFile,headers:{ "Content-Type": "multipart/form-data" }, params,timeout:10*60*1000 })
export const modifyPlaninfo = (params?) =>defHttp.post({ url: Api.modifyPlaninfo,headers:{ "Content-Type": "multipart/form-data" }, params })
export const approvePlaninfo = (params?) =>defHttp.post({ url: Api.approvePlaninfo,headers:{ "Content-Type": "multipart/form-data" }, params })
export const planFilePageList = (params) => defHttp.get({ url: Api.planFilePageList, params })

73
src/views/projectLib/projectPlan/viewPlanDetail.vue

@ -1,5 +1,6 @@
<template>
<!-- 自定义表单 -->
<el-divider content-position="left">项目名称{{ dataTo.projectName }}</el-divider>
<el-divider content-position="left">项目计划进程</el-divider>
<!-- <BasicTable @register="registerPlanDetail" /> -->
<div>
@ -135,7 +136,7 @@
import { isShowByRoles } from '../../projectLib/projectInfo/projectInfo.api';
import uploadURTfile from '@/views/projectLib/projectPlan/uploadURTfile.vue';
let dataTo = defineProps(['projectId', 'projectStage']);
let dataTo = defineProps(['projectId', 'projectStage', 'projectName']);
let projectId = ref(dataTo.projectId);
let isfinish = ref();
let activities = ref([]);
@ -245,10 +246,9 @@
label: '重新上传',
ifShow: () => {
if (
record.isfinish ==2 &&
record.taskFile?.length > 0 &&(
record.taskName == '可研报告初稿编制' ||
record.taskName == '可研报告送审稿编制')
record.isfinish == 2 &&
record.taskFile?.length > 0 &&
(record.taskName == '可研报告初稿编制' || record.taskName == '可研报告送审稿编制')
) {
if (isShowByRoles('projectContact')) {
return true;
@ -271,8 +271,8 @@
});
}
async function handleREuploadfile(record) {
//
taskName.value = record.taskName;
//
taskName.value = record.taskName;
type.value = record.isfinish;
if (record.taskFile.includes(',')) {
fileArr.value = record.taskFile.split(',');
@ -280,11 +280,10 @@
fileArr.value = record.taskFile.split(',');
}
if (record.taskName.indexOf('可研报告初稿编制') >= 0) {
fileArr.value.push("《项目建议书》");
}else if (record.taskName.indexOf('可研报告送审稿编制') >= 0) {
fileArr.value.push("《项目建议书》");
fileArr.value.push("《补充说明》");
fileArr.value.push('《项目建议书》');
} else if (record.taskName.indexOf('可研报告送审稿编制') >= 0) {
fileArr.value.push('《项目建议书》');
fileArr.value.push('《补充说明》');
}
planinfoid.value = record.id;
openPlanFile();
@ -298,26 +297,40 @@
fileArr.value = record.taskFile.split(',');
}
if (record.taskName.indexOf('可研报告初稿编制') >= 0) {
fileArr.value.push("《项目建议书》");
}else if (record.taskName.indexOf('可研报告送审稿编制') >= 0) {
fileArr.value.push("《项目建议书》");
fileArr.value.push("《补充说明》");
fileArr.value.push('《项目建议书》');
} else if (record.taskName.indexOf('可研报告送审稿编制') >= 0) {
fileArr.value.push('《项目建议书》');
fileArr.value.push('《补充说明》');
}
fileArr.value.push()
fileArr.value.push();
planinfoid.value = record.id;
// let tableData = await getDataSource();
// console.log('tableData', tableData);
//
// for (let i = 0; i < tableData[0].children.length; i++) {
// let child = tableData[0].children[i];
// //
// if (child.id == record.id) {
// //
// let pre = tableData[0].children[i - 1];
// if (pre.isfinish != 2) {
// message.error('' + pre.taskName + '');
// return;
let tableData = await getDataSource();
console.log('tableData', tableData);
//
// for (let x = 1; x < tableData.length; x++) {
// for (let i = 0; i < tableData[x].children.length; i++) {
// let child = tableData[x].children[i];
// //,
// if (i >= 1) {
// if (child.id == record.id) {
// //
// let pre = tableData[x].children[i - 1];
// if (pre.isfinish != 2) {
// message.error('' + pre.taskName + '');
// return;
// }
// }
// } else {
// //
// if (child.id == record.id) {
// //
// let preLength = tableData[x - 1].children.length; //
// let pre = tableData[x - 1].children[preLength - 1];
// if (pre.isfinish != 2) {
// message.error('' + pre.taskName + '');
// return;
// }
// }
// }
// }
// }

32
src/views/projectLib/projectProgress/index.vue

@ -1,12 +1,12 @@
<template>
<!-- 自定义表单 -->
<PageWrapper dense>
<PageWrapper dense>
<BasicTable @register="registerTable" @fetch-success="fetchSuccess">
<template #action="{ record }">
<TableAction :actions="getTableAction(record)" />
</template>
<template #tableTitle>
<a-button type="primary" @click="setWancheng" shape="round" v-if="isShowByRoles('org')">线下完成情况</a-button>
<!-- <a-button type="primary" @click="setWancheng" shape="round" v-if="isShowByRoles('org')">线下完成情况</a-button> -->
</template>
<template #toolbar>
<div class="text-base font-bold">单位万元</div>
@ -63,21 +63,21 @@
</div>
</template>
</BasicTable>
<BasicModal
@register="registeruploadFile"
title="查看进度"
width="1200px"
:showOkBtn="false"
:showCancelBtn="false"
>
<showtu :res="showtuList" />
</BasicModal>
<SetWanCheng @register="registerwancheng"></SetWanCheng>
</PageWrapper>
<BasicModal
@register="registeruploadFile"
title="查看进度"
width="1200px"
:showOkBtn="false"
:showCancelBtn="false"
>
<showtu :res="showtuList" />
</BasicModal>
<SetWanCheng @register="registerwancheng"></SetWanCheng>
</PageWrapper>
</template>
<script lang="ts" name="addAndModify" setup>
import { PageWrapper } from '@/components/Page';
import { PageWrapper } from '@/components/Page';
import { ref, onMounted } from 'vue';
import { ActionItem, BasicTable, TableAction, useTable } from '@/components/Table';
import { useModalInner, BasicModal } from '@/components/Modal';
@ -150,7 +150,7 @@ import { PageWrapper } from '@/components/Page';
openPlanFile(true);
}
function setWancheng() {
openModal(true,fatherData.value);
openModal(true, fatherData.value);
}
</script>
<style></style>

4
src/views/projectLib/workReport/detaiWorkReport.vue

@ -15,7 +15,7 @@
import { ref } from "vue"
import { ActionItem, BasicTable, TableAction, useTable } from '@/components/Table';
import { useModal } from '@/components/Modal';
import { downloadFile } from "@/api/common/api"
import { downloadResource } from "@/api/common/api"
import { workReportShowDetailcolumns } from '@/views/projectLib/workReport/workReport.data';
import addModifyWorkreport from "@/views/projectLib/workReport/addModifyWorkreport.vue"
import { searchFormSchema } from '@/views/projectLib/projectInfo/projectInfo.data';
@ -78,7 +78,7 @@ function handledown(record) {
//
console.log("我这一行的数据是", param)
downloadFile("/huzhouUploadfileinfo/downloadfile", record.documentName, param)
downloadResource("/huzhouUploadfileinfo/downloadfile", record.documentName, param)
}
async function handleDelete(record) {
await deleteWorkreport({ id: record.id })

12
src/views/projectLib/workReport/index.vue

@ -26,7 +26,6 @@
import { ref } from "vue"
import { ActionItem, BasicTable, TableAction, useTable } from '@/components/Table';
import { useModal } from '@/components/Modal';
import { downloadFile } from "@/api/common/api"
import { PageWrapper } from '@/components/Page';
import { isShowByRoles } from '@/views/projectLib/projectInfo/projectInfo.api';
import { workReportTablecolumns } from '@/views/projectLib/workReport/workReport.data';
@ -81,17 +80,6 @@ function handleadd(record) {
}
function handledown(record) {
console.log("我这一行的数据是", record)
let param = {
path: record.documentPath,
fileName: record.documentName
}
//
console.log("我这一行的数据是", param)
downloadFile("/huzhouUploadfileinfo/downloadfile", record.documentName, param)
}
async function handleDetail(record) {
await openModaldetaiWorkReport(true,{ projectid: record.id,reportType:record.reportType })
}

2
src/views/projectSummary/planSummary/planSummary.api.ts

@ -5,6 +5,7 @@ export enum Api {
getProjectNumber='/huzhouProject/getTotalNumber',
getStoragedNumber='/huzhouProject/getStoragedNumber',//入库项目数量
getSupportingNumber='/huzhouProject/getSupportingNumber',//配套项目数量
getStopNumber='/huzhouProject/getStopNumber',//停工项目数量
getStoragedFound='/huzhouProject/getStoragedFound',//入库项目资金
getSupportingFound='/huzhouProject/getSupportingFound',//配套项目资金
getProjectSummaryPage='/huzhouProject/getProjectSummaryPage',//项目总览页面(层级)
@ -19,6 +20,7 @@ export const getplanSummary = (params) => defHttp.get({ url: Api.getplanSummary,
export const getProjectNumber = (params?) => defHttp.get({ url: Api.getProjectNumber, params })
export const getStoragedNumber = (params?) => defHttp.get({ url: Api.getStoragedNumber, params })
export const getSupportingNumber = (params?) => defHttp.get({ url: Api.getSupportingNumber, params })
export const getStopNumber = (params?) => defHttp.get({ url: Api.getStopNumber, params })
export const getStoragedFound = (params?) => defHttp.get({ url: Api.getStoragedFound, params })
export const getSupportingFound = (params?) => defHttp.get({ url: Api.getSupportingFound, params })
export const getProjectSummaryPage = (params) => defHttp.get({ url: Api.getProjectSummaryPage, params })

135
src/views/projectSummary/planSummary/planSummary.data.ts

@ -331,7 +331,52 @@ export const detailColumn: BasicColumn[] = [
dataIndex: 'superLeader',
format: 'dict|superLeader',
},
{
title: "当前所处阶段",
dataIndex: "projectStage",
filters: [
{ text: '项目申报阶段', value: '0' },
{ text: '项目立项阶段', value: '1' },
{ text: '项目采购', value: '2' },
{ text: '项目建设', value: '3' },
{ text: '项目验收', value: '5' },
],
},
{
title: "当前所处节点",
dataIndex: "stepName",
filters: [
{ text: '可研报告初稿编制', value: '可研报告初稿编制' },
{ text: '可研技术审查报告确认', value: '可研技术审查报告确认' },
{ text: '可研报告送审稿编制', value: '可研报告送审稿编制' },
{ text: '造价评估报告确认', value: '造价评估报告确认' },
{ text: '联合技术审查', value: '联合技术审查' },
{ text: '集中核验', value: '集中核验' },
{ text: '立项审批', value: '立项审批' },
{ text: '招标文件编制', value: '招标文件编制' },
{ text: '合同签订', value: '合同签订' },
{ text: '项目开工', value: '项目开工' },
{ text: '初验阶段', value: '初验阶段' },
{ text: '终验阶段', value: '终验阶段' },
],
},
{
title: "当前审批节点",
dataIndex: "isUpload",
},
// {
// title: "线下阶段完成情况",
// dataIndex: "isOffline",
// },
{
title: "项目总进度",
dataIndex: "projectProgress",
customRender: ({ record }) => {
let progress: number = record.projectProgress * 100
return progress.toFixed(0) + "%"
},
},
{
title: "总申报资金",
dataIndex: "totalMoney",
@ -378,52 +423,52 @@ export const detailColumn: BasicColumn[] = [
},
sorter: true,
},
{
title: "当前所处阶段",
dataIndex: "projectStage",
filters: [
{ text: '项目申报阶段', value: '0' },
{ text: '项目立项阶段', value: '1' },
{ text: '项目采购', value: '2' },
{ text: '项目建设', value: '3' },
{ text: '项目验收', value: '5' },
],
},
{
title: "当前所处节点",
dataIndex: "stepName",
filters: [
{ text: '可研报告初稿编制', value: '可研报告初稿编制' },
{ text: '可研技术审查报告确认', value: '可研技术审查报告确认' },
{ text: '可研报告送审稿编制', value: '可研报告送审稿编制' },
{ text: '造价评估报告确认', value: '造价评估报告确认' },
{ text: '联合技术审查', value: '联合技术审查' },
{ text: '集中核验', value: '集中核验' },
{ text: '立项审批', value: '立项审批' },
{ text: '招标文件编制', value: '招标文件编制' },
{ text: '合同签订', value: '合同签订' },
{ text: '项目开工', value: '项目开工' },
{ text: '初验阶段', value: '初验阶段' },
{ text: '终验阶段', value: '终验阶段' },
// {
// title: "当前所处阶段",
// dataIndex: "projectStage",
// filters: [
// { text: '项目申报阶段', value: '0' },
// { text: '项目立项阶段', value: '1' },
// { text: '项目采购', value: '2' },
// { text: '项目建设', value: '3' },
// { text: '项目验收', value: '5' },
// ],
// },
// {
// title: "当前所处节点",
// dataIndex: "stepName",
// filters: [
// { text: '可研报告初稿编制', value: '可研报告初稿编制' },
// { text: '可研技术审查报告确认', value: '可研技术审查报告确认' },
// { text: '可研报告送审稿编制', value: '可研报告送审稿编制' },
// { text: '造价评估报告确认', value: '造价评估报告确认' },
// { text: '联合技术审查', value: '联合技术审查' },
// { text: '集中核验', value: '集中核验' },
// { text: '立项审批', value: '立项审批' },
// { text: '招标文件编制', value: '招标文件编制' },
// { text: '合同签订', value: '合同签订' },
// { text: '项目开工', value: '项目开工' },
// { text: '初验阶段', value: '初验阶段' },
// { text: '终验阶段', value: '终验阶段' },
],
},
{
title: "当前审批节点",
dataIndex: "isUpload",
},
{
title: "线下阶段完成情况",
dataIndex: "isOffline",
},
{
title: "项目总进度",
dataIndex: "projectProgress",
customRender: ({ record }) => {
let progress: number = record.projectProgress * 100
return progress.toFixed(0) + "%"
},
},
// ],
// },
// {
// title: "当前审批节点",
// dataIndex: "isUpload",
// },
// {
// title: "线下阶段完成情况",
// dataIndex: "isOffline",
// },
// {
// title: "项目总进度",
// dataIndex: "projectProgress",
// customRender: ({ record }) => {
// let progress: number = record.projectProgress * 100
// return progress.toFixed(0) + "%"
// },
// },
];
export const searchFormSchemacengji: FormSchema[] = [

262
src/views/projectSummary/planSummary/shouyeindex.vue

@ -0,0 +1,262 @@
<template>
<PageWrapper dense>
<!--引用表格-->
<div>
<a-tabs v-model:activeKey="activeKey" type="card" @change="handleTabChange">
<a-tab-pane key="1" tab="入库项目汇总(按任务)">
<BasicTable @register="registerRenwuTable">
<template #toolbar>
<div class="text-base font-bold">单位万元</div>
<a-button type="primary" @click="showMore('renwu')" shape="round">更多</a-button>
</template>
<template #headerTop>
<div class="container mx-auto mt-4 mb-4 h-20">
<div class="grid grid-cols-4 gap-4 h-full">
<div class="bg-[#1890FF] opacity-100 h-full">
<div class="grid grid-cols-4 gap-1 h-full">
<div class="col-span-3 mt-4 ml-4 text-white">项目数量</div>
<div
class="col-span-1 flex justify-center items-center text-white text-4xl font-bold "
>{{ planSummary.projectNum }}</div
>
</div>
</div>
<div class="bg-[#1890FF] opacity-90 h-full">
<div class="grid grid-cols-4 gap-1 h-full">
<div class="col-span-3 mt-4 ml-4 text-white">项目总进度</div>
<div
class="col-span-1 flex justify-center items-center text-white text-4xl font-bold mr-20"
>{{planSummary.projectProgress }}</div
>
</div>
</div>
<div class="bg-[#1890FF] opacity-85 h-full">
<div class="grid grid-cols-5 gap-1 h-full">
<div class="col-span-2 mt-4 ml-4 text-white">总申报资金</div>
<div
class="col-span-2 flex justify-center items-center text-white text-4xl font-bold"
>{{ planSummary.totalMoney }}</div
>
</div>
</div>
<div class="bg-[#1890FF] opacity-80 h-full">
<div class="grid grid-cols-5 gap-1 h-full">
<div class="col-span-2 mt-4 ml-4 text-white">总中央资金</div>
<div
class="col-span-2 flex justify-center items-center text-white text-4xl font-bold "
>{{ planSummary.centralMoney }}</div
>
</div>
</div>
</div>
</div>
</template>
</BasicTable>
</a-tab-pane>
<!-- <a-tab-pane key="2" tab="入库项目汇总(按层级)">
<BasicTable @register="registerCengjiTable">
<template #toolbar>
<div class="text-base font-bold">单位万元</div>
<a-button type="primary" @click="showMore('cengji')" shape="round">更多</a-button>
</template>
<template #headerTop>
<div class="container mx-auto mt-4 mb-4 h-20">
<div class="grid grid-cols-4 gap-4 h-full">
<div class="bg-[#1890FF] opacity-100 h-full">
<div class="grid grid-cols-4 gap-1 h-full">
<div class="col-span-3 mt-4 ml-4 text-white">项目数量</div>
<div
class="col-span-1 flex justify-center items-center text-white text-4xl font-bold "
>{{ planSummary.projectNum }}</div
>
</div>
</div>
<div class="bg-[#1890FF] opacity-90 h-full">
<div class="grid grid-cols-4 gap-1 h-full">
<div class="col-span-3 mt-4 ml-4 text-white">项目总进度</div>
<div
class="col-span-1 flex justify-center items-center text-white text-4xl font-bold mr-20"
>{{planSummary.projectProgress }}</div
>
</div>
</div>
<div class="bg-[#1890FF] opacity-85 h-full">
<div class="grid grid-cols-5 gap-1 h-full">
<div class="col-span-2 mt-4 ml-4 text-white">总申报资金</div>
<div
class="col-span-2 flex justify-center items-center text-white text-4xl font-bold"
>{{ planSummary.totalMoney }}</div
>
</div>
</div>
<div class="bg-[#1890FF] opacity-80 h-full">
<div class="grid grid-cols-5 gap-1 h-full">
<div class="col-span-2 mt-4 ml-4 text-white">总中央资金</div>
<div
class="col-span-2 flex justify-center items-center text-white text-4xl font-bold "
>{{ planSummary.centralMoney }}</div
>
</div>
</div>
</div>
</div>
</template>
</BasicTable>
</a-tab-pane> -->
</a-tabs>
<ShowMorePage @register="register" />
</div>
</PageWrapper>
</template>
<script lang="ts" name="planSummary" setup>
//ts
import { ref, onMounted } from 'vue';
import { BasicTable, useTable } from '@/components/Table';
import { PageWrapper } from '@/components/Page';
import { renwuColumn, cengjiColumn } from '@/views/projectSummary/planSummary/planSummary.data';
import {
getProjectSummaryPage,
getProjectSummaryPageByTask,
} from '@/views/projectSummary/planSummary/planSummary.api';
import { useModal, BasicModal } from '@/components/Modal';
import ShowMorePage from './ShowMorePage.vue';
const [register, { openModal }] = useModal();
onMounted(async () => {});
let planSummary = ref<any>({
projectNum: '',
centralMoney: '',
totalMoney: '',
projectProgress: '',
});
let activeKey = ref('1');
const [registerRenwuTable,{ reload:rwload }] = useTable({
api: getProjectSummaryPageByTask,
title: '入库项目汇总',
columns: renwuColumn,
rowKey: 'projectName',
showIndexColumn: false,
useSearchForm: false,
showSummary: true,
summaryFunc: onSummary,
// actionColumn: {
// width: 140,
// title: '',
// dataIndex: 'action',
// slots: { customRender: 'action' },
// },
});
const [registerCengjiTable,{ reload:cjload }] = useTable({
api: getProjectSummaryPage,
title: '入库项目汇总',
columns: cengjiColumn,
rowKey: 'projectName',
showIndexColumn: false,
useSearchForm: false,
showSummary: true,
summaryFunc: onSummary,
// actionColumn: {
// width: 140,
// title: '',
// dataIndex: 'action',
// slots: { customRender: 'action' },
// },
});
function mapTableTotalSummary(tableData, fields) {
let totals = {};
fields.forEach((field) => {
totals[field] = tableData.reduce((acc, item) => acc + Number(item[field]), 0);
});
return totals;
}
function showMore(type) {
openModal(true, { type: type });
console.log(type);
}
function onSummary(tableData: Recordable[]) {
const totals = mapTableTotalSummary(tableData, [
'projectNum',
'projectProgress',
'totalMoney',
'centralMoney',
]);
console.log('onSummary****totals>>>', totals);
planSummary.value = {
projectNum: totals.projectNum,
centralMoney: (totals.centralMoney/10000).toFixed(2),
totalMoney: (totals.totalMoney/10000).toFixed(2),
projectProgress: ((totals.projectProgress / tableData.length)*100).toFixed(2)+"%",
}
return [
// // totals,
{
reformName: '总计',
// superLeader:"",
dutyWorkplace: '总计',
//
projectNum: totals.projectNum,
centralMoney: totals.centralMoney,
totalMoney: totals.totalMoney,
projectProgress: (totals.projectProgress / tableData.length).toFixed(2),
},
];
}
function handleTabChange(key) {
// activeKey.value = key;
if (key === '1') {
rwload();
} else {
cjload();
}
}
</script>
<style scoped>
.timeline {
display: flex;
width: 100%;
margin-bottom: 100px;
.lineitem {
transform: translateX(50%);
width: 25%;
}
}
::v-deep .el-timeline-item__tail {
border-left: none;
width: 100%;
border-top: 2px solid #e4e7ed;
position: absolute;
top: 6px;
}
::v-deep .el-timeline-item__wrapper {
padding-left: 0;
position: absolute;
top: 20px;
transform: translateX(-50%);
text-align: center;
}
::v-deep .el-timeline-item__timestamp {
font-size: 14px;
}
.nested-timeline {
margin-left: 20px;
border-left: 1px dashed #ccc;
padding-left: 20px;
}
.nested-timeline-item {
margin-bottom: 10px;
}
::v-deep .ant-table-expanded-row {
height: auto !important;
/* 其他样式 */
}
</style>

1
src/views/workSystem/organizationStructure/organizationStructure.api.ts

@ -1,5 +1,4 @@
import { defHttp } from '@/utils/http/axios';
import { downloadFile } from "../../../api/common/api"
export enum Api {
getUsers = '/api/auth/sys/user/getUsers',

Loading…
Cancel
Save