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' ENV = 'development'
# base api # base api
#VUE_APP_BASE_API = 'http://localhost:8000/api' VUE_APP_BASE_API = 'http://127.0.0.1:8000/api'
VUE_APP_BASE_API = 'http://47.95.0.242:2222/api' #VUE_APP_BASE_API = 'http://47.95.0.242:2222/api'
# vue-cli uses the VUE_CLI_BABEL_TRANSPILE_MODULES environment variable, # vue-cli uses the VUE_CLI_BABEL_TRANSPILE_MODULES environment variable,

View File

@ -30,6 +30,7 @@
"vue-json-editor": "^1.4.3", "vue-json-editor": "^1.4.3",
"vue-router": "^3.5.2", "vue-router": "^3.5.2",
"vuex": "^3.6.2", "vuex": "^3.6.2",
"webpack-dev-server": "^4.2.0",
"xlsx": "^0.17.1" "xlsx": "^0.17.1"
}, },
"devDependencies": { "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 * the routes that need to be dynamically loaded based on user perms
*/ */
export const asyncRoutes = [ 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', path: '/equipment',
component: Layout, component: Layout,
@ -91,13 +134,34 @@ export const asyncRoutes = [
path: 'index', path: 'index',
name: 'index', name: 'index',
component: () => import('@/views/equipment/index'), component: () => import('@/views/equipment/index'),
meta: { title: '设备台账', icon: 'example', perms: ['index_manage'] } meta: { title: '生产设备', icon: 'example', perms: ['index_manage'] }
}, },
{ {
path: 'index', path: 'index',
name: 'index', name: 'index',
component: () => import('@/views/equipment/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', path: '/procurement',

View File

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

View File

@ -4,7 +4,7 @@
<div> <div>
<el-input <el-input
v-model="listQuery.search" v-model="listQuery.search"
placeholder="原料名称/原料编号" placeholder="物料名称/物料编号"
style="width: 300px" style="width: 300px"
class="filter-item" class="filter-item"
@keyup.enter.native="handleFilter" @keyup.enter.native="handleFilter"
@ -37,7 +37,9 @@
border border
fit fit
stripe stripe
highlight-current-row highlight-current-row
max-height="600"
height="100"
v-el-height-adaptive-table="{bottomOffset: 50}" v-el-height-adaptive-table="{bottomOffset: 50}"
> >
<el-table-column type="index" width="50" /> <el-table-column type="index" width="50" />
@ -45,17 +47,20 @@
<template slot-scope="scope">{{ scope.row.number }}</template> <template slot-scope="scope">{{ scope.row.number }}</template>
</el-table-column> </el-table-column>
<el-table-column label="物料类别"> <el-table-column label="物料类别" :filters="[{ text: '成品', value: 1 }, { text: '半成品', value: 2 },{ text: '主要原料', value: 3 }, { text: '辅助原料', value: 4 }]"
<template slot-scope="scope"> {{ options_[scope.row.type] }}</template> :filter-method="filterTag"
filter-placement="bottom-end">
<template slot-scope="scope"> {{options_[scope.row.type]}}</template>
</el-table-column> </el-table-column>
<el-table-column label="物料名称"> <el-table-column label="物料名称">
<template slot-scope="scope">{{ scope.row.name }}</template> <template slot-scope="scope">{{ scope.row.name }}</template>
</el-table-column> </el-table-column>
<el-table-column label="物料编"> <el-table-column label="规格型">
<template slot-scope="scope">{{ scope.row.number }}</template> <template slot-scope="scope">{{ scope.row.specification }}</template>
</el-table-column> </el-table-column>
<el-table-column label="计量单位"> <el-table-column label="计量单位">
<template slot-scope="scope">{{ scope.row.unit }}</template> <template slot-scope="scope">{{ scope.row.unit }}</template>
</el-table-column> </el-table-column>
@ -109,6 +114,10 @@
<el-form-item label="物料编号" prop="number"> <el-form-item label="物料编号" prop="number">
<el-input v-model="material.number" placeholder="物料编号" /> <el-input v-model="material.number" placeholder="物料编号" />
</el-form-item> </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-form-item label="计量单位" prop="unit">
<el-select style="width: 100%" v-model="material.unit" placeholder="请选择"> <el-select style="width: 100%" v-model="material.unit" placeholder="请选择">
<el-option <el-option
@ -175,7 +184,8 @@ export default {
"1":'成品', "1":'成品',
"2":'半成品', "2":'半成品',
"3":'原料', "3":'主要原料',
"4":'辅助原料',
}, },
options: [{ options: [{
@ -186,7 +196,10 @@ export default {
label: '半成品' label: '半成品'
}, { }, {
value: 3, value: 3,
label: '原料' label: '主要原料'
}, {
value: 4,
label: '辅助原料'
}], }],
unitoptions:[ unitoptions:[
{ {
@ -231,7 +244,10 @@ export default {
this.listLoading = false; this.listLoading = false;
}); });
}, },
filterTag(value, row) {
return row.type === value;
},
//工序清单 //工序清单
getProcessList() { getProcessList() {
getProcessList().then((res) => { 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 import django.utils.timezone as timezone
from django.db.models.query import QuerySet from django.db.models.query import QuerySet
from apps.system.models import CommonAModel, CommonBModel, Organization, User, Dict, File from apps.system.models import CommonAModel, CommonBModel, Organization, User, Dict, File
#from apps.mtm.models import Process
from utils.model import SoftModel, BaseModel from utils.model import SoftModel, BaseModel
from simple_history.models import HistoricalRecords from simple_history.models import HistoricalRecords
@ -32,8 +33,10 @@ class Equipment(CommonBModel):
state = models.CharField('设备状态', max_length=11, choices=state_choices, default=1) state = models.CharField('设备状态', max_length=11, choices=state_choices, default=1)
parameter = models.TextField('技术参数', null=True, blank=True) parameter = models.TextField('技术参数', null=True, blank=True)
place = models.CharField('存放位置', max_length=50, 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) keeper = models.ForeignKey(User, verbose_name='保管人', on_delete=models.CASCADE, null=True, blank=True)
description = models.CharField('描述', max_length=200, blank=True, null=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: class Meta:
verbose_name = '设备信息' 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=( type_choices=(
(1, '成品'), (1, '成品'),
(2, '半成品'), (2, '半成品'),
(3, '原材料') (3, '主要原料'),
(4,'辅助原料')
) )
unit_choices =( unit_choices =(
('', ''), ('', ''),
@ -23,6 +24,7 @@ class Material(CommonAModel):
) )
name = models.CharField('物料名称', max_length=100, unique=True) name = models.CharField('物料名称', max_length=100, unique=True)
number = 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) type = models.CharField('物料类型', choices= type_choices, max_length=20, default=1)
sort_str = models.CharField('排序字符', max_length=100, null=True, blank=True) sort_str = models.CharField('排序字符', max_length=100, null=True, blank=True)
processes = models.JSONField('工艺流程', default=list, blank=True) processes = models.JSONField('工艺流程', default=list, blank=True)

View File

@ -50,7 +50,7 @@ class StepSimpleSerializer(serializers.ModelSerializer):
fields = ['id', 'name', 'sort'] fields = ['id', 'name', 'sort']
class StepDetailSerializer(serializers.ModelSerializer): class StepDetailSerializer(serializers.ModelSerializer):
equipments_ = EquipmentSimpleSerializer(source='equipments', many=True)
class Meta: class Meta:
model = Step model = Step
fields = '__all__' 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) name = models.CharField('客户名称', max_length=50, unique=True)
address = models.CharField('详细地址', max_length=20, blank=True, null=True) address = models.CharField('详细地址', max_length=20, blank=True, null=True)
contact = models.CharField('联系人', max_length=20) 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) description = models.CharField('描述', max_length=200, blank=True, null=True)
class Meta: class Meta:

View File

@ -2,7 +2,6 @@ from rest_framework import serializers
from .models import Contract, Customer, Order from .models import Contract, Customer, Order
class CustomerSerializer(serializers.ModelSerializer): class CustomerSerializer(serializers.ModelSerializer):
class Meta: class Meta:
model = Customer model = Customer
@ -44,4 +43,4 @@ class OrderSerializer(serializers.ModelSerializer):
customer_ = CustomerSimpleSerializer(source='customer', read_only=True) customer_ = CustomerSimpleSerializer(source='customer', read_only=True)
class Meta: class Meta:
model = Order 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 uuid
import base64 import base64
import os import os
@ -381,13 +381,14 @@ class FaceLogin(CreateAPIView):
with open(filepath, 'wb') as f: with open(filepath, 'wb') as f:
data = tran64(request.data.get('base64').replace(' ', '+')) data = tran64(request.data.get('base64').replace(' ', '+'))
f.write(base64.urlsafe_b64decode(data)) f.write(base64.urlsafe_b64decode(data))
picture_of_me = face_recognition.load_image_file(settings.BASE_DIR +'/temp/me.png') # 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] # my_face_encoding = face_recognition.face_encodings(picture_of_me)[0]
unknown_picture = face_recognition.load_image_file(filepath) # unknown_picture = face_recognition.load_image_file(filepath)
unknown_face_encoding = face_recognition.face_encodings(unknown_picture)[0] # unknown_face_encoding = face_recognition.face_encodings(unknown_picture)[0]
results = face_recognition.compare_faces([my_face_encoding], unknown_face_encoding, tolerance=0.2) #results = face_recognition.compare_faces([my_face_encoding], unknown_face_encoding, tolerance=0.2)
os.remove(filepath) os.remove(filepath)
if results[0] == True: # if results[0] == True:
return Response('这是曹前明') # return Response('这是曹前明')
else: # else:
return Response('这不是曹前明') # return Response('这不是曹前明')

View File

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