Browse Source

抽查接口

dev
巴林闲侠 1 year ago
parent
commit
6864494fd1
  1. 1
      .gitignore
  2. 11
      api/.vscode/launch.json
  3. 156
      api/app/lib/controllers/report/index.js
  4. 7
      api/app/lib/index.js
  5. 60
      api/app/lib/models/report_spot_check.js
  6. 74
      api/app/lib/models/report_spot_check_preview.js
  7. 6
      api/app/lib/routes/report/index.js
  8. 18
      api/sequelize-automate.config.js
  9. 29
      scripts/1.3.0/schema/1.report_spot_check_preview.sql
  10. 17
      scripts/1.3.0/schema/2.create_report_spot_check.sql

1
.gitignore

@ -143,3 +143,4 @@ web/client/assets/color.less
package-lock.json
development.text
web/package-lock.json
web/log/development.txt

11
api/.vscode/launch.json

@ -16,14 +16,19 @@
"-p 13400",
"-f http://localhost:13400",
"-g postgres://postgres:123@10.8.30.32:5432/highways4good",
//"-g postgres://FashionAdmin:123456@10.8.30.156:5432/highway4goodn0728",
// "-g postgres://FashionAdmin:123456@10.8.30.156:5432/highway4goodn0728",
"--qnak XuDgkao6cL0HidoMAPnA5OB10Mc_Ew08mpIfRJK5",
"--qnsk yewcieZLzKZuDfig0wLZ9if9jKp2P_1jd3CMJPSa",
"--qnbkt dev-highways4good",
// "--qndmn http://resources.anxinyun.cn",
"--qndmn http://rfkimpwbb.hn-bkt.clouddn.com",
"--yingshiKey d0704fb9d5d14a6682c1c1d592c12512",
"--yingshiSecret 93d023269495b86be62cdfdcf34a6cd1"
// "--qndmn http://resources-test.anxinyun.cn",
// "--yingshiKey d0704fb9d5d14a6682c1c1d592c12512",
// "--yingshiSecret 93d023269495b86be62cdfdcf34a6cd1",
"--yingshiKey 5d16a667e1c2423d9d0d634f781810b4",
"--yingshiSecret 0cc4e1ec4e6a53ea3dabeb09cd5f468b",
]
},
{

156
api/app/lib/controllers/report/index.js

@ -1,6 +1,6 @@
'use strict';
const { QueryTypes } = require('sequelize');
const moment = require('moment')
async function reportList (ctx) {
try {
const models = ctx.fs.dc.models;
@ -289,8 +289,160 @@ async function deleteReport (ctx) {
// TODO 小程序填写道路名称的时候的道路筛选 是一起都返回 还是不断传关键字搜索返回
async function spotPrepare (ctx) {
try {
const { models } = ctx.fs.dc;
const sequelize = ctx.fs.dc.orm;
const { percentage } = ctx.request.body;
const departmentIdRes = await models.Department.findAll({
attributes: ['id', 'name'],
where: {
dependence: null,
delete: false,
}
})
let lukyDepartment = ''
if (departmentIdRes.length) {
lukyDepartment = departmentIdRes[(Math.round(Math.random() * departmentIdRes.length) || 1) - 1]
} else {
throw `暂无乡镇信息`
}
const sqlStr = `
WITH RECURSIVE sub_departments AS (
SELECT id, dependence
FROM department
WHERE id = ${lukyDepartment.id}
UNION ALL
SELECT d.id, d.dependence
FROM sub_departments sd
JOIN department d ON sd.id = d.dependence
)
SELECT u.id
FROM "user" AS u
JOIN sub_departments sd ON u.department_id = sd.id
WHERE u.delete = false;
`
const userRes = await sequelize.query(sqlStr, { type: QueryTypes.SELECT })
let findUsers = []
findUsers = userRes.map(item => {
return item.id
})
const reportCount = findUsers.length ? await models.Report.count({
where: {
reportType: 'conserve',
userId: { $in: findUsers }
}
}) : 0
const previewRes = await models.ReportSpotCheckPreview.create({
percentage: percentage,
departmentId: lukyDepartment.id,
date: moment().format(),
reportCount: reportCount,
checked: false,
})
ctx.status = 200;
ctx.body = {
lukyDepartment,
reportCount,
previewId: previewRes.id
}
} catch (error) {
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`);
ctx.status = 400;
ctx.body = {
message: typeof error == 'string' ? error : undefined
}
}
}
async function spotCheck (ctx) {
const transaction = await ctx.fs.dc.orm.transaction();
try {
const { models } = ctx.fs.dc;
const sequelize = ctx.fs.dc.orm;
const { previewId } = ctx.query
if (!previewId) {
throw '参数错误'
}
const prepareRes = await models.ReportSpotCheckPreview.find({
id: previewId
})
const sqlStr = `
WITH RECURSIVE sub_departments AS (
SELECT id, dependence
FROM department
WHERE id = ${prepareRes.departmentId}
UNION ALL
SELECT d.id, d.dependence
FROM sub_departments sd
JOIN department d ON sd.id = d.dependence
)
SELECT u.id
FROM "user" AS u
JOIN sub_departments sd ON u.department_id = sd.id
WHERE u.delete = false;
`
const userRes = await sequelize.query(sqlStr, { type: QueryTypes.SELECT })
let findUsers = []
findUsers = userRes.map(item => {
return item.id
})
let checkCount = Math.ceil(prepareRes.reportCount * (prepareRes.percentage / 100))
const reportRes = findUsers.length && checkCount ? await models.Report.findAll({
where: {
reportType: 'conserve',
userId: { $in: findUsers }
},
order: sequelize.random(), // 随机排序
limit: checkCount, // 限制返回的记录数
}) : []
await models.ReportSpotCheckPreview.update({
checked: true
}, {
where: {
id: previewId
}
})
if (reportRes.length) {
let spotDate = moment().format('YYYY-MM-DD')
await models.ReportSpotCheck.bulkCreate(reportRes.map(r => {
return {
reportId: r.id,
spotDate: spotDate,
prepareId: previewId
}
}))
}
await transaction.commit();
ctx.status = 200;
ctx.body = reportRes
} catch (error) {
await transaction.rollback();
ctx.fs.logger.error(`path: ${ctx.path}, error: error`);
ctx.status = 400;
ctx.body = {
message: typeof error == 'string' ? error : undefined
}
}
}
module.exports = {
reportList,
reportPosition,
reportDetail, createReport, deleteReport, reportHandle
reportDetail, createReport, deleteReport, reportHandle,
spotPrepare, spotCheck,
};

7
api/app/lib/index.js

@ -27,7 +27,7 @@ module.exports.models = function (dc) { // dc = { orm: Sequelize对象, ORM: Seq
require(`./models/${filename}`)(dc)
});
const { User, Department, Report, FileType, Road, Files, FileRoad, TaskManage, UserResource, Resource } = dc.models;
const { User, Department, Report, FileType, Road, Files, FileRoad, TaskManage, UserResource, Resource, ReportSpotCheck, ReportSpotCheckPreview } = dc.models;
// 定义外键
User.belongsTo(Department, { foreignKey: 'departmentId', targetKey: 'id' });
Department.hasMany(User, { foreignKey: 'departmentId', sourceKey: 'id' });
@ -55,6 +55,11 @@ module.exports.models = function (dc) { // dc = { orm: Sequelize对象, ORM: Seq
Resource.hasMany(UserResource, { foreignKey: 'resourceId', sourceKey: 'code' });
Resource.hasMany(Resource, { foreignKey: 'parentResource', sourceKey: 'code' });
ReportSpotCheckPreview.belongsTo(Department, { foreignKey: 'departmentId', targetKey: 'id' });
Department.hasMany(ReportSpotCheckPreview, { foreignKey: 'departmentId', sourceKey: 'id' });
ReportSpotCheck.belongsTo(Report, { foreignKey: 'reportId', targetKey: 'id' });
Report.hasMany(ReportSpotCheck, { foreignKey: 'reportId', sourceKey: 'id' });
};

60
api/app/lib/models/report_spot_check.js

@ -0,0 +1,60 @@
/* eslint-disable*/
'use strict';
module.exports = dc => {
const DataTypes = dc.ORM;
const sequelize = dc.orm;
const ReportSpotCheck = sequelize.define("reportSpotCheck", {
id: {
type: DataTypes.INTEGER,
allowNull: false,
defaultValue: null,
comment: null,
primaryKey: true,
field: "id",
autoIncrement: true,
unique: "report_spot_check_id_uindex"
},
reportId: {
type: DataTypes.INTEGER,
allowNull: false,
defaultValue: null,
comment: null,
primaryKey: false,
field: "report_id",
autoIncrement: false,
references: {
key: "id",
model: "report"
}
},
spotDate: {
type: DataTypes.DATEONLY,
allowNull: false,
defaultValue: null,
comment: null,
primaryKey: false,
field: "spot_date",
autoIncrement: false
},
prepareId: {
type: DataTypes.INTEGER,
allowNull: false,
defaultValue: null,
comment: null,
primaryKey: false,
field: "prepare_id",
autoIncrement: false,
references: {
key: "id",
model: "reportSpotCheckPreview"
}
}
}, {
tableName: "report_spot_check",
comment: "",
indexes: []
});
dc.models.ReportSpotCheck = ReportSpotCheck;
return ReportSpotCheck;
};

74
api/app/lib/models/report_spot_check_preview.js

@ -0,0 +1,74 @@
/* eslint-disable*/
'use strict';
module.exports = dc => {
const DataTypes = dc.ORM;
const sequelize = dc.orm;
const ReportSpotCheckPreview = sequelize.define("reportSpotCheckPreview", {
id: {
type: DataTypes.INTEGER,
allowNull: false,
defaultValue: null,
comment: null,
primaryKey: true,
field: "id",
autoIncrement: true,
unique: "report_spot_check_preview_id_uindex"
},
percentage: {
type: DataTypes.INTEGER,
allowNull: false,
defaultValue: null,
comment: "抽查比例",
primaryKey: false,
field: "percentage",
autoIncrement: false
},
departmentId: {
type: DataTypes.INTEGER,
allowNull: false,
defaultValue: null,
comment: "幸运乡镇",
primaryKey: false,
field: "department_id",
autoIncrement: false,
references: {
key: "id",
model: "department"
}
},
date: {
type: DataTypes.DATE,
allowNull: true,
defaultValue: null,
comment: "预览时间",
primaryKey: false,
field: "date",
autoIncrement: false
},
reportCount: {
type: DataTypes.INTEGER,
allowNull: false,
defaultValue: null,
comment: "当时上报总数",
primaryKey: false,
field: "report_count",
autoIncrement: false
},
checked: {
type: DataTypes.BOOLEAN,
allowNull: true,
defaultValue: null,
comment: null,
primaryKey: false,
field: "checked",
autoIncrement: false
}
}, {
tableName: "report_spot_check_preview",
comment: "",
indexes: []
});
dc.models.ReportSpotCheckPreview = ReportSpotCheckPreview;
return ReportSpotCheckPreview;
};

6
api/app/lib/routes/report/index.js

@ -24,4 +24,10 @@ module.exports = function (app, router, opts) {
app.fs.api.logAttr['get/allDepUsers'] = { content: '查询所有部门的员工', visible: false };
router.get('allDepUsers', Department.getDepUsers);
app.fs.api.logAttr['POST/report/spot/prepare'] = { content: '抽查预览', visible: false };
router.post('report/spot/prepare', report.spotPrepare);
app.fs.api.logAttr['GET/report/spot/check'] = { content: '抽查', visible: false };
router.get('report/spot/check', report.spotCheck);
}

18
api/sequelize-automate.config.js

@ -1,11 +1,19 @@
module.exports = {
// 数据库配置 与 sequelize 相同
dbOptions: {
database: 'highway4goodn0728',
username: 'FashionAdmin',
password: '123456',
// database: 'highway4goodn0728',
// username: 'FashionAdmin',
// password: '123456',
// host: '10.8.30.156',
// port: 5432,
database: 'highways4good',
username: 'postgres',
password: '123',
host: '10.8.30.32',
port: 5432,
dialect: 'postgres',
host: '10.8.30.156',
port: 5432,
define: {
underscored: false,
@ -27,7 +35,7 @@ module.exports = {
dir: './app/lib/models', // 指定输出 models 文件的目录
typesDir: 'models', // 指定输出 TypeScript 类型定义的文件目录,只有 TypeScript / Midway 等会有类型定义
emptyDir: false, // !!! 谨慎操作 生成 models 之前是否清空 `dir` 以及 `typesDir`
tables: ['user_resource'], // 指定生成哪些表的 models,如 ['user', 'user_post'];如果为 null,则忽略改属性
tables: ['report_spot_check'], // 指定生成哪些表的 models,如 ['user', 'user_post'];如果为 null,则忽略改属性
skipTables: [], // 指定跳过哪些表的 models,如 ['user'];如果为 null,则忽略改属性
tsNoCheck: false, // 是否添加 `@ts-nocheck` 注释到 models 文件中
ignorePrefix: [], // 生成的模型名称忽略的前缀,因为 项目中有以下表名是以 t_ 开头的,在实际模型中不需要, 可以添加多个 [ 't_data_', 't_',] ,长度较长的 前缀放前面

29
scripts/1.3.0/schema/1.report_spot_check_preview.sql

@ -0,0 +1,29 @@
create table report_spot_check_preview
(
id serial not null,
percentage int not null,
department_id int not null
constraint report_spot_check_preview_department_id_fk
references department (id),
date timestamp with time zone,
report_count int not null,
checked bool default false
);
comment on table report_spot_check_preview is '抽查的预览结果 ';
comment on column report_spot_check_preview.percentage is '抽查比例';
comment on column report_spot_check_preview.department_id is '幸运乡镇';
comment on column report_spot_check_preview.date is '预览时间';
comment on column report_spot_check_preview.report_count is '当时上报总数';
create unique index report_spot_check_preview_id_uindex
on report_spot_check_preview (id);
alter table report_spot_check_preview
add constraint report_spot_check_preview_pk
primary key (id);

17
scripts/1.3.0/schema/2.create_report_spot_check.sql

@ -0,0 +1,17 @@
create table if not exists report_spot_check
(
id serial not null
constraint report_spot_check_pk
primary key,
report_id integer not null
constraint report_spot_check_report_id_fk
references report,
spot_date date not null,
prepare_id integer not null
constraint report_spot_check_report_spot_check_preview_id_fk
references report_spot_check_preview
);
create unique index if not exists report_spot_check_id_uindex
on report_spot_check (id);
Loading…
Cancel
Save