Merge branch 'develop' of https://e.coding.net/ctcdevteam/hberp/hberp into develop
This commit is contained in:
commit
289a7a2335
|
@ -6,68 +6,69 @@ import 'nprogress/nprogress.css' // progress bar style
|
||||||
import { getToken } from '@/utils/auth' // get token from cookie
|
import { getToken } from '@/utils/auth' // get token from cookie
|
||||||
import getPageTitle from '@/utils/get-page-title'
|
import getPageTitle from '@/utils/get-page-title'
|
||||||
|
|
||||||
NProgress.configure({ showSpinner: false }) // NProgress Configuration
|
NProgress.configure({ showSpinner: false }) ;// NProgress Configuration
|
||||||
|
|
||||||
const whiteList = ['/login'] // no redirect whitelist
|
const whiteList = ['/login']; // no redirect whitelist
|
||||||
|
|
||||||
router.beforeEach(async(to, from, next) => {
|
router.beforeEach(async(to, from, next) => {
|
||||||
// start progress bar
|
// start progress bar
|
||||||
NProgress.start()
|
NProgress.start();
|
||||||
|
|
||||||
// set page title
|
// set page title
|
||||||
document.title = getPageTitle(to.meta.title)
|
document.title = getPageTitle(to.meta.title);
|
||||||
|
|
||||||
// determine whether the user has logged in
|
// determine whether the user has logged in
|
||||||
const hasToken = getToken()
|
const hasToken = getToken();
|
||||||
|
|
||||||
if (hasToken) {
|
if (hasToken) {
|
||||||
if (to.path === '/login') {
|
if (to.path === '/login') {
|
||||||
// if is logged in, redirect to the home page
|
// if is logged in, redirect to the home page
|
||||||
next({ path: '/' })
|
next({ path: '/' });
|
||||||
NProgress.done()
|
NProgress.done()
|
||||||
} else {
|
} else {
|
||||||
// determine whether the user has obtained his permission perms through getInfo
|
// determine whether the user has obtained his permission perms through getInfo
|
||||||
const hasPerms = store.getters.perms && store.getters.perms.length > 0
|
const hasPerms = store.getters.perms && store.getters.perms.length > 0;
|
||||||
if (hasPerms) {
|
if (hasPerms) {
|
||||||
next()
|
next()
|
||||||
} else {
|
} else {
|
||||||
try {
|
try {
|
||||||
// get user info
|
// get user info
|
||||||
// note: perms must be a object array! such as: ['admin'] or ,['developer','editor']
|
// note: perms must be a object array! such as: ['admin'] or ,['developer','editor']
|
||||||
const { perms } = await store.dispatch('user/getInfo')
|
const { perms } = await store.dispatch('user/getInfo');
|
||||||
// generate accessible routes map based on perms
|
// generate accessible routes map based on perms
|
||||||
const accessRoutes = await store.dispatch('permission/generateRoutes', perms)
|
const accessRoutes = await store.dispatch('permission/generateRoutes', perms);
|
||||||
|
|
||||||
// dynamically add accessible routes
|
// dynamically add accessible routes
|
||||||
router.addRoutes(accessRoutes)
|
router.addRoutes(accessRoutes);
|
||||||
|
|
||||||
// hack method to ensure that addRoutes is complete
|
// hack method to ensure that addRoutes is complete
|
||||||
// set the replace: true, so the navigation will not leave a history record
|
// set the replace: true, so the navigation will not leave a history record
|
||||||
next({ ...to, replace: true })
|
next({ ...to, replace: true })
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
// remove token and go to login page to re-login
|
// remove token and go to login page to re-login
|
||||||
await store.dispatch('user/resetToken')
|
await store.dispatch('user/resetToken');
|
||||||
Message.error(error || 'Has Error')
|
Message.error(error || 'Has Error');
|
||||||
next(`/login?redirect=${to.path}`)
|
next(`/login?redirect=${to.path}`);
|
||||||
NProgress.done()
|
NProgress.done()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* has no token*/
|
/* has no token*/
|
||||||
|
if (to.path === '/index'){
|
||||||
if (whiteList.indexOf(to.path) !== -1) {
|
next()
|
||||||
|
}else if (whiteList.indexOf(to.path) !== -1) {
|
||||||
// in the free login whitelist, go directly
|
// in the free login whitelist, go directly
|
||||||
next()
|
next()
|
||||||
} else {
|
} else {
|
||||||
// other pages that do not have permission to access are redirected to the login page.
|
// other pages that do not have permission to access are redirected to the login page.
|
||||||
next(`/login?redirect=${to.path}`)
|
next(`/login?redirect=${to.path}`);
|
||||||
NProgress.done()
|
NProgress.done()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
|
|
||||||
router.afterEach(() => {
|
router.afterEach(() => {
|
||||||
// finish progress bar
|
// finish progress bar
|
||||||
NProgress.done()
|
NProgress.done()
|
||||||
})
|
});
|
||||||
|
|
|
@ -20,7 +20,7 @@ service.interceptors.request.use(
|
||||||
// please modify it according to the actual situation
|
// please modify it according to the actual situation
|
||||||
config.headers['Authorization'] = 'Bearer ' + getToken()
|
config.headers['Authorization'] = 'Bearer ' + getToken()
|
||||||
}
|
}
|
||||||
let data = config.data;
|
let data = config.data?config.data:config.params;
|
||||||
/*debugger;
|
/*debugger;
|
||||||
console.log(data)*/
|
console.log(data)*/
|
||||||
if(data){
|
if(data){
|
||||||
|
@ -28,6 +28,9 @@ service.interceptors.request.use(
|
||||||
if(token){
|
if(token){
|
||||||
config.headers['Authorization'] = 'Bearer ' + token
|
config.headers['Authorization'] = 'Bearer ' + token
|
||||||
}
|
}
|
||||||
|
if(data.type==='big_screen'){
|
||||||
|
config.headers['Authorization'] = 'big_screen '
|
||||||
|
}
|
||||||
}
|
}
|
||||||
/* debugger;
|
/* debugger;
|
||||||
console.log(config.headers['Authorization'])*/
|
console.log(config.headers['Authorization'])*/
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
:key="item.title"
|
:key="item.title"
|
||||||
>
|
>
|
||||||
<p class="ml-3 colorBlue fw-b fs-xl">{{ item.title }}</p>
|
<p class="ml-3 colorBlue fw-b fs-xl">{{ item.title }}</p>
|
||||||
<div>
|
<div v-if="numberShow">
|
||||||
<dv-digital-flop
|
<dv-digital-flop
|
||||||
class="dv-dig-flop ml-1 mt-2 pl-3"
|
class="dv-dig-flop ml-1 mt-2 pl-3"
|
||||||
:config="item.number"
|
:config="item.number"
|
||||||
|
@ -20,7 +20,7 @@
|
||||||
<span>
|
<span>
|
||||||
<el-icon class="el-icon-pie-chart"></el-icon>
|
<el-icon class="el-icon-pie-chart"></el-icon>
|
||||||
</span>
|
</span>
|
||||||
<span class="fs-xl text mx-2 mb-1 pl-3">任务完成进度</span>
|
<span class="fs-xl text mx-2 mb-1 pl-3">工序生产进度</span>
|
||||||
<dv-scroll-ranking-board class="dv-scr-rank-board mt-1" :config="ranking" />
|
<dv-scroll-ranking-board class="dv-scr-rank-board mt-1" :config="ranking" />
|
||||||
</div>
|
</div>
|
||||||
<div class="percent">
|
<div class="percent">
|
||||||
|
@ -49,11 +49,20 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import CenterChart from '@/components/echart/chartRate.vue'
|
import {getProductionplanList} from "@/api/pm";
|
||||||
|
import {getContractList, getOrderList} from "@/api/sam";
|
||||||
|
import CenterChart from '@/components/echart/chartRate.vue'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
contractTotalCurrent:0,
|
||||||
|
orderTotalCurrent:0,
|
||||||
|
planTotalCurrent:0,
|
||||||
|
selProductCurrent:0,
|
||||||
|
noProductCurrent:0,
|
||||||
|
numberShow:true,
|
||||||
|
/* create_time_start:'',
|
||||||
titleItem: [
|
titleItem: [
|
||||||
{
|
{
|
||||||
title: '本月合同数',
|
title: '本月合同数',
|
||||||
|
@ -198,11 +207,101 @@ export default {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]*/
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
components: {
|
components: {
|
||||||
CenterChart
|
CenterChart
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
titleItem:{
|
||||||
|
type:Array,
|
||||||
|
default: () => {
|
||||||
|
return []
|
||||||
|
}
|
||||||
|
} ,
|
||||||
|
rate:{
|
||||||
|
type:Array,
|
||||||
|
default: () => {
|
||||||
|
return []
|
||||||
|
}
|
||||||
|
} ,
|
||||||
|
water:{
|
||||||
|
type:Object,
|
||||||
|
default: () => {
|
||||||
|
return {}
|
||||||
|
}
|
||||||
|
} ,
|
||||||
|
ranking:{
|
||||||
|
type:Object,
|
||||||
|
default: () => {
|
||||||
|
return {}
|
||||||
|
}
|
||||||
|
} ,
|
||||||
|
},
|
||||||
|
methods:{
|
||||||
|
/* getData(){
|
||||||
|
let that = this;
|
||||||
|
that.numberShow = false;
|
||||||
|
let dat = new Date();
|
||||||
|
that.week = dat.getDay();
|
||||||
|
that.currentTime = dat.getTime();
|
||||||
|
that.currentYear = dat.getFullYear();
|
||||||
|
let month = dat.getMonth() + 1;
|
||||||
|
that.currentMonth = month > 9 ? month : '0' + month;
|
||||||
|
that.currentDay = dat.getDate();
|
||||||
|
that.create_time_start = that.currentYear + '-' + that.currentMonth + '-01';
|
||||||
|
that.$nextTick(()=>{
|
||||||
|
|
||||||
|
})
|
||||||
|
},*/
|
||||||
|
getContract(){
|
||||||
|
let that = this;
|
||||||
|
//合同
|
||||||
|
getContractList({type:'big_screen',page: 1, page_size: 1, create_time_start: that.create_time_start}).then((response) => {
|
||||||
|
if (response.data) {
|
||||||
|
that.numberShow = false;
|
||||||
|
that.titleItem[0].number.number[0] = response.data.count;
|
||||||
|
that.numberShow = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
getOrder(){
|
||||||
|
let that = this;
|
||||||
|
//订单
|
||||||
|
getOrderList({type:'big_screen',page: 1, page_size: 1, create_time_start: that.create_time_start}).then((response) => {
|
||||||
|
if (response.data) {
|
||||||
|
that.numberShow = false;
|
||||||
|
that.titleItem[1].number.number[0] = response.data.count;
|
||||||
|
that.numberShow = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
getProductionplan(){
|
||||||
|
let that = this;
|
||||||
|
//已排产任务
|
||||||
|
getProductionplanList({type:'big_screen',page: 1, page_size: 1, tag: 'working'}).then((response) => {
|
||||||
|
if (response.data) {
|
||||||
|
that.numberShow = false;
|
||||||
|
that.titleItem[2].number.number[0] = response.data.count;
|
||||||
|
that.numberShow = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
let that = this;
|
||||||
|
let dat = new Date();
|
||||||
|
that.week = dat.getDay();
|
||||||
|
that.currentTime = dat.getTime();
|
||||||
|
that.currentYear = dat.getFullYear();
|
||||||
|
let month = dat.getMonth() + 1;
|
||||||
|
that.currentMonth = month > 9 ? month : '0' + month;
|
||||||
|
that.currentDay = dat.getDate();
|
||||||
|
that.create_time_start = that.currentYear + '-' + that.currentMonth + '-01';
|
||||||
|
that.getContract();
|
||||||
|
that.getOrder();
|
||||||
|
that.getProductionplan();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="d-flex jc-center body-box">
|
<div class="d-flex jc-center body-box">
|
||||||
<dv-scroll-board class="dv-scr-board" :config="config" />
|
<dv-scroll-board class="dv-scr-board" :config="userConfig" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -19,7 +19,7 @@
|
||||||
export default {
|
export default {
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
config: {
|
/* config: {
|
||||||
header: ['姓名', '部门', '到岗情况'],
|
header: ['姓名', '部门', '到岗情况'],
|
||||||
data: [
|
data: [
|
||||||
['张思', '一车间', "<span class='colorGrass'>已到岗</span>"],
|
['张思', '一车间', "<span class='colorGrass'>已到岗</span>"],
|
||||||
|
@ -41,9 +41,17 @@ export default {
|
||||||
index: false,
|
index: false,
|
||||||
// columnWidth: [50],
|
// columnWidth: [50],
|
||||||
align: ['center']
|
align: ['center']
|
||||||
|
}*/
|
||||||
|
}
|
||||||
|
},
|
||||||
|
props:{
|
||||||
|
userConfig:{
|
||||||
|
type:Object,
|
||||||
|
default:()=>{
|
||||||
|
return {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
export default {
|
export default {
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
config: {
|
/*config: {
|
||||||
data: [
|
data: [
|
||||||
{
|
{
|
||||||
name: '冷加工',
|
name: '冷加工',
|
||||||
|
@ -50,6 +50,14 @@ export default {
|
||||||
value: 100
|
value: 100
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
}*/
|
||||||
|
}
|
||||||
|
},
|
||||||
|
props:{
|
||||||
|
config:{
|
||||||
|
type:Object,
|
||||||
|
default:()=>{
|
||||||
|
return {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -4,9 +4,9 @@
|
||||||
<!--<dv-loading v-show="loading">Loading...</dv-loading>-->
|
<!--<dv-loading v-show="loading">Loading...</dv-loading>-->
|
||||||
<div class="host-body">
|
<div class="host-body">
|
||||||
<div class="d-flex jc-center" id="firstLine">
|
<div class="d-flex jc-center" id="firstLine">
|
||||||
<dv-decoration-10 class="dv-dec-10" />
|
<dv-decoration-10 class="dv-dec-10"/>
|
||||||
<div class="d-flex jc-center">
|
<div class="d-flex jc-center">
|
||||||
<dv-decoration-8 class="dv-dec-8" :color="['#568aea', '#000000']" />
|
<dv-decoration-8 class="dv-dec-8" :color="['#568aea', '#000000']"/>
|
||||||
<div class="title">
|
<div class="title">
|
||||||
<div class="title-text">
|
<div class="title-text">
|
||||||
<span style="margin-right: 20px">航玻生产</span><span>管理系统</span>
|
<span style="margin-right: 20px">航玻生产</span><span>管理系统</span>
|
||||||
|
@ -23,7 +23,7 @@
|
||||||
:color="['#568aea', '#000000']"
|
:color="['#568aea', '#000000']"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<dv-decoration-10 class="dv-dec-10-s" />
|
<dv-decoration-10 class="dv-dec-10-s"/>
|
||||||
</div>
|
</div>
|
||||||
<!-- 第二行 -->
|
<!-- 第二行 -->
|
||||||
<div class="d-flex jc-between px-2">
|
<div class="d-flex jc-between px-2">
|
||||||
|
@ -50,36 +50,45 @@
|
||||||
<!-- 第三行数据 -->
|
<!-- 第三行数据 -->
|
||||||
<div id="centerWrap" class="content-box">
|
<div id="centerWrap" class="content-box">
|
||||||
<!-- 数据统计 -->
|
<!-- 数据统计 -->
|
||||||
<div>
|
<div v-if="numberShow">
|
||||||
<center />
|
<center
|
||||||
|
:titleItem="titleItem"
|
||||||
|
:rate="rate"
|
||||||
|
:water="water"
|
||||||
|
:ranking="ranking"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div v-if="processRate">
|
||||||
<centerRight2 />
|
<centerRight2
|
||||||
|
:config="config"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<dv-border-box-1>
|
<dv-border-box-1>
|
||||||
<centerLeft1 />
|
<centerLeft1/>
|
||||||
</dv-border-box-1>
|
</dv-border-box-1>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<dv-border-box-1>
|
<dv-border-box-1>
|
||||||
<centerLeft2 />
|
<centerLeft2/>
|
||||||
</dv-border-box-1>
|
</dv-border-box-1>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div v-if="listUser">
|
||||||
<dv-border-box-13>
|
<dv-border-box-13>
|
||||||
<centerRight1 />
|
<centerRight1
|
||||||
|
:userConfig="userConfig"
|
||||||
|
/>
|
||||||
</dv-border-box-13>
|
</dv-border-box-13>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- 第四行数据 -->
|
<!-- 第四行数据 -->
|
||||||
<div class="bototm-box">
|
<div class="bototm-box">
|
||||||
<dv-border-box-3>
|
<dv-border-box-3>
|
||||||
<bottomRight />
|
<bottomRight/>
|
||||||
</dv-border-box-3>
|
</dv-border-box-3>
|
||||||
<dv-border-box-13>
|
<dv-border-box-13>
|
||||||
<bottomLeft />
|
<bottomLeft/>
|
||||||
</dv-border-box-13>
|
</dv-border-box-13>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -90,18 +99,22 @@
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import drawMixin from "../../utils/drawMixin";
|
import drawMixin from "../../utils/drawMixin";
|
||||||
import { formatTimeBigScreen } from '../../utils/index.js'
|
import {formatTimeBigScreen} from '../../utils/index.js'
|
||||||
import centerLeft1 from './centerLeft1'
|
import centerLeft1 from './centerLeft1'
|
||||||
import centerLeft2 from './centerLeft2'
|
import centerLeft2 from './centerLeft2'
|
||||||
import centerRight1 from './centerRight1'
|
import centerRight1 from './centerRight1'
|
||||||
import centerRight2 from './centerRight2'
|
import centerRight2 from './centerRight2'
|
||||||
import center from './center'
|
import center from './center'
|
||||||
|
import {getEmployee} from "@/api/hrm";
|
||||||
import bottomLeft from './bottomLeft'
|
import bottomLeft from './bottomLeft'
|
||||||
import bottomRight from './bottomRight'
|
import bottomRight from './bottomRight'
|
||||||
import { getPlanGantt } from "@/api/srm";
|
import {getPlanGantt} from "@/api/srm";
|
||||||
|
import {getProductionplanList} from "@/api/pm";
|
||||||
|
import {getProcessYield} from "@/api/srm";
|
||||||
|
import {getContractList, getOrderList} from "@/api/sam";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
mixins: [ drawMixin ],
|
mixins: [drawMixin],
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
timing: null,
|
timing: null,
|
||||||
|
@ -109,7 +122,183 @@
|
||||||
dateDay: null,
|
dateDay: null,
|
||||||
dateYear: null,
|
dateYear: null,
|
||||||
dateWeek: null,
|
dateWeek: null,
|
||||||
planGanttList:[],
|
planGanttList: [],
|
||||||
|
numberShow: false,
|
||||||
|
processRate: false,
|
||||||
|
listUser: false,
|
||||||
|
create_time_start: '',
|
||||||
|
titleItem: [
|
||||||
|
{
|
||||||
|
title: '本月合同数',
|
||||||
|
number: {
|
||||||
|
number: [12],//数字数值
|
||||||
|
toFixed: 0,//小数位数
|
||||||
|
textAlign: 'left',//水平对齐方式
|
||||||
|
content: '{nt}',//内容模版//rowGap行间距
|
||||||
|
style: {//样式配置
|
||||||
|
fontSize: 26
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '本月生产订单数',
|
||||||
|
number: {
|
||||||
|
number: [12],
|
||||||
|
toFixed: 0,
|
||||||
|
textAlign: 'left',
|
||||||
|
content: '{nt}',
|
||||||
|
style: {
|
||||||
|
fontSize: 26
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '本月在制任务数',
|
||||||
|
number: {
|
||||||
|
number: [2],
|
||||||
|
toFixed: 0,
|
||||||
|
textAlign: 'left',
|
||||||
|
content: '{nt}',
|
||||||
|
style: {
|
||||||
|
fontSize: 26
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '本月交付产品数',
|
||||||
|
number: {
|
||||||
|
number: [8],
|
||||||
|
toFixed: 0,
|
||||||
|
textAlign: 'left',
|
||||||
|
content: '{nt}',
|
||||||
|
style: {
|
||||||
|
fontSize: 26
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '本月不合格产品数',
|
||||||
|
number: {
|
||||||
|
number: [2],
|
||||||
|
toFixed: 0,
|
||||||
|
textAlign: 'left',
|
||||||
|
content: '{nt}',
|
||||||
|
style: {
|
||||||
|
fontSize: 26
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '本月军检合格率',
|
||||||
|
number: {
|
||||||
|
number: [99],
|
||||||
|
toFixed: 1,
|
||||||
|
textAlign: 'left',
|
||||||
|
content: '{nt}%',
|
||||||
|
style: {
|
||||||
|
fontSize: 26
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
],
|
||||||
|
ranking: {
|
||||||
|
data: [
|
||||||
|
{
|
||||||
|
name: '冷加工',
|
||||||
|
value: 100
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '热弯成型',
|
||||||
|
value: 100
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '化学钢化',
|
||||||
|
value: 100
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '镀膜',
|
||||||
|
value: 100
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '夹层',
|
||||||
|
value: 100
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '包边',
|
||||||
|
value: 100
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '装框',
|
||||||
|
value: 100
|
||||||
|
}
|
||||||
|
],
|
||||||
|
carousel: 'single',
|
||||||
|
unit: '%'
|
||||||
|
},
|
||||||
|
water: {
|
||||||
|
data: [24, 45],
|
||||||
|
shape: 'roundRect',
|
||||||
|
formatter: '{value}%',
|
||||||
|
waveNum: 3
|
||||||
|
},
|
||||||
|
// 通过率和达标率的组件复用数据
|
||||||
|
rate: [
|
||||||
|
{
|
||||||
|
id: 'centerRate1',
|
||||||
|
tips: 98,
|
||||||
|
colorData: {
|
||||||
|
textStyle: '#3fc0fb',
|
||||||
|
series: {
|
||||||
|
color: ['#00bcd44a', 'transparent'],
|
||||||
|
dataColor: {
|
||||||
|
normal: '#03a9f4',
|
||||||
|
shadowColor: '#97e2f5'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'centerRate2',
|
||||||
|
tips: 99,
|
||||||
|
colorData: {
|
||||||
|
textStyle: '#67e0e3',
|
||||||
|
series: {
|
||||||
|
color: ['#faf3a378', 'transparent'],
|
||||||
|
dataColor: {
|
||||||
|
normal: '#ff9800',
|
||||||
|
shadowColor: '#fcebad'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
config: {
|
||||||
|
data: []
|
||||||
|
},
|
||||||
|
//人员到岗
|
||||||
|
userConfig: {
|
||||||
|
header: ['姓名', '部门', '到岗情况'],
|
||||||
|
data: [
|
||||||
|
['张思', '一车间', "<span class='colorGrass'>已到岗</span>"],
|
||||||
|
['李森', '一车间', "<span class='colorGrass'>已到岗</span>"],
|
||||||
|
['王师', '一车间', "<span class='colorRed'>未到岗</span>"],
|
||||||
|
['赵迪', '一车间', "<span class='colorGrass'>已到岗</span>"],
|
||||||
|
['孟津', '一车间', "<span class='colorGrass'>已到岗</span>"],
|
||||||
|
['孙东课', '一车间', "<span class='colorGrass'>已到岗</span>"],
|
||||||
|
['周神秘', '二车间', "<span class='colorGrass'>已到岗</span>"],
|
||||||
|
['吴老弟', '二车间', "<span class='colorRed'>未到岗</span>"],
|
||||||
|
['郑成功', '二车间', "<span class='colorGrass'>已到岗</span>"],
|
||||||
|
['冯宝宝', '二车间', "<span class='colorGrass'>已到岗</span>"]
|
||||||
|
],
|
||||||
|
rowNum: 7, //表格行数
|
||||||
|
headerHeight: 35,
|
||||||
|
headerBGC: '#0f1325', //表头
|
||||||
|
oddRowBGC: '#0f1325', //奇数行
|
||||||
|
evenRowBGC: '#171c33', //偶数行
|
||||||
|
index: false,
|
||||||
|
// columnWidth: [50],
|
||||||
|
align: ['center']
|
||||||
|
},
|
||||||
weekday: ['周日', '周一', '周二', '周三', '周四', '周五', '周六']
|
weekday: ['周日', '周一', '周二', '周三', '周四', '周五', '周六']
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -122,21 +311,33 @@
|
||||||
bottomLeft,
|
bottomLeft,
|
||||||
bottomRight
|
bottomRight
|
||||||
},
|
},
|
||||||
created(){
|
created() {
|
||||||
// window.open('http://49.232.14.174:2222/#/index');
|
// window.open('http://49.232.14.174:2222/#/index');
|
||||||
// this.$router.go(-1)
|
// this.$router.go(-1)
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
|
let that = this;
|
||||||
this.timeFn();
|
this.timeFn();
|
||||||
this.cancelLoading();
|
this.cancelLoading();
|
||||||
this.getPageData();
|
this.getPageData();
|
||||||
let bigHeight = document.getElementsByClassName('host-body')[0].clientHeight;
|
let bigHeight = document.getElementsByClassName('host-body')[0].clientHeight;
|
||||||
let firstHeight = document.getElementById('firstLine').clientHeight;
|
let firstHeight = document.getElementById('firstLine').clientHeight;
|
||||||
let secondHeight = document.getElementsByClassName('jc-between')[0].clientHeight;
|
let secondHeight = document.getElementsByClassName('jc-between')[0].clientHeight;
|
||||||
let domHeight = (bigHeight/2) - firstHeight - secondHeight-30;
|
let domHeight = (bigHeight / 2) - firstHeight - secondHeight - 30;
|
||||||
document.getElementById('centerWrap').style.height = domHeight + 'px';
|
document.getElementById('centerWrap').style.height = domHeight + 'px';
|
||||||
|
let dat = new Date();
|
||||||
|
that.week = dat.getDay();
|
||||||
|
that.currentTime = dat.getTime();
|
||||||
|
that.currentYear = dat.getFullYear();
|
||||||
|
let month = dat.getMonth() + 1;
|
||||||
|
that.currentMonth = month > 9 ? month : '0' + month;
|
||||||
|
that.currentDay = dat.getDate();
|
||||||
|
that.create_time_start = that.currentYear + '-' + that.currentMonth + '-01';
|
||||||
|
that.getCenterData();
|
||||||
|
that.getCenterRight2Data();
|
||||||
|
that.getUserList();
|
||||||
},
|
},
|
||||||
beforeDestroy () {
|
beforeDestroy() {
|
||||||
clearInterval(this.timing)
|
clearInterval(this.timing)
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
@ -147,9 +348,9 @@
|
||||||
this.dateWeek = this.weekday[new Date().getDay()]
|
this.dateWeek = this.weekday[new Date().getDay()]
|
||||||
}, 1000)
|
}, 1000)
|
||||||
},
|
},
|
||||||
getPageData(){
|
getPageData() {
|
||||||
let that = this;
|
let that = this;
|
||||||
getPlanGantt({Authorization:'big_screen'}).then(res => {
|
getPlanGantt({type: 'big_screen'}).then(res => {
|
||||||
if (res.code === 200) {
|
if (res.code === 200) {
|
||||||
this.planGanttList = res.data.results;
|
this.planGanttList = res.data.results;
|
||||||
} else {
|
} else {
|
||||||
|
@ -161,7 +362,86 @@
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
this.loading = false
|
this.loading = false
|
||||||
}, 500)
|
}, 500)
|
||||||
}
|
},
|
||||||
|
getCenterData() {
|
||||||
|
let that = this;
|
||||||
|
that.numberShow = false;
|
||||||
|
//合同
|
||||||
|
getContractList({
|
||||||
|
type: 'big_screen',
|
||||||
|
page: 1,
|
||||||
|
page_size: 1,
|
||||||
|
create_time_start: that.create_time_start
|
||||||
|
}).then((response) => {
|
||||||
|
if (response.data) {
|
||||||
|
that.titleItem[0].number.number[0] = response.data.count;
|
||||||
|
getOrderList({
|
||||||
|
type: 'big_screen',
|
||||||
|
page: 1,
|
||||||
|
page_size: 1,
|
||||||
|
create_time_start: that.create_time_start
|
||||||
|
}).then((response) => {
|
||||||
|
if (response.data) {
|
||||||
|
that.titleItem[1].number.number[0] = response.data.count;
|
||||||
|
getProductionplanList({type: 'big_screen', page: 1, page_size: 1, tag: 'working'}).then((response) => {
|
||||||
|
if (response.data) {
|
||||||
|
that.titleItem[2].number.number[0] = response.data.count;
|
||||||
|
that.numberShow = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
getCenterRight2Data() {
|
||||||
|
let that = this;
|
||||||
|
that.processRate = false;
|
||||||
|
let dat = new Date();
|
||||||
|
let Year = dat.getFullYear();
|
||||||
|
let month = dat.getMonth() + 1;
|
||||||
|
let day = dat.getDate();
|
||||||
|
let searchTime = Year + '-' + month + '-' + day;
|
||||||
|
getProcessYield({datetime_start: searchTime, datetime_end: searchTime,type:'big_screen'}).then((response) => {
|
||||||
|
if (response.data) {
|
||||||
|
let list = response.data;
|
||||||
|
let data = [];
|
||||||
|
list.forEach(item => {
|
||||||
|
let obj = new Object();
|
||||||
|
obj.name = item.name;
|
||||||
|
obj.value = Math.floor(item.rate * 100);
|
||||||
|
// obj.value = rate.toFixed(2);
|
||||||
|
data.push(obj)
|
||||||
|
});
|
||||||
|
that.config.data = data;
|
||||||
|
that.processRate = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
//人员到岗情况列表
|
||||||
|
getUserList() {
|
||||||
|
let that = this;
|
||||||
|
that.listUser = false;
|
||||||
|
getEmployee({page: 0,type:'big_screen'}).then((response) => {
|
||||||
|
if (response.data) {
|
||||||
|
let list = response.data.results;
|
||||||
|
let data = [];
|
||||||
|
list.forEach(item => {
|
||||||
|
let obj = [];
|
||||||
|
obj.push(item.name);
|
||||||
|
obj.push(item.dept_.name);
|
||||||
|
if (item.is_atwork) {
|
||||||
|
obj.push("<span class='colorGrass'>已到岗</span>")
|
||||||
|
} else {
|
||||||
|
obj.push("<span class='colorRed'>未到岗</span>")
|
||||||
|
}
|
||||||
|
data.push(obj)
|
||||||
|
});
|
||||||
|
that.userConfig.data = data;
|
||||||
|
that.listUser = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<img class="faceLoginBtn" src="./../../assets/face.png" @click="takePhoto()">
|
<img class="faceLoginBtn" src="./../../assets/face.png" @click="takePhoto()">
|
||||||
</div>
|
</div>
|
||||||
<div style="width: 360px;">
|
<div style="width: 360px;">
|
||||||
<h3 class="title">航玻生产管理系统</h3>
|
<h3 class="title" @click="toBigScreen">航玻生产管理系统</h3>
|
||||||
<el-tabs v-model="activeName" :stretch="true">
|
<el-tabs v-model="activeName" :stretch="true">
|
||||||
<el-tab-pane label="账号密码登录">
|
<el-tab-pane label="账号密码登录">
|
||||||
<el-form
|
<el-form
|
||||||
|
@ -135,6 +135,9 @@
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
toBigScreen(){
|
||||||
|
this.$router.push('/index')
|
||||||
|
},
|
||||||
showPwd() {
|
showPwd() {
|
||||||
if (this.passwordType === "password") {
|
if (this.passwordType === "password") {
|
||||||
this.passwordType = "";
|
this.passwordType = "";
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
from django.contrib import admin
|
||||||
|
|
||||||
|
# Register your models here.
|
|
@ -0,0 +1,6 @@
|
||||||
|
from django.apps import AppConfig
|
||||||
|
|
||||||
|
|
||||||
|
class CmsConfig(AppConfig):
|
||||||
|
name = 'apps.cms'
|
||||||
|
verbose_name = '内容管理'
|
|
@ -0,0 +1,37 @@
|
||||||
|
# Generated by Django 3.2.9 on 2022-03-16 02:25
|
||||||
|
|
||||||
|
from django.conf import settings
|
||||||
|
from django.db import migrations, models
|
||||||
|
import django.db.models.deletion
|
||||||
|
import django.utils.timezone
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
initial = True
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='Article',
|
||||||
|
fields=[
|
||||||
|
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('create_time', models.DateTimeField(default=django.utils.timezone.now, help_text='创建时间', verbose_name='创建时间')),
|
||||||
|
('update_time', models.DateTimeField(auto_now=True, help_text='修改时间', verbose_name='修改时间')),
|
||||||
|
('is_deleted', models.BooleanField(default=False, help_text='删除标记', verbose_name='删除标记')),
|
||||||
|
('title', models.CharField(max_length=100, verbose_name='标题')),
|
||||||
|
('content', models.TextField(verbose_name='内容')),
|
||||||
|
('author', models.CharField(blank=True, max_length=100, null=True, verbose_name='作者')),
|
||||||
|
('is_top', models.BooleanField(default=False, verbose_name='是否置顶')),
|
||||||
|
('is_published', models.BooleanField(default=False, verbose_name='是否发布')),
|
||||||
|
('create_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='article_create_by', to=settings.AUTH_USER_MODEL, verbose_name='创建人')),
|
||||||
|
('update_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='article_update_by', to=settings.AUTH_USER_MODEL, verbose_name='最后编辑人')),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'abstract': False,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
]
|
|
@ -0,0 +1,12 @@
|
||||||
|
from django.db import models
|
||||||
|
from apps.system.models import CommonAModel
|
||||||
|
# Create your models here.
|
||||||
|
class Article(CommonAModel):
|
||||||
|
"""
|
||||||
|
文章
|
||||||
|
"""
|
||||||
|
title = models.CharField('标题', max_length=100)
|
||||||
|
content = models.TextField('内容')
|
||||||
|
author = models.CharField('作者', max_length=100, null=True, blank=True)
|
||||||
|
is_top = models.BooleanField('是否置顶', default=False)
|
||||||
|
is_published = models.BooleanField('是否发布', default=False)
|
|
@ -0,0 +1,21 @@
|
||||||
|
from rest_framework import serializers
|
||||||
|
from apps.cms.models import Article
|
||||||
|
from apps.system.serializers import UserSimpleSerializer
|
||||||
|
|
||||||
|
class ArticleListSerializer(serializers.ModelSerializer):
|
||||||
|
create_by_ = UserSimpleSerializer(source='create_by', read_only=True)
|
||||||
|
class Meta:
|
||||||
|
model = Article
|
||||||
|
exclude = ['content']
|
||||||
|
|
||||||
|
class ArticleCreateUpdateSerializer(serializers.ModelSerializer):
|
||||||
|
class Meta:
|
||||||
|
model = Article
|
||||||
|
fields = ['title', 'content', 'author', 'is_published', 'is_top']
|
||||||
|
|
||||||
|
|
||||||
|
class ArticleDetailSerializer(serializers.ModelSerializer):
|
||||||
|
create_by_ = UserSimpleSerializer(source='create_by', read_only=True)
|
||||||
|
class Meta:
|
||||||
|
model = Article
|
||||||
|
fields = '__all__'
|
|
@ -0,0 +1,3 @@
|
||||||
|
from django.test import TestCase
|
||||||
|
|
||||||
|
# Create your tests here.
|
|
@ -0,0 +1,10 @@
|
||||||
|
from rest_framework.routers import DefaultRouter
|
||||||
|
from django.urls import path, include
|
||||||
|
from apps.cms.views import ArticleViewSet
|
||||||
|
|
||||||
|
router = DefaultRouter()
|
||||||
|
router.register('article', ArticleViewSet, basename='article')
|
||||||
|
|
||||||
|
urlpatterns = [
|
||||||
|
path('', include(router.urls)),
|
||||||
|
]
|
|
@ -0,0 +1,26 @@
|
||||||
|
from django.shortcuts import render
|
||||||
|
from rest_framework.viewsets import ModelViewSet
|
||||||
|
|
||||||
|
from apps.cms.models import Article
|
||||||
|
from apps.cms.serializers import ArticleCreateUpdateSerializer, ArticleDetailSerializer, ArticleListSerializer
|
||||||
|
from apps.system.mixins import CreateUpdateModelAMixin
|
||||||
|
# Create your views here.
|
||||||
|
|
||||||
|
class ArticleViewSet(CreateUpdateModelAMixin, ModelViewSet):
|
||||||
|
"""
|
||||||
|
文章增删改查
|
||||||
|
"""
|
||||||
|
perms_map = {'get': '*', 'post': 'article_create'
|
||||||
|
, 'put':'article_update', 'delete':'article_delete'}
|
||||||
|
queryset = Article.objects.select_related('create_by')
|
||||||
|
filterset_fields = ['is_top', 'is_published']
|
||||||
|
serializer_class = ArticleListSerializer
|
||||||
|
search_fields = ['title', 'author']
|
||||||
|
ordering = ['is_published', 'is_top', 'update_time']
|
||||||
|
|
||||||
|
def get_serializer_class(self):
|
||||||
|
if self.action in ['create', 'update']:
|
||||||
|
return ArticleCreateUpdateSerializer
|
||||||
|
elif self.action in ['retrieve']:
|
||||||
|
return ArticleDetailSerializer
|
||||||
|
return super().get_serializer_class()
|
|
@ -121,6 +121,12 @@ class UpdateFIFONumber(APIView):
|
||||||
i.save()
|
i.save()
|
||||||
return Response()
|
return Response()
|
||||||
|
|
||||||
|
class CorrectWproduct(APIView):
|
||||||
|
permission_classes = [IsAdminUser]
|
||||||
|
def post(self, request):
|
||||||
|
"""
|
||||||
|
"""
|
||||||
|
# WProduct.objects.filter(is_hidden=True).update(act_state=WProduct.WPR_ACT_STATE_USED)
|
||||||
|
|
||||||
|
|
||||||
class ReloadServer(APIView):
|
class ReloadServer(APIView):
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
# Generated by Django 3.2.9 on 2022-03-15 07:00
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('em', '0012_auto_20220120_1048'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='equipment',
|
||||||
|
name='state',
|
||||||
|
field=models.PositiveIntegerField(choices=[(10, '完好'), (20, '限用'), (30, '在修'), (40, '禁用'), (50, '报废')], default=0, verbose_name='设备状态'),
|
||||||
|
),
|
||||||
|
]
|
|
@ -1,4 +1,4 @@
|
||||||
from django.db.models import base
|
|
||||||
from rest_framework import urlpatterns
|
from rest_framework import urlpatterns
|
||||||
from apps.hrm.views import ClockRecordViewSet, EmployeeViewSet, FaceLogin, NotWorkRemarkViewSet
|
from apps.hrm.views import ClockRecordViewSet, EmployeeViewSet, FaceLogin, NotWorkRemarkViewSet
|
||||||
from django.urls import path, include
|
from django.urls import path, include
|
||||||
|
|
|
@ -23,10 +23,11 @@ class MbFilterSet(DynamicFieldsFilterMixin, filters.FilterSet):
|
||||||
class IProductFilterSet(DynamicFieldsFilterMixin, filters.FilterSet):
|
class IProductFilterSet(DynamicFieldsFilterMixin, filters.FilterSet):
|
||||||
order = filters.NumberFilter(field_name="wproduct__subproduction_plan__production_plan__order")
|
order = filters.NumberFilter(field_name="wproduct__subproduction_plan__production_plan__order")
|
||||||
to_order = filters.NumberFilter(field_name="wproduct__to_order")
|
to_order = filters.NumberFilter(field_name="wproduct__to_order")
|
||||||
|
to_order_need_mtest = filters.BooleanFilter(field_name="wproduct__to_order__need_mtest")
|
||||||
need_to_order = filters.BooleanFilter(field_name="wproduct__need_to_order")
|
need_to_order = filters.BooleanFilter(field_name="wproduct__need_to_order")
|
||||||
update_time_start = filters.DateFilter(field_name="update_time", lookup_expr='gte')
|
update_time_start = filters.DateFilter(field_name="update_time", lookup_expr='gte')
|
||||||
update_time_end = filters.DateFilter(field_name="update_time", lookup_expr='lte')
|
update_time_end = filters.DateFilter(field_name="update_time", lookup_expr='lte')
|
||||||
class Meta:
|
class Meta:
|
||||||
model = IProduct
|
model = IProduct
|
||||||
fields = ['material', 'warehouse', 'batch', 'order', 'material__type', 'update_time_start', 'update_time_end',
|
fields = ['material', 'warehouse', 'batch', 'order', 'material__type', 'update_time_start', 'update_time_end',
|
||||||
'to_order', 'need_to_order', 'state']
|
'to_order', 'need_to_order', 'state', 'to_order_need_mtest']
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
# Generated by Django 3.2.9 on 2022-03-15 07:00
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
import django.db.models.deletion
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('sam', '0016_sale_iproducts'),
|
||||||
|
('inm', '0033_fifoitem_expiration_date'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='fifo',
|
||||||
|
name='sale',
|
||||||
|
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='fifo_sale', to='sam.sale', verbose_name='关联销售记录'),
|
||||||
|
),
|
||||||
|
]
|
|
@ -2,6 +2,7 @@ from rest_framework import exceptions
|
||||||
from rest_framework import serializers
|
from rest_framework import serializers
|
||||||
|
|
||||||
from apps.inm.models import FIFO, FIFOItem, FIFOItemProduct, IProduct, MaterialBatch, WareHouse, Inventory
|
from apps.inm.models import FIFO, FIFOItem, FIFOItemProduct, IProduct, MaterialBatch, WareHouse, Inventory
|
||||||
|
from apps.mtm.models import Material
|
||||||
from apps.pum.models import PuOrder, Vendor
|
from apps.pum.models import PuOrder, Vendor
|
||||||
from apps.qm.models import TestRecord, TestRecordItem
|
from apps.qm.models import TestRecord, TestRecordItem
|
||||||
from apps.sam.serializers import OrderSimpleSerializer
|
from apps.sam.serializers import OrderSimpleSerializer
|
||||||
|
@ -173,6 +174,8 @@ class FIFOOutOtherSerializer(serializers.ModelSerializer):
|
||||||
obj.save()
|
obj.save()
|
||||||
for i in details:
|
for i in details:
|
||||||
mb = i.pop('material_batch')
|
mb = i.pop('material_batch')
|
||||||
|
if mb.material.type in [Material.MA_TYPE_GOOD, Material.MA_TYPE_HALFGOOD]:
|
||||||
|
raise ValidationError('不可直接出成品或半成品')
|
||||||
i['material'] = mb.material
|
i['material'] = mb.material
|
||||||
i['batch'] = mb.batch
|
i['batch'] = mb.batch
|
||||||
i['warehouse'] = mb.warehouse
|
i['warehouse'] = mb.warehouse
|
||||||
|
|
|
@ -6,6 +6,8 @@ from apps.sam.models import SalePack, SaleProduct
|
||||||
from django.db.models import Count
|
from django.db.models import Count
|
||||||
from django.db.models.aggregates import Sum
|
from django.db.models.aggregates import Sum
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
|
from apps.wpm.services import WpmService
|
||||||
logger = logging.getLogger('log')
|
logger = logging.getLogger('log')
|
||||||
|
|
||||||
class InmService:
|
class InmService:
|
||||||
|
@ -133,8 +135,10 @@ class InmService:
|
||||||
|
|
||||||
# 更新动态产品表情况
|
# 更新动态产品表情况
|
||||||
from apps.wpm.models import WProduct
|
from apps.wpm.models import WProduct
|
||||||
WProduct.objects.filter(id__in=ips.values_list('wproduct', flat=True)).update(
|
wps = WProduct.objects.filter(id__in=ips.values_list('wproduct', flat=True))
|
||||||
|
wps.update(
|
||||||
act_state=WProduct.WPR_ACT_STATE_SELLED)
|
act_state=WProduct.WPR_ACT_STATE_SELLED)
|
||||||
|
WpmService.add_wproducts_flow_log(instances=wps, change_str='selled')
|
||||||
|
|
||||||
# 变更销售记录实际发货数
|
# 变更销售记录实际发货数
|
||||||
sale.count_real = ips.count()
|
sale.count_real = ips.count()
|
||||||
|
|
|
@ -163,6 +163,7 @@ class FIFOViewSet(ListModelMixin, DestroyModelMixin, GenericViewSet):
|
||||||
return super().destroy(request, *args, **kwargs)
|
return super().destroy(request, *args, **kwargs)
|
||||||
|
|
||||||
@action(methods=['post'], detail=False, perms_map={'post': 'fifo_in_pur'}, serializer_class=FIFOInPurSerializer)
|
@action(methods=['post'], detail=False, perms_map={'post': 'fifo_in_pur'}, serializer_class=FIFOInPurSerializer)
|
||||||
|
@transaction.atomic()
|
||||||
def in_pur(self, request, pk=None):
|
def in_pur(self, request, pk=None):
|
||||||
"""
|
"""
|
||||||
采购入库
|
采购入库
|
||||||
|
@ -174,6 +175,7 @@ class FIFOViewSet(ListModelMixin, DestroyModelMixin, GenericViewSet):
|
||||||
|
|
||||||
@action(methods=['post'], detail=False, perms_map={'post': 'fifo_in_other'},
|
@action(methods=['post'], detail=False, perms_map={'post': 'fifo_in_other'},
|
||||||
serializer_class=FIFOInOtherSerializer)
|
serializer_class=FIFOInOtherSerializer)
|
||||||
|
@transaction.atomic()
|
||||||
def in_other(self, request, pk=None):
|
def in_other(self, request, pk=None):
|
||||||
"""
|
"""
|
||||||
其他入库
|
其他入库
|
||||||
|
@ -185,6 +187,7 @@ class FIFOViewSet(ListModelMixin, DestroyModelMixin, GenericViewSet):
|
||||||
|
|
||||||
@action(methods=['post'], detail=False, perms_map={'post': 'fifo_out_other'},
|
@action(methods=['post'], detail=False, perms_map={'post': 'fifo_out_other'},
|
||||||
serializer_class=FIFOOutOtherSerializer)
|
serializer_class=FIFOOutOtherSerializer)
|
||||||
|
@transaction.atomic()
|
||||||
def out_other(self, request, pk=None):
|
def out_other(self, request, pk=None):
|
||||||
"""
|
"""
|
||||||
其他出库
|
其他出库
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
|
from email.policy import default
|
||||||
from rest_framework import serializers
|
from rest_framework import serializers
|
||||||
from apps.pm.models import ProductionPlan, SubProductionPlan
|
from apps.pm.models import ProductionPlan, SubProductionPlan
|
||||||
from apps.mtm.serializers import MaterialSimpleSerializer, ProcessSimpleSerializer
|
from apps.mtm.serializers import MaterialSimpleSerializer, ProcessSimpleSerializer
|
||||||
|
from apps.system.models import Organization
|
||||||
|
|
||||||
class SubplanGanttSerializer(serializers.ModelSerializer):
|
class SubplanGanttSerializer(serializers.ModelSerializer):
|
||||||
process_ = ProcessSimpleSerializer(source='process', read_only=True)
|
process_ = ProcessSimpleSerializer(source='process', read_only=True)
|
||||||
|
@ -25,6 +27,19 @@ class ProcessYieldSerializer(serializers.Serializer):
|
||||||
datetime_start = serializers.DateField(label='开始时间', required=False, allow_null=True)
|
datetime_start = serializers.DateField(label='开始时间', required=False, allow_null=True)
|
||||||
datetime_end = serializers.DateField(label='结束时间', required=False, allow_null=True)
|
datetime_end = serializers.DateField(label='结束时间', required=False, allow_null=True)
|
||||||
|
|
||||||
|
class SrmCountSerializer(serializers.Serializer):
|
||||||
|
datetime_start = serializers.DateField(label='开始时间', required=False, allow_null=True)
|
||||||
|
datetime_end = serializers.DateField(label='结束时间', required=False, allow_null=True)
|
||||||
|
|
||||||
|
class ProductCountSerializer(serializers.Serializer):
|
||||||
|
tag_choices=(
|
||||||
|
(1, '统计成品'),
|
||||||
|
(2, '统计全部')
|
||||||
|
)
|
||||||
|
datetime_start = serializers.DateField(label='开始时间', required=False, allow_null=True)
|
||||||
|
datetime_end = serializers.DateField(label='结束时间', required=False, allow_null=True)
|
||||||
|
tag = serializers.ChoiceField(choices=tag_choices, label='统计范围1成品2全部', default=1)
|
||||||
|
dept = serializers.PrimaryKeyRelatedField(queryset=Organization.objects.all(), label="车间", required=False)
|
||||||
|
|
||||||
class AtWorkCountSerializer(serializers.Serializer):
|
class AtWorkCountSerializer(serializers.Serializer):
|
||||||
year = serializers.IntegerField(label='年')
|
year = serializers.IntegerField(label='年')
|
||||||
|
|
|
@ -0,0 +1,74 @@
|
||||||
|
from apps.mtm.models import Material
|
||||||
|
from apps.pm.models import ProductionPlan
|
||||||
|
from apps.sam.models import Order
|
||||||
|
from apps.wpm.models import WProduct, WproductFlow
|
||||||
|
from django.db.models import F
|
||||||
|
from apps.wpm.serializers import WProductDetailSerializer
|
||||||
|
class SrmServices:
|
||||||
|
"""
|
||||||
|
数据统计分析
|
||||||
|
"""
|
||||||
|
@classmethod
|
||||||
|
def get_product_count(cls, datetime_start=None, datetime_end=None, tag=1, dept=None):
|
||||||
|
"""
|
||||||
|
根据生产情况统计相关数量
|
||||||
|
"""
|
||||||
|
if tag == 1:
|
||||||
|
objs = WproductFlow.objects.filter(is_lastlog=True, material__type=Material.MA_TYPE_GOOD)
|
||||||
|
else:
|
||||||
|
objs = WproductFlow.objects.filter(is_lastlog=True)
|
||||||
|
if datetime_start:
|
||||||
|
objs = objs.filter(create_time__gte=datetime_start)
|
||||||
|
if datetime_end:
|
||||||
|
objs = objs.filter(create_time__lte=datetime_end)
|
||||||
|
if dept:
|
||||||
|
objs = objs.filter(subproduction_plan__workshop=dept)
|
||||||
|
count = objs.count()
|
||||||
|
count_ok = objs.filter(act_state__in=[WProduct.WPR_ACT_STATE_INM,
|
||||||
|
WProduct.WPR_ACT_STATE_OK, WProduct.WPR_ACT_STATE_SELLED]).count()
|
||||||
|
# count_notok = objs.filter(act_state__in=[WProduct.WPR_ACT_STATE_NOTOK, WProduct.WPR_ACT_STATE_SCRAP]).count()
|
||||||
|
count_notok = (
|
||||||
|
objs.filter(act_state__in=[WProduct.WPR_ACT_STATE_NOTOK, WProduct.WPR_ACT_STATE_SCRAP]).exclude(step__process__id=1)
|
||||||
|
| objs.filter(act_state__in=[WProduct.WPR_ACT_STATE_NOTOK, WProduct.WPR_ACT_STATE_SCRAP],
|
||||||
|
step__process__id=1).exclude(number=None)
|
||||||
|
).count()
|
||||||
|
count_selled = objs.filter(act_state=WProduct.WPR_ACT_STATE_SELLED).count()
|
||||||
|
count_mtestok = objs.filter(is_mtestok=True).count()
|
||||||
|
count_mtestnotok = objs.filter(is_mtestok=False).count()
|
||||||
|
count_doing = objs.filter(act_state__in=[
|
||||||
|
WProduct.WPR_ACT_STATE_TOTEST, WProduct.WPR_ACT_STATE_TOCOMBTEST, WProduct.WPR_ACT_STATE_TOFINALTEST,
|
||||||
|
WProduct.WPR_ACT_STATE_TORETEST, WProduct.WPR_ACT_STATE_DOWAIT, WProduct.WPR_ACT_STATE_DOING
|
||||||
|
], subproduction_plan__product=F('material')).count()
|
||||||
|
return dict(count=count,count_ok=count_ok, count_notok=count_notok,
|
||||||
|
count_selled=count_selled, count_mtestok=count_mtestok, count_mtestnotok=count_mtestnotok, count_doing=count_doing)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_plan_count(cls, datetime_start=None, datetime_end=None):
|
||||||
|
"""
|
||||||
|
任务数量
|
||||||
|
"""
|
||||||
|
objs = ProductionPlan.objects.all()
|
||||||
|
if datetime_start:
|
||||||
|
objs = objs.filter(end_date__gte=datetime_start)
|
||||||
|
if datetime_end:
|
||||||
|
objs = objs.filter(end_date__lte=datetime_end)
|
||||||
|
count = objs.count()
|
||||||
|
count_use = objs.exclude(state__in=[ProductionPlan.PLAN_STATE_PAUSE, ProductionPlan.PLAN_STATE_STOP]).count()
|
||||||
|
count_completed = objs.filter(state__in=[ProductionPlan.PLAN_STATE_DONE, ProductionPlan.PLAN_MTEST_DONE]).count()
|
||||||
|
return dict(count=count, count_use=count_use, count_completed=count_completed)
|
||||||
|
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_order_count(cls, datetime_start=None, datetime_end=None):
|
||||||
|
"""
|
||||||
|
订单数量
|
||||||
|
"""
|
||||||
|
objs = Order.objects.all()
|
||||||
|
if datetime_start:
|
||||||
|
objs = objs.filter(delivery_date__gte=datetime_start)
|
||||||
|
if datetime_end:
|
||||||
|
objs = objs.filter(delivery_date__lte=datetime_end)
|
||||||
|
count = objs.count()
|
||||||
|
count_delivered = objs.filter(delivered_count__gte=F('count')).count()
|
||||||
|
return dict(count=count, count_delivered=count_delivered)
|
||||||
|
|
|
@ -3,12 +3,16 @@ from rest_framework import urlpatterns
|
||||||
from django.urls import path, include
|
from django.urls import path, include
|
||||||
from rest_framework.routers import DefaultRouter
|
from rest_framework.routers import DefaultRouter
|
||||||
|
|
||||||
from apps.srm.views import AtWorkCountView, GanttPlan, ProcessYieldView
|
from apps.srm.views import AtWorkCountView, GanttPlan, OrderCountView, PlanCountView, ProcessNowView, ProcessYieldView, ProductCountView
|
||||||
|
|
||||||
router = DefaultRouter()
|
router = DefaultRouter()
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path('gantt/plan/', GanttPlan.as_view()),
|
path('gantt/plan/', GanttPlan.as_view()),
|
||||||
|
path('product/count/', ProductCountView.as_view()),
|
||||||
|
path('plan/count/', PlanCountView.as_view()),
|
||||||
|
path('order/count/', OrderCountView.as_view()),
|
||||||
path('process/yield/', ProcessYieldView.as_view()),
|
path('process/yield/', ProcessYieldView.as_view()),
|
||||||
|
path('process/now/', ProcessNowView.as_view()),
|
||||||
path('at_work/', AtWorkCountView.as_view()),
|
path('at_work/', AtWorkCountView.as_view()),
|
||||||
path('', include(router.urls)),
|
path('', include(router.urls)),
|
||||||
]
|
]
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
|
|
||||||
from datetime import date, timedelta
|
from datetime import date, timedelta
|
||||||
from django.shortcuts import render
|
from django.shortcuts import render
|
||||||
|
from idna import valid_contextj
|
||||||
from numpy import number
|
from numpy import number
|
||||||
from rest_framework import serializers
|
from rest_framework import serializers
|
||||||
from rest_framework.generics import ListAPIView, CreateAPIView
|
from rest_framework.generics import ListAPIView, CreateAPIView
|
||||||
|
@ -9,9 +10,10 @@ from rest_framework.response import Response
|
||||||
from apps.hrm.models import ClockRecord
|
from apps.hrm.models import ClockRecord
|
||||||
from apps.mtm.models import Process, Step
|
from apps.mtm.models import Process, Step
|
||||||
from apps.pm.models import ProductionPlan, SubProductionPlan
|
from apps.pm.models import ProductionPlan, SubProductionPlan
|
||||||
from apps.srm.serializers import AtWorkCountSerializer, PlanGanttSerializer, ProcessYieldSerializer
|
from apps.srm.serializers import AtWorkCountSerializer, PlanGanttSerializer, ProcessYieldSerializer, ProductCountSerializer, SrmCountSerializer
|
||||||
|
from apps.srm.services import SrmServices
|
||||||
from apps.wpm.models import WProduct, WproductFlow
|
from apps.wpm.models import WProduct, WproductFlow
|
||||||
from django.db.models import Count, F
|
from django.db.models import Count, F, Sum
|
||||||
# Create your views here.
|
# Create your views here.
|
||||||
|
|
||||||
class GanttPlan(ListAPIView):
|
class GanttPlan(ListAPIView):
|
||||||
|
@ -23,6 +25,62 @@ class GanttPlan(ListAPIView):
|
||||||
queryset = ProductionPlan.objects.filter(is_deleted=False, is_planed=True).prefetch_related('subplan_plan', 'subplan_plan__process')
|
queryset = ProductionPlan.objects.filter(is_deleted=False, is_planed=True).prefetch_related('subplan_plan', 'subplan_plan__process')
|
||||||
ordering = ['-id']
|
ordering = ['-id']
|
||||||
|
|
||||||
|
class ProductCountView(CreateAPIView):
|
||||||
|
"""
|
||||||
|
产品数量统计
|
||||||
|
"""
|
||||||
|
perms_map = {'post':'*'}
|
||||||
|
serializer_class = ProductCountSerializer
|
||||||
|
def create(self, request, *args, **kwargs):
|
||||||
|
serializer = self.get_serializer(data=request.data)
|
||||||
|
serializer.is_valid(raise_exception=True)
|
||||||
|
vdata = serializer.validated_data
|
||||||
|
res = SrmServices.get_product_count(**vdata)
|
||||||
|
return Response(res)
|
||||||
|
|
||||||
|
|
||||||
|
class PlanCountView(CreateAPIView):
|
||||||
|
"""
|
||||||
|
计划数量统计
|
||||||
|
"""
|
||||||
|
perms_map = {'post':'*'}
|
||||||
|
serializer_class = SrmCountSerializer
|
||||||
|
|
||||||
|
def create(self, request, *args, **kwargs):
|
||||||
|
serializer = self.get_serializer(data=request.data)
|
||||||
|
serializer.is_valid(raise_exception=True)
|
||||||
|
vdata = serializer.validated_data
|
||||||
|
res = SrmServices.get_plan_count(**vdata)
|
||||||
|
return Response(res)
|
||||||
|
|
||||||
|
class OrderCountView(CreateAPIView):
|
||||||
|
"""
|
||||||
|
订单数量统计
|
||||||
|
"""
|
||||||
|
perms_map = {'post':'*'}
|
||||||
|
serializer_class = SrmCountSerializer
|
||||||
|
|
||||||
|
def create(self, request, *args, **kwargs):
|
||||||
|
serializer = self.get_serializer(data=request.data)
|
||||||
|
serializer.is_valid(raise_exception=True)
|
||||||
|
vdata = serializer.validated_data
|
||||||
|
res = SrmServices.get_order_count(**vdata)
|
||||||
|
return Response(res)
|
||||||
|
|
||||||
|
class ProcessNowView(CreateAPIView):
|
||||||
|
"""
|
||||||
|
工序当前进度
|
||||||
|
"""
|
||||||
|
perms_map = {'post':'*'}
|
||||||
|
serializer_class = serializers.Serializer
|
||||||
|
|
||||||
|
def create(self, request, *args, **kwargs):
|
||||||
|
objs = SubProductionPlan.objects.filter(production_plan__state__in =[ProductionPlan.PLAN_STATE_WORKING,
|
||||||
|
ProductionPlan.PLAN_STATE_ASSGINED]).order_by('process__number').values('process',
|
||||||
|
'process__name').annotate(count_ok=Sum('count_ok'),
|
||||||
|
count=Sum('count'), count_real=Sum('count_real'), count_notok=Sum('count_notok'))
|
||||||
|
return Response(objs)
|
||||||
|
|
||||||
class ProcessYieldView(CreateAPIView):
|
class ProcessYieldView(CreateAPIView):
|
||||||
"""
|
"""
|
||||||
工序成品率统计
|
工序成品率统计
|
||||||
|
|
|
@ -33,6 +33,7 @@ class WProductFilterSet(DynamicFieldsFilterMixin, filters.FilterSet):
|
||||||
tag = filters.CharFilter(method='filter_tag')
|
tag = filters.CharFilter(method='filter_tag')
|
||||||
production_plan = filters.NumberFilter(
|
production_plan = filters.NumberFilter(
|
||||||
field_name='subproduction_plan__production_plan')
|
field_name='subproduction_plan__production_plan')
|
||||||
|
to_order_need_mtest = filters.BooleanFilter(field_name="to_order__need_mtest")
|
||||||
def filter_fields(self, queryset, name, value):
|
def filter_fields(self, queryset, name, value):
|
||||||
return queryset
|
return queryset
|
||||||
|
|
||||||
|
@ -41,7 +42,7 @@ class WProductFilterSet(DynamicFieldsFilterMixin, filters.FilterSet):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = WProduct
|
model = WProduct
|
||||||
fields = ['step', 'subproduction_plan', 'material',
|
fields = ['step', 'subproduction_plan', 'material',
|
||||||
'step__process', 'act_state', 'material__type', 'need_to_order']
|
'step__process', 'act_state', 'material__type', 'need_to_order', 'to_order_need_mtest']
|
||||||
|
|
||||||
def filter_tag(self, queryset, name, value):
|
def filter_tag(self, queryset, name, value):
|
||||||
if value == 'no_scrap':
|
if value == 'no_scrap':
|
||||||
|
|
|
@ -0,0 +1,28 @@
|
||||||
|
# Generated by Django 3.2.9 on 2022-03-15 07:00
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('wpm', '0053_auto_20220129_1512'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='operationequip',
|
||||||
|
name='state',
|
||||||
|
field=models.PositiveSmallIntegerField(choices=[(10, '完好'), (20, '限用'), (30, '在修'), (40, '禁用'), (50, '报废')], default=10, verbose_name='当前设备状态'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='wproduct',
|
||||||
|
name='act_state',
|
||||||
|
field=models.IntegerField(choices=[(6, '待复检'), (8, '操作准备中'), (10, '操作进行中'), (20, '待检验'), (26, '待夹层检验'), (30, '已合格'), (40, '已入库'), (50, '不合格'), (60, '待成品检验'), (70, '已报废'), (80, '已售出'), (90, '已使用')], default=0, verbose_name='进行状态'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='wproductflow',
|
||||||
|
name='act_state',
|
||||||
|
field=models.IntegerField(choices=[(6, '待复检'), (8, '操作准备中'), (10, '操作进行中'), (20, '待检验'), (26, '待夹层检验'), (30, '已合格'), (40, '已入库'), (50, '不合格'), (60, '待成品检验'), (70, '已报废'), (80, '已售出'), (90, '已使用')], default=0, verbose_name='进行状态'),
|
||||||
|
),
|
||||||
|
]
|
|
@ -43,6 +43,7 @@ class WProduct(CommonAModel):
|
||||||
WPR_ACT_STATE_TOFINALTEST = 60
|
WPR_ACT_STATE_TOFINALTEST = 60
|
||||||
WPR_ACT_STATE_SCRAP = 70
|
WPR_ACT_STATE_SCRAP = 70
|
||||||
WPR_ACT_STATE_SELLED = 80
|
WPR_ACT_STATE_SELLED = 80
|
||||||
|
WPR_ACT_STATE_USED = 90
|
||||||
act_state_choices = (
|
act_state_choices = (
|
||||||
(WPR_ACT_STATE_TORETEST, '待复检'),
|
(WPR_ACT_STATE_TORETEST, '待复检'),
|
||||||
(WPR_ACT_STATE_DOWAIT, '操作准备中'),
|
(WPR_ACT_STATE_DOWAIT, '操作准备中'),
|
||||||
|
@ -55,6 +56,7 @@ class WProduct(CommonAModel):
|
||||||
(WPR_ACT_STATE_TOFINALTEST, '待成品检验'),
|
(WPR_ACT_STATE_TOFINALTEST, '待成品检验'),
|
||||||
(WPR_ACT_STATE_SCRAP, '已报废'),
|
(WPR_ACT_STATE_SCRAP, '已报废'),
|
||||||
(WPR_ACT_STATE_SELLED, '已售出'),
|
(WPR_ACT_STATE_SELLED, '已售出'),
|
||||||
|
(WPR_ACT_STATE_USED, '已使用'),
|
||||||
)
|
)
|
||||||
SCRAP_REASON_QIPAO = 10
|
SCRAP_REASON_QIPAO = 10
|
||||||
SCRAP_REASON_PODIAN = 20
|
SCRAP_REASON_PODIAN = 20
|
||||||
|
|
|
@ -167,6 +167,23 @@ class WpmService(object):
|
||||||
ins.change_str = change_str
|
ins.change_str = change_str
|
||||||
ins.save()
|
ins.save()
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def add_wproducts_flow_log(cls, instances, change_str=''):
|
||||||
|
"""
|
||||||
|
批量创建产品变动日志
|
||||||
|
"""
|
||||||
|
WproductFlow.objects.filter(wproduct__in=instances).update(is_lastlog=False)
|
||||||
|
wfw = []
|
||||||
|
for i in instances:
|
||||||
|
ins = WproductFlow()
|
||||||
|
ins.wproduct = i
|
||||||
|
for f in WproductFlow.__meta.fields:
|
||||||
|
if f.name not in ['id', 'wproduct', 'is_lastlog']:
|
||||||
|
setattr(ins, f.name, getattr(i, f.name, None))
|
||||||
|
ins.change_str = change_str
|
||||||
|
wfw.append(ins)
|
||||||
|
WproductFlow.objects.bulk_create(wfw)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def update_cutting_list_with_operation(cls, op:Operation):
|
def update_cutting_list_with_operation(cls, op:Operation):
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -781,8 +781,9 @@ class OperationViewSet(ListModelMixin, RetrieveModelMixin, CreateModelMixin, Upd
|
||||||
WpmService.add_wproduct_flow_log(wproduct, 'wproduct_create')
|
WpmService.add_wproduct_flow_log(wproduct, 'wproduct_create')
|
||||||
# 隐藏原半成品
|
# 隐藏原半成品
|
||||||
wps = WProduct.objects.filter(ow_wproduct__operation=op)
|
wps = WProduct.objects.filter(ow_wproduct__operation=op)
|
||||||
wps.update(is_hidden=True, child=wproduct,
|
wps.update(act_state=WProduct.WPR_ACT_STATE_USED, child=wproduct, is_hidden=True,
|
||||||
update_by=request.user, update_time=timezone.now())
|
update_by=request.user, update_time=timezone.now())
|
||||||
|
WpmService.add_wproducts_flow_log(wps, change_str='wproduct_create')
|
||||||
else:
|
else:
|
||||||
raise exceptions.APIException('产出物料未填写或填写错误')
|
raise exceptions.APIException('产出物料未填写或填写错误')
|
||||||
op.is_submited = True
|
op.is_submited = True
|
||||||
|
|
|
@ -60,7 +60,8 @@ INSTALLED_APPS = [
|
||||||
'apps.pm',
|
'apps.pm',
|
||||||
'apps.wpm',
|
'apps.wpm',
|
||||||
'apps.srm',
|
'apps.srm',
|
||||||
'apps.develop'
|
'apps.develop',
|
||||||
|
'apps.cms'
|
||||||
]
|
]
|
||||||
|
|
||||||
X_FRAME_OPTIONS = 'SAMEORIGIN'
|
X_FRAME_OPTIONS = 'SAMEORIGIN'
|
||||||
|
|
|
@ -72,6 +72,7 @@ urlpatterns = [
|
||||||
path('api/wpm/', include('apps.wpm.urls')),
|
path('api/wpm/', include('apps.wpm.urls')),
|
||||||
path('api/srm/', include('apps.srm.urls')),
|
path('api/srm/', include('apps.srm.urls')),
|
||||||
path('api/develop/', include('apps.develop.urls')),
|
path('api/develop/', include('apps.develop.urls')),
|
||||||
|
path('api/cms/', include('apps.cms.urls')),
|
||||||
|
|
||||||
# 工具
|
# 工具
|
||||||
path('api/utils/signature/', GenSignature.as_view()),
|
path('api/utils/signature/', GenSignature.as_view()),
|
||||||
|
|
Loading…
Reference in New Issue