Merge branch 'develop' of https://e.coding.net/ctcdevteam/hberp/hberp into develop

This commit is contained in:
unknown 2021-09-14 09:49:55 +08:00
commit 876b9a6263
20 changed files with 918 additions and 111 deletions

View File

@ -2,8 +2,8 @@
ENV = 'development'
# base api
#VUE_APP_BASE_API = 'http://localhost:8000/api'
VUE_APP_BASE_API = 'http://47.95.0.242:2222/api'
VUE_APP_BASE_API = 'http://127.0.0.1:8000/api'
#VUE_APP_BASE_API = 'http://47.95.0.242:2222/api'
# vue-cli uses the VUE_CLI_BABEL_TRANSPILE_MODULES environment variable,

View File

@ -30,6 +30,7 @@
"vue-json-editor": "^1.4.3",
"vue-router": "^3.5.2",
"vuex": "^3.6.2",
"webpack-dev-server": "^4.2.0",
"xlsx": "^0.17.1"
},
"devDependencies": {

59
hb_client/src/api/sam.js Normal file
View File

@ -0,0 +1,59 @@
import request from '@/utils/request'
//客户
export function getCustomerList(query) {
return request({
url: '/sam/customer/',
method: 'get',
params: query
})
}
export function createCustomer(data) {
return request({
url: '/sam/customer/',
method: 'post',
data
})
}
export function updateCustomer(id, data) {
return request({
url: `/sam/customer/${id}/`,
method: 'put',
data
})
}
export function deleteCustomer(id, data) {
return request({
url: `/sam/customer/${id}/`,
method: 'delete',
data
})
}
//合同
export function getContractList(query) {
return request({
url: '/sam/contract/',
method: 'get',
params: query
})
}
export function createContract(data) {
return request({
url: '/sam/contract/',
method: 'post',
data
})
}
export function updateContract(id, data) {
return request({
url: `/sam/contract/${id}/`,
method: 'put',
data
})
}
export function deleteContract(id, data) {
return request({
url: `/sam/contract/${id}/`,
method: 'delete',
data
})
}

View File

@ -80,6 +80,49 @@ export const constantRoutes = [
* the routes that need to be dynamically loaded based on user perms
*/
export const asyncRoutes = [
{
path: '/mtm',
component: Layout,
redirect: '/mtm/material/',
name: 'mtm',
meta: { title: '制造管理', icon: 'example', perms: ['procurement_set'] },
children: [
{
path: 'material',
name: 'material',
component: () => import('@/views/mtm/material'),
meta: { title: '物料清单', icon: 'example', perms: ['vendor_manage'] }
},
{
path: 'process',
name: 'process',
component: () => import('@/views/mtm/process'),
meta: { title: '工序管理', icon: 'example', perms: ['vendor_manage'] }
},
{
path: 'step/:id',
name: 'Step',
component: () => import('@/views/mtm/step.vue'),
meta: { title: '子工序', perms: ['vendor_manage'] },
hidden: true
}
,
{
path: 'stepdo/:id',
name: 'StepDo',
component: () => import('@/views/mtm/stepdo.vue'),
meta: { title: '子工序查看', perms: ['vendor_manage'] },
hidden: true
},
{
path: '/mtm/productprocess/',
name: 'productprocess',
component: () => import('@/views/mtm/productprocess'),
meta: { title: '产品管理', icon: 'example', perms: ['vendor_manage'] }
},
]
},
{
path: '/equipment',
component: Layout,
@ -91,13 +134,34 @@ export const asyncRoutes = [
path: 'index',
name: 'index',
component: () => import('@/views/equipment/index'),
meta: { title: '设备台账', icon: 'example', perms: ['index_manage'] }
meta: { title: '生产设备', icon: 'example', perms: ['index_manage'] }
},
{
path: 'index',
name: 'index',
component: () => import('@/views/equipment/index'),
meta: { title: '运维记录', icon: 'example', perms: ['index_manage'] }
meta: { title: '监视和测量设备', icon: 'example', perms: ['index_manage'] }
}
]
},
{
path: '/sam',
component: Layout,
redirect: '/sam/index',
name: 'sam',
meta: { title: '合同管理', icon: 'example', perms: ['equipment_set'] },
children: [
{
path: 'customer',
name: 'customer',
component: () => import('@/views/sam/customer'),
meta: { title: '客户信息', icon: 'example', perms: ['index_manage'] }
},
{
path: 'contract',
name: 'contract',
component: () => import('@/views/sam/contract'),
meta: { title: '合同信息', icon: 'example', perms: ['index_manage'] }
}
]
},
@ -123,48 +187,6 @@ export const asyncRoutes = [
]
},
{
path: '/mtm',
component: Layout,
redirect: '/mtm/material/',
name: 'mtm',
meta: { title: '制造管理', icon: 'example', perms: ['procurement_set'] },
children: [
{
path: 'material',
name: 'material',
component: () => import('@/views/mtm/material'),
meta: { title: '物料', icon: 'example', perms: ['vendor_manage'] }
},
{
path: 'process',
name: 'process',
component: () => import('@/views/mtm/process'),
meta: { title: '工序', icon: 'example', perms: ['vendor_manage'] }
},
{
path: 'step/:id',
name: 'Step',
component: () => import('@/views/mtm/step.vue'),
meta: { title: '子工序', perms: ['vendor_manage'] },
hidden: true
}
,
{
path: 'stepdo/:id',
name: 'StepDo',
component: () => import('@/views/mtm/stepdo.vue'),
meta: { title: '子工序查看', perms: ['vendor_manage'] },
hidden: true
},
{
path: '/mtm/productprocess/',
name: 'productprocess',
component: () => import('@/views/mtm/productprocess'),
meta: { title: '产品工艺', icon: 'example', perms: ['vendor_manage'] }
},
]
},
{
path: '/procurement',

View File

@ -109,47 +109,39 @@
<el-form
ref="Form"
:model="equipment"
label-width="80px"
label-width="100px"
label-position="right"
:rules="rule1"
>
<el-row>
<el-col :span="11">
<el-form-item label="设备名称" prop="name">
<el-input v-model="equipment.name" placeholder="设备名称" />
</el-form-item>
</el-col>
<el-col :span="11">
<el-form-item label="设备编号" prop="number">
<el-input v-model="equipment.number" placeholder="设备编号" />
</el-form-item>
<el-form-item label="规格型号" prop="model">
<el-input v-model="equipment.model" placeholder="规格型号" />
</el-col>
</el-row>
<el-row>
<el-col :span="11">
<el-form-item label="型号规格" prop="model">
<el-input v-model="equipment.model" placeholder="规格型号规格" />
</el-form-item>
<el-form-item label="类型" prop="type">
<el-select style="width: 100%" v-model="equipment.type" placeholder="请选择">
<el-option
v-for="item in typeoptions"
:key="item.value"
:label="item.label"
:value="item.value">
</el-option>
</el-select>
</el-col>
<el-col :span="11">
<el-form-item label="数量" prop="count">
<el-input v-model="equipment.count" placeholder="数量" />
</el-form-item>
<el-form-item label="设备状态" prop="state">
<el-select style="width: 100%" v-model="equipment.state" placeholder="请选择">
<el-option
v-for="item in options"
:key="item.value"
:label="item.label"
:value="item.value">
</el-option>
</el-select>
</el-form-item>
<el-form-item label="生产厂商" prop="factory">
<el-input v-model="equipment.factory" placeholder="生产厂商" />
</el-col>
</el-row>
<el-form-item label="厂商及国别" prop="factory">
<el-input v-model="equipment.factory" placeholder="生产厂商及国别" />
</el-form-item>
<el-row>
<el-col :span="11">
<el-form-item label="生产日期" prop="production_date">
<el-date-picker
v-model="equipment.production_date"
@ -160,6 +152,8 @@
>
</el-date-picker>
</el-form-item>
</el-col>
<el-col :span="11">
<el-form-item label="购置日期" prop="buy_date">
<el-date-picker
v-model="equipment.buy_date"
@ -170,18 +164,34 @@
>
</el-date-picker>
</el-form-item>
<el-form-item label="技术参数" prop="parameter">
<el-input v-model="equipment.parameter" placeholder="技术参数" />
</el-col>
</el-row>
<el-form-item label="状态" prop="state">
<el-select style="width: 100%" v-model="equipment.state" placeholder="请选择">
<el-option
v-for="item in options"
:key="item.value"
:label="item.label"
:value="item.value">
</el-option>
</el-select>
</el-form-item>
<el-form-item label="技术指标" prop="parameter">
<el-input v-model="equipment.parameter" placeholder="技术指标" />
</el-form-item>
<el-form-item label="存放位置" prop="place">
<el-form-item label="存放位置" prop="place">
<el-input v-model="equipment.place" placeholder="存放位置" />
</el-form-item>
<el-row>
<el-col :span="11">
<el-form-item label="所属部门" prop="belong_dept">
<el-cascader :options="depOptions" :props="{ checkStrictly: true,emitPath:false }" ref="demoCascader" style="width:100%" v-model="equipment.belong_dept"></el-cascader>
</el-form-item>
</el-col>
<el-col :span="11">
<el-form-item label="保管人" prop="keeper">
<el-select
@ -201,7 +211,8 @@
</el-form-item>
</el-col>
</el-row>
<el-form-item label="设备备注" prop="description">
<el-input
type="textarea"
@ -210,6 +221,15 @@
placeholder="设备备注"
/>
</el-form-item>
</el-form>
<div style="text-align: right">
<el-button type="danger" @click="dialogVisible = false">取消</el-button>
@ -244,13 +264,7 @@ export default {
'2':'检验工具',
},
typeoptions: [{
value: 1,
label: '生产设备'
}, {
value: 2,
label: '检验工具'
}],
options: [{
value: 0,
label: '运转正常'
@ -370,6 +384,7 @@ export default {
}
});
} else {
this.equipment.type=1;
createEquipment(this.equipment).then((res) => {
if (res.code >= 200) {
this.getList();

View File

@ -4,7 +4,7 @@
<div>
<el-input
v-model="listQuery.search"
placeholder="原料名称/原料编号"
placeholder="物料名称/物料编号"
style="width: 300px"
class="filter-item"
@keyup.enter.native="handleFilter"
@ -37,7 +37,9 @@
border
fit
stripe
highlight-current-row
highlight-current-row
max-height="600"
height="100"
v-el-height-adaptive-table="{bottomOffset: 50}"
>
<el-table-column type="index" width="50" />
@ -45,17 +47,20 @@
<template slot-scope="scope">{{ scope.row.number }}</template>
</el-table-column>
<el-table-column label="物料类别">
<template slot-scope="scope"> {{ options_[scope.row.type] }}</template>
<el-table-column label="物料类别" :filters="[{ text: '成品', value: 1 }, { text: '半成品', value: 2 },{ text: '主要原料', value: 3 }, { text: '辅助原料', value: 4 }]"
:filter-method="filterTag"
filter-placement="bottom-end">
<template slot-scope="scope"> {{options_[scope.row.type]}}</template>
</el-table-column>
<el-table-column label="物料名称">
<template slot-scope="scope">{{ scope.row.name }}</template>
</el-table-column>
<el-table-column label="物料编">
<template slot-scope="scope">{{ scope.row.number }}</template>
<el-table-column label="规格型">
<template slot-scope="scope">{{ scope.row.specification }}</template>
</el-table-column>
<el-table-column label="计量单位">
<template slot-scope="scope">{{ scope.row.unit }}</template>
</el-table-column>
@ -109,6 +114,10 @@
<el-form-item label="物料编号" prop="number">
<el-input v-model="material.number" placeholder="物料编号" />
</el-form-item>
<el-form-item label="规格型号" prop="specification">
<el-input v-model="material.specification" placeholder="规格型号" />
</el-form-item>
<el-form-item label="计量单位" prop="unit">
<el-select style="width: 100%" v-model="material.unit" placeholder="请选择">
<el-option
@ -175,7 +184,8 @@ export default {
"1":'成品',
"2":'半成品',
"3":'原料',
"3":'主要原料',
"4":'辅助原料',
},
options: [{
@ -186,7 +196,10 @@ export default {
label: '半成品'
}, {
value: 3,
label: '原料'
label: '主要原料'
}, {
value: 4,
label: '辅助原料'
}],
unitoptions:[
{
@ -231,7 +244,10 @@ export default {
this.listLoading = false;
});
},
filterTag(value, row) {
return row.type === value;
},
//工序清单
getProcessList() {
getProcessList().then((res) => {

View File

@ -0,0 +1,261 @@
<template>
<div class="app-container">
<el-card>
<div>
<el-input
v-model="listQuery.search"
placeholder="仓库名称/仓库编号"
style="width: 300px"
class="filter-item"
@keyup.enter.native="handleFilter"
/>
<el-button
class="filter-item"
type="primary"
icon="el-icon-search"
@click="handleFilter"
>搜索</el-button
>
<el-button
class="filter-item"
type="primary"
icon="el-icon-refresh-left"
@click="resetFilter"
>重置</el-button
>
</div>
<div style="margin-top: 10px">
<el-button type="primary" icon="el-icon-plus" @click="handleCreate"
>新增仓库</el-button
>
</div>
</el-card>
<el-card style="margin-top: 10px">
<el-table
v-loading="listLoading"
:data="warehouseList.results"
border
fit
stripe
highlight-current-row
max-height="600"
>
<el-table-column type="index" width="50" />
<el-table-column label="客户名称">
<template slot-scope="scope">{{ scope.row.name }}</template>
</el-table-column>
<el-table-column label="详细地址">
<template slot-scope="scope">{{ scope.row.address }}</template>
</el-table-column>
<el-table-column label="联系人">
<template slot-scope="scope">{{ scope.row.contact }}</template>
</el-table-column>
<el-table-column label="联系电话">
<template slot-scope="scope">{{ scope.row.contact_phone }}</template>
</el-table-column>
<el-table-column label="描述">
<template slot-scope="scope">{{ scope.row.description }}</template>
</el-table-column>
<el-table-column label="创建时间">
<template slot-scope="scope">{{ scope.row.create_time }}</template>
</el-table-column>
<el-table-column
align="center"
label="操作"
width="220px"
>
<template slot-scope="scope">
<el-link
v-if="checkPermission(['warehouse_update'])"
@click="handleEdit(scope)"
>编辑</el-link
>
<el-link
v-if="checkPermission(['warehouse_delete'])"
type="danger"
@click="handleDelete(scope)"
>删除</el-link
>
</template>
</el-table-column>
</el-table>
<pagination
v-show="warehouseList.count > 0"
:total="warehouseList.count"
:page.sync="listQuery.page"
:limit.sync="listQuery.page_size"
@pagination="getList"
/>
</el-card>
<el-dialog
:visible.sync="dialogVisible"
:title="dialogType === 'edit' ? '编辑仓库' : '新增仓库'"
>
<el-form
ref="Form"
:model="warehouse"
label-width="80px"
label-position="right"
:rules="rule1"
>
<el-form-item label="客户名称" prop="name">
<el-input v-model="warehouse.name" placeholder="仓库名称" />
</el-form-item>
<el-form-item label="客户地址" prop="address">
<el-input v-model="warehouse.address" placeholder="仓库编号" />
</el-form-item>
<el-form-item label="联系人" prop="contact">
<el-input v-model="warehouse.contact" placeholder="具体地点" />
</el-form-item>
<el-form-item label="联系电话" prop="contact_phone">
<el-input v-model="warehouse.contact_phone" placeholder="仓库编号" />
</el-form-item>
<el-form-item label="描述" prop="description">
<el-input v-model="warehouse.description" placeholder="具体地点" />
</el-form-item>
</el-form>
<div style="text-align: right">
<el-button type="danger" @click="dialogVisible = false">取消</el-button>
<el-button type="primary" @click="confirm('Form')">确认</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import { getWarehouseList, createWarehouse,updateWarehouse,deleteWarehouse } from "@/api/inm";
import checkPermission from "@/utils/permission";
import { genTree } from "@/utils";
import Pagination from "@/components/Pagination"; // secondary package based on el-pagination
const defaultewarehouse = {
};
export default {
components: { Pagination },
data() {
return {
warehouse: defaultewarehouse,
warehouseList: {
count: 0,
},
options: [{
value: 0,
label: '运转正常'
}, {
value: 1,
label: '停用'
}, {
value: 2,
label: '报废'
}],
listQuery: {
page: 1,
page_size: 20,
},
keeperOptions:[],
depOptions:[],
listLoading: true,
dialogVisible: false,
dialogType: "new",
rule1: {
name: [{ required: true, message: "请输入", trigger: "blur" }],
number: [{ required: true, message: "请输入", trigger: "blur" }],
place: [{ required: true, message: "请输入", trigger: "blur" }],
},
};
},
computed: {},
watch: {},
created() {
this.getList();
},
methods: {
checkPermission,
//设备列表
getList() {
this.listLoading = true;
getWarehouseList(this.listQuery).then((response) => {
if (response.data) {
this.warehouseList = response.data;
}
this.listLoading = false;
});
},
handleFilter() {
this.listQuery.page = 1;
this.getList();
},
resetFilter() {
this.listQuery = {
page: 1,
page_size: 20,
}
this.getList();
},
handleCreate() {
this.warehouse = Object.assign({}, defaultewarehouse);
this.dialogType = "new";
this.dialogVisible = true;
this.$nextTick(() => {
this.$refs["Form"].clearValidate();
});
},
handleEdit(scope) {
this.warehouse = Object.assign({}, scope.row); // copy obj
this.dialogType = "edit";
this.dialogVisible = true;
this.$nextTick(() => {
this.$refs["Form"].clearValidate();
});
},
handleDelete(scope) {
this.$confirm("确认删除?", "警告", {
confirmButtonText: "确认",
cancelButtonText: "取消",
type: "error",
})
.then(async () => {
await deleteWarehouse(scope.row.id);
this.getList();
this.$message.success("成功");
})
.catch((err) => {
console.error(err);
});
},
async confirm(form) {
this.$refs[form].validate((valid) => {
if (valid) {
const isEdit = this.dialogType === "edit";
if (isEdit) {
updateWarehouse(this.warehouse.id, this.warehouse).then((res) => {
if (res.code >= 200) {
this.getList();
this.dialogVisible = false;
this.$message.success("成功");
}
});
} else {
createWarehouse(this.warehouse).then((res) => {
if (res.code >= 200) {
this.getList();
this.dialogVisible = false;
this.$message.success("成功");
}
});
}
} else {
return false;
}
});
},
},
};
</script>

View File

@ -0,0 +1,244 @@
<template>
<div class="app-container">
<el-card>
<div>
<el-input
v-model="listQuery.search"
placeholder="客户名称"
style="width: 300px"
class="filter-item"
@keyup.enter.native="handleFilter"
/>
<el-button
class="filter-item"
type="primary"
icon="el-icon-search"
@click="handleFilter"
>搜索</el-button
>
<el-button
class="filter-item"
type="primary"
icon="el-icon-refresh-left"
@click="resetFilter"
>重置</el-button
>
</div>
<div style="margin-top: 10px">
<el-button type="primary" icon="el-icon-plus" @click="handleCreate"
>新增客户</el-button
>
</div>
</el-card>
<el-card style="margin-top: 10px">
<el-table
v-loading="listLoading"
:data="warehouseList.results"
border
fit
stripe
highlight-current-row
max-height="600"
>
<el-table-column type="index" width="50" />
<el-table-column label="客户名称">
<template slot-scope="scope">{{ scope.row.name }}</template>
</el-table-column>
<el-table-column label="详细地址">
<template slot-scope="scope">{{ scope.row.address }}</template>
</el-table-column>
<el-table-column label="联系人">
<template slot-scope="scope">{{ scope.row.contact }}</template>
</el-table-column>
<el-table-column label="联系电话">
<template slot-scope="scope">{{ scope.row.contact_phone }}</template>
</el-table-column>
<el-table-column label="描述">
<template slot-scope="scope">{{ scope.row.description }}</template>
</el-table-column>
<el-table-column label="创建时间">
<template slot-scope="scope">{{ scope.row.create_time }}</template>
</el-table-column>
<el-table-column
align="center"
label="操作"
width="220px"
>
<template slot-scope="scope">
<el-link
v-if="checkPermission(['warehouse_update'])"
@click="handleEdit(scope)"
>编辑</el-link
>
<el-link
v-if="checkPermission(['warehouse_delete'])"
type="danger"
@click="handleDelete(scope)"
>删除</el-link
>
</template>
</el-table-column>
</el-table>
<pagination
v-show="warehouseList.count > 0"
:total="warehouseList.count"
:page.sync="listQuery.page"
:limit.sync="listQuery.page_size"
@pagination="getList"
/>
</el-card>
<el-dialog
:visible.sync="dialogVisible"
:title="dialogType === 'edit' ? '编辑客户' : '新增客户'"
>
<el-form
ref="Form"
:model="customer"
label-width="80px"
label-position="right"
:rules="rule1"
>
<el-form-item label="客户名称" prop="name">
<el-input v-model="customer.name" placeholder="客户名称" />
</el-form-item>
<el-form-item label="客户地址" prop="address">
<el-input v-model="customer.address" placeholder="客户地址" />
</el-form-item>
<el-form-item label="联系人" prop="contact">
<el-input v-model="customer.contact" placeholder="联系人" />
</el-form-item>
<el-form-item label="联系电话" prop="contact_phone">
<el-input v-model="customer.contact_phone" placeholder="联系电话" />
</el-form-item>
<el-form-item label="描述" prop="description">
<el-input v-model="customer.description" placeholder="描述" />
</el-form-item>
</el-form>
<div style="text-align: right">
<el-button type="danger" @click="dialogVisible = false">取消</el-button>
<el-button type="primary" @click="confirm('Form')">确认</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import { getCustomerList, createCustomer,updateCustomer,deleteCustomer } from "@/api/sam";
import checkPermission from "@/utils/permission";
import { genTree } from "@/utils";
import Pagination from "@/components/Pagination"; // secondary package based on el-pagination
const defaultecustomer = {
};
export default {
components: { Pagination },
data() {
return {
customer: defaultecustomer,
customerList: {
count: 0,
},
listLoading: true,
dialogVisible: false,
dialogType: "new",
rule1: {
name: [{ required: true, message: "请输入", trigger: "blur" }],
},
};
},
computed: {},
watch: {},
created() {
this.getList();
},
methods: {
checkPermission,
//设备列表
getList() {
this.listLoading = true;
getCustomerList(this.listQuery).then((response) => {
if (response.data) {
this.warehouseList = response.data;
}
this.listLoading = false;
});
},
handleFilter() {
this.listQuery.page = 1;
this.getList();
},
resetFilter() {
this.listQuery = {
page: 1,
page_size: 20,
}
this.getList();
},
handleCreate() {
this.customer = Object.assign({}, defaultecustomer);
this.dialogType = "new";
this.dialogVisible = true;
this.$nextTick(() => {
this.$refs["Form"].clearValidate();
});
},
handleEdit(scope) {
this.customer = Object.assign({}, scope.row); // copy obj
this.dialogType = "edit";
this.dialogVisible = true;
this.$nextTick(() => {
this.$refs["Form"].clearValidate();
});
},
handleDelete(scope) {
this.$confirm("确认删除?", "警告", {
confirmButtonText: "确认",
cancelButtonText: "取消",
type: "error",
})
.then(async () => {
await deleteCustomer(scope.row.id);
this.getList();
this.$message.success("成功");
})
.catch((err) => {
console.error(err);
});
},
async confirm(form) {
this.$refs[form].validate((valid) => {
if (valid) {
const isEdit = this.dialogType === "edit";
if (isEdit) {
updateCustomer(this.customer.id, this.customer).then((res) => {
if (res.code >= 200) {
this.getList();
this.dialogVisible = false;
this.$message.success("成功");
}
});
} else {
createCustomer(this.customer).then((res) => {
if (res.code >= 200) {
this.getList();
this.dialogVisible = false;
this.$message.success("成功");
}
});
}
} else {
return false;
}
});
},
},
};
</script>

View File

@ -0,0 +1,18 @@
# Generated by Django 3.2.6 on 2021-09-13 08:33
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('em', '0003_equipment_type'),
]
operations = [
migrations.AddField(
model_name='equipment',
name='count',
field=models.IntegerField(default=0, verbose_name='数量'),
),
]

View File

@ -4,6 +4,7 @@ from django.db.models.base import Model
import django.utils.timezone as timezone
from django.db.models.query import QuerySet
from apps.system.models import CommonAModel, CommonBModel, Organization, User, Dict, File
#from apps.mtm.models import Process
from utils.model import SoftModel, BaseModel
from simple_history.models import HistoricalRecords
@ -32,8 +33,10 @@ class Equipment(CommonBModel):
state = models.CharField('设备状态', max_length=11, choices=state_choices, default=1)
parameter = models.TextField('技术参数', null=True, blank=True)
place = models.CharField('存放位置', max_length=50, null=True, blank=True)
count = models.IntegerField('数量', default=0)
keeper = models.ForeignKey(User, verbose_name='保管人', on_delete=models.CASCADE, null=True, blank=True)
description = models.CharField('描述', max_length=200, blank=True, null=True)
#process = models.ForeignKey(Process, verbose_name='工序', on_delete=models.CASCADE, null=True, blank=True)
class Meta:
verbose_name = '设备信息'

View File

@ -0,0 +1,51 @@
# Generated by Django 3.2.6 on 2021-09-13 01:54
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
import django.utils.timezone
class Migration(migrations.Migration):
dependencies = [
('mtm', '0011_alter_recordformfield_field_type'),
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('inm', '0001_initial'),
]
operations = [
migrations.CreateModel(
name='Inventory',
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='删除标记')),
('count', models.IntegerField(default=0, verbose_name='数量')),
('create_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='inventory_create_by', to=settings.AUTH_USER_MODEL, verbose_name='创建人')),
('material', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='mtm.material', verbose_name='物料信息')),
('update_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='inventory_update_by', to=settings.AUTH_USER_MODEL, verbose_name='最后编辑人')),
('warehouse', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='inm.warehouse', verbose_name='所在仓库')),
],
options={
'verbose_name': '库存表',
'verbose_name_plural': '库存表',
},
),
migrations.CreateModel(
name='FIFO',
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='删除标记')),
('type', models.IntegerField(default=1, verbose_name='出入库类型')),
('create_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='fifo_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='fifo_update_by', to=settings.AUTH_USER_MODEL, verbose_name='最后编辑人')),
],
options={
'abstract': False,
},
),
]

View File

@ -0,0 +1,23 @@
# Generated by Django 3.2.6 on 2021-09-13 06:12
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('mtm', '0011_alter_recordformfield_field_type'),
]
operations = [
migrations.AddField(
model_name='material',
name='specification',
field=models.CharField(blank=True, max_length=100, null=True, verbose_name='规格型号'),
),
migrations.AlterField(
model_name='material',
name='type',
field=models.CharField(choices=[(1, '成品'), (2, '半成品'), (3, '主要原料'), (4, '辅助原料')], default=1, max_length=20, verbose_name='物料类型'),
),
]

View File

@ -15,7 +15,8 @@ class Material(CommonAModel):
type_choices=(
(1, '成品'),
(2, '半成品'),
(3, '原材料')
(3, '主要原料'),
(4,'辅助原料')
)
unit_choices =(
('', ''),
@ -23,6 +24,7 @@ class Material(CommonAModel):
)
name = models.CharField('物料名称', max_length=100, unique=True)
number = models.CharField('编号', max_length=100, unique=True)
specification = models.CharField('型号', max_length=100, null=True, blank=True)
type = models.CharField('物料类型', choices= type_choices, max_length=20, default=1)
sort_str = models.CharField('排序字符', max_length=100, null=True, blank=True)
processes = models.JSONField('工艺流程', default=list, blank=True)

View File

@ -50,7 +50,7 @@ class StepSimpleSerializer(serializers.ModelSerializer):
fields = ['id', 'name', 'sort']
class StepDetailSerializer(serializers.ModelSerializer):
equipments_ = EquipmentSimpleSerializer(source='equipments', many=True)
class Meta:
model = Step
fields = '__all__'

View File

@ -0,0 +1,77 @@
# Generated by Django 3.2.6 on 2021-09-13 01:54
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
import django.utils.timezone
class Migration(migrations.Migration):
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('sam', '0001_initial'),
]
operations = [
migrations.CreateModel(
name='Contract',
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='删除标记')),
('name', models.CharField(max_length=100, verbose_name='合同名称')),
('number', models.CharField(max_length=100, unique=True, verbose_name='合同编号')),
('amount', models.IntegerField(default=0, verbose_name='合同金额')),
('sign_date', models.DateField(verbose_name='签订日期')),
('description', models.CharField(blank=True, max_length=200, null=True, verbose_name='描述')),
('create_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='contract_create_by', to=settings.AUTH_USER_MODEL, verbose_name='创建人')),
],
options={
'verbose_name': '合同信息',
'verbose_name_plural': '合同信息',
},
),
migrations.RemoveField(
model_name='customer',
name='country',
),
migrations.RemoveField(
model_name='customer',
name='phone',
),
migrations.RemoveField(
model_name='order',
name='contact',
),
migrations.AddField(
model_name='customer',
name='contact_phone',
field=models.CharField(max_length=11, null=True, unique=True, verbose_name='联系电话'),
),
migrations.AlterField(
model_name='customer',
name='contact',
field=models.CharField(default=1, max_length=20, verbose_name='联系人'),
preserve_default=False,
),
migrations.DeleteModel(
name='Contact',
),
migrations.AddField(
model_name='contract',
name='customer',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='contact_customer', to='sam.customer', verbose_name='关联客户'),
),
migrations.AddField(
model_name='contract',
name='update_by',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='contract_update_by', to=settings.AUTH_USER_MODEL, verbose_name='最后编辑人'),
),
migrations.AddField(
model_name='order',
name='contract',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='sam.contract', verbose_name='所属合同'),
),
]

View File

@ -17,7 +17,7 @@ class Customer(CommonAModel):
name = models.CharField('客户名称', max_length=50, unique=True)
address = models.CharField('详细地址', max_length=20, blank=True, null=True)
contact = models.CharField('联系人', max_length=20)
contact_phone = models.CharField('联系电话', max_length=11, unique=True)
contact_phone = models.CharField('联系电话', max_length=11, unique=True,null=True)
description = models.CharField('描述', max_length=200, blank=True, null=True)
class Meta:

View File

@ -2,7 +2,6 @@ from rest_framework import serializers
from .models import Contract, Customer, Order
class CustomerSerializer(serializers.ModelSerializer):
class Meta:
model = Customer
@ -44,4 +43,4 @@ class OrderSerializer(serializers.ModelSerializer):
customer_ = CustomerSimpleSerializer(source='customer', read_only=True)
class Meta:
model = Order
fields = '__all__'
fields = '__all__'

View File

@ -0,0 +1,14 @@
from django.db.models import base
from rest_framework import urlpatterns
from apps.sam.views import CustomerViewSet,ContractViewSet
from django.urls import path, include
from rest_framework.routers import DefaultRouter
router = DefaultRouter()
router.register('customer', CustomerViewSet, basename='customer')
router.register('contract', ContractViewSet, basename='contract')
urlpatterns = [
path('', include(router.urls)),
]

View File

@ -353,7 +353,7 @@ class FileViewSet(CreateModelMixin, DestroyModelMixin, RetrieveModelMixin, ListM
import face_recognition
#import face_recognition
import uuid
import base64
import os
@ -381,13 +381,14 @@ class FaceLogin(CreateAPIView):
with open(filepath, 'wb') as f:
data = tran64(request.data.get('base64').replace(' ', '+'))
f.write(base64.urlsafe_b64decode(data))
picture_of_me = face_recognition.load_image_file(settings.BASE_DIR +'/temp/me.png')
my_face_encoding = face_recognition.face_encodings(picture_of_me)[0]
unknown_picture = face_recognition.load_image_file(filepath)
unknown_face_encoding = face_recognition.face_encodings(unknown_picture)[0]
results = face_recognition.compare_faces([my_face_encoding], unknown_face_encoding, tolerance=0.2)
# picture_of_me = face_recognition.load_image_file(settings.BASE_DIR +'/temp/me.png')
# my_face_encoding = face_recognition.face_encodings(picture_of_me)[0]
# unknown_picture = face_recognition.load_image_file(filepath)
# unknown_face_encoding = face_recognition.face_encodings(unknown_picture)[0]
#results = face_recognition.compare_faces([my_face_encoding], unknown_face_encoding, tolerance=0.2)
os.remove(filepath)
if results[0] == True:
return Response('这是曹前明')
else:
return Response('这不是曹前明')
# if results[0] == True:
# return Response('这是曹前明')
# else:
# return Response('这不是曹前明')

View File

@ -65,6 +65,7 @@ urlpatterns = [
path('api/wf/', include('apps.wf.urls')),
path('api/mtm/', include('apps.mtm.urls')),
path('api/inm/', include('apps.inm.urls')),
path('api/sam/', include('apps.sam.urls')),
# 工具
path('api/utils/signature/', GenSignature.as_view()),