| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642 |
- <template>
- <div>
- <Toptitle :title="this.$route.query.type==1?'新增':this.$route.query.type==2?'编辑':this.$route.query.type==3?'变更':'详情'">
- <Button type="primary" @click="back" style="margin-right:10px">返回</Button>
- <Button type="primary" @click="postData" v-if="$route.query.type!=4">保存</Button>
- </Toptitle>
- <div style="height:90%;overflow:auto">
- <Form :label-width='100' class="content">
- <FormItem label='项目编码:'>
- <Input placeholder="请输入项目编码" v-model="formData.order_no" class="form_item" clearable v-if="$route.query.type==1||$route.query.type==2" :disabled='$route.query.type!=1'/>
- <span class="form_span" v-else>{{formData.order_no}}</span>
- </FormItem>
- <FormItem label='项目名称:'>
- <Input placeholder="请输入项目名称" class="form_item" clearable v-model="formData.project_title" v-if="$route.query.type==1||$route.query.type==2"/>
- <span class="form_span" v-else>{{formData.project_title}}</span>
- </FormItem>
- <FormItem label='项目地址:'>
- <Input placeholder="请输入项目地址" class="form_item" clearable v-model="formData.project_address" v-if="$route.query.type==1||$route.query.type==2"/>
- <span class="form_span" v-else>{{formData.project_address}}</span>
- </FormItem>
- <FormItem label='联系人:'>
- <Input placeholder="请输入联系人" class="form_item" clearable v-model="formData.connect_person" v-if="$route.query.type==1||$route.query.type==2"/>
- <span class="form_span" v-else>{{formData.connect_person}}</span>
- </FormItem>
- <FormItem label='联系电话:'>
- <Input placeholder="请输入联系电话" class="form_item" clearable v-model="formData.connect_phone" v-if="$route.query.type==1||$route.query.type==2"/>
- <span class="form_span" v-else>{{formData.connect_phone}}</span>
- </FormItem>
- <FormItem label='项目阶段:'>
- <Select filterable clearable multiple v-model="formData.phase" placeholder="请选择" class="form_item" v-if="$route.query.type!=4" @on-change='changePhase'>
- <Option v-for="(item,index) in agreementList" :key="index" :value="item.id" :label="item.title"></Option>
- </Select>
- <span class="form_span" v-else>{{getPhase()}}</span>
- </FormItem>
- <FormItem label='项目日期:'>
- <DatePicker type="date" placeholder="年/月/日" class="form_item" v-model="formData.project_date" v-if="$route.query.type==1||$route.query.type==2"></DatePicker>
- <span class="form_span" v-else>{{formData.project_date}}</span>
- </FormItem>
- <FormItem label='客户名称:'>
- <Input v-model="formData.customer" placeholder="请输入客户名称" class="form_item" clearable v-if="$route.query.type==1||$route.query.type==2"/>
- <span class="form_span" v-else>{{formData.customer}}</span>
- </FormItem>
- <FormItem label='紧急程度:'>
- <Select v-model="formData.warning_state" filterable clearable class="form_item" v-if="$route.query.type==1||$route.query.type==2">
- <Option :value="1">普通</Option>
- <Option :value="2">紧急</Option>
- <Option :value="3">非常紧急</Option>
- </Select>
- <span class="form_span" v-else>{{formData.warning_state==1?'普通':formData.warning_state==2?'紧急':formData.warning_state==3?'非常紧急':''}}</span>
- </FormItem>
- <FormItem label='金螳螂ID:'>
- <Input v-model="formData.customer_id" placeholder="请输入金螳螂ID" class="form_item" clearable v-if="$route.query.type==1||$route.query.type==2"/>
- <span class="form_span" v-else>{{formData.customer_id}}</span>
- </FormItem>
- <FormItem label='投标金额:'>
- <Input v-model="formData.bid_price" placeholder="自动生成" class="form_item" clearable v-if="$route.query.type==1||$route.query.type==2" :disabled='true'/>
- <span class="form_span" v-else>{{formData.bid_price}}</span>
- </FormItem>
- <FormItem label='合同金额:'>
- <Input placeholder="自动生成" v-model="formData.agreement_price" class="form_item" clearable v-if="$route.query.type==1||$route.query.type==2" disabled/>
- <span class="form_span" v-else>{{formData.agreement_price}}</span>
- </FormItem>
- <FormItem label='核量金额:'>
- <Input v-model="formData.quantity_price" placeholder="请输入核量金额" class="form_item" clearable v-if="$route.query.type==1||$route.query.type==2"/>
- <span class="form_span" v-else>{{formData.quantity_price}}</span>
- </FormItem>
- <FormItem label='备注:'>
- <Input v-model="formData.remark" placeholder="请输入备注" class="form_item" clearable v-if="$route.query.type==1||$route.query.type==2"/>
- <span class="form_span" v-else>{{formData.remark}}</span>
- </FormItem>
- <FormItem label='附件:' style="width:100%">
- <Button type="primary" @click="addStage" v-if='$route.query.type==1||$route.query.type==2'>添加阶段</Button>
- <span v-else></span>
- </FormItem>
- <FormItem :label='`${item.title}:`' style="width:100%" v-for="(item,index) in showList" :key="index">
- <div class="total_img">
- <div v-for="(_item,_index) in item.url" :key="_index" class="img_item">
- <img @click="looks(_item.url,_item.is_pic)" :src="_item.is_pic?$store.state.ip + _item.url:require('./../../assets/imgs/file.jpg')" alt="" class="img_content"/>
- <Icon
- v-if="$route.query.type!=4"
- size="20"
- @click="delItems(_index, item.url)"
- class="delete-img"
- type="ios-close-circle"
- />
- <div class="img_title"><a @click="exportData(`${$store.state.ip}${_item.url}`,_item.is_pic,_item.name)">{{_item.name}}</a></div>
- </div>
- <Upload
- v-if="$route.query.type!=4"
- multiple
- :headers="headers"
- :show-upload-list="false"
- :on-success="handleSuccess"
- :action="$store.state.ip+'/api/upload_file'">
- <div class="upd_file" @click="recordIndex(index)">
- <Icon type="ios-cloud-upload-outline" class="ico" size='50'/>
- </div>
- </Upload>
- </div>
- </FormItem>
- </Form>
- <Card>
- <p slot="title">
- 清单
- </p>
- <div slot="extra" v-if="$route.query.type!=4" style="display:flex">
-
- <Upload
- v-if="$route.query.type!=3||$route.query.type!=4"
- multiple
- :headers="headers"
- :show-upload-list="false"
- :on-success="handleTotalTableSuccess"
- :action="$store.state.ip+'/api/upload_image'"
- style="margin-right:10px"
- >
- <Button type="primary" size='small'>批量上传图片</Button>
- </Upload>
- <Button type="primary" style="margin-right:10px" @click="totalDel" size='small'>批量删除</Button>
- <Upload
- style="display:inline"
- name="your_file"
- :show-upload-list="false"
- :headers="headers"
- :on-error="uploadError"
- :on-success="uploadSuccess"
- :action="$store.state.ip + '/api/contract_import'"
- >
- <Button type="primary" style="margin-right:10px;" size='small'
- >导入</Button
- >
- </Upload>
- </div>
-
- <Table :data='tableData' :columns='$route.query.type==1||$route.query.type==2?tableColumns:editTableColumns' border max-height='620' @on-selection-change='handleSelect' show-summary :summary-method="handleSummary">
- <template slot="set" slot-scope="{index}">
- <a @click="del(index)">删除</a>
- </template>
- <template slot="bp_id" slot-scope="{row,index}">
- <Select v-model="row.bp_id" @on-change='selectBpId($event,index)' filterable clearable :transfer='true'>
- <Option v-for="(item,index) in bp_list" :key="index" :value="item.id" :label='item.title'/>
- </Select>
- </template>
- <template slot="product_img" slot-scope="{row,index}">
- <div>
-
- <Upload
- v-if="!row.product_img&&($route.query.type!=3||$route.query.type!=4)"
- :headers="headers"
- :show-upload-list="false"
- :on-success="handleTableSuccess"
- :action="$store.state.ip+'/api/upload_image'">
- <a @click="updTableImg(index)">上传</a>
- </Upload>
- <div v-if="tableData[index].product_img" class="img_box">
- <img @click="looks(row.product_img,true)" :src="$store.state.ip + tableData[index].product_img" alt="" class="img_table_content"/>
-
- <Icon
- v-if="$route.query.type!=4"
- size="20"
- @click="delTableItems(row,index)"
- class="delete-img"
- type="ios-close-circle"
- />
- </div>
- </div>
- </template>
- <template slot="total_bid_price" slot-scope="{row,index}">
- <Input v-model="row.total_bid_price" @on-change='changeTotalBidPrice($event,index)' type="number" @on-blur='checkPrice(row,index)'/>
- </template>
- </Table>
- </Card>
- </div>
- <Modal title="添加阶段" v-model="show_stage" @on-ok='sureAdd'>
- <div class="model_agreement">
- <span >阶段名称:</span>
- <Select v-model="list" filterable multiple>
- <Option :disabled='item.is_show' v-for="(item,index) in agreementList" :key="index" :label="item.title" :value="item.title"/>
- </Select>
- </div>
- </Modal>
- </div>
- </template>
- <script>
- export default {
- data(){
- return{
- tableIndex:null,
- bp_list:[],
- showPicIndex:null,
- showList:[],
- list:[],
- show_stage:false,
- headers: { 'Authorization': localStorage.getItem('token') },
- selectData:[],
- agreementList:[{title:'立项',is_show:false,id:1},{title:'评审',is_show:false,id:2},{title:'报价',is_show:false,id:3},{title:'投标',is_show:false,id:4},{title:'中标',is_show:false,id:5},{title:'废标',is_show:false,id:6}],
- formData:{
- bid_price:'',
- order_no:'',
- project_title:'',
- project_address:'',
- connect_person:'',
- connect_phone:'',
- phase:[],
- project_date:'',
- customer:'',
- customer_id:'',
- warning_state:'',
- agreement_price:'',
- quantity_price:'',
- remark:'',
- },
- tableData:[],
- tableColumns:[
- {type:'selection',minWidth:40,align:'center',key:'select'},
- {title:'序号',type:'index',align:'center',minWidth:80,key:'index'},
- {title:'区域',minWidth:100,align:'center',key:'region'},
- {title:'产品分类',minWidth:100,align:'center',key:'bp_id',slot:'bp_id'},
- {title:'产品名称',minWidth:100,align:'center',key:'product_title'},
- {title:'产品图片',minWidth:100,align:'center',key:'product_img',slot:'product_img'},
- {title:'产品特征',minWidth:200,align:'center',key:'product_feature'},
- {title:'计量单位',minWidth:60,align:'center',key:'unit'},
- {title:'工程量',minWidth:80,align:'center',key:'num'},
- {title:'投标单价',minWidth:100,align:'center',key:'bid_price'},
- {title:'投标金额',minWidth:100,align:'center',key:'total_bid_price',slot:'total_bid_price'},
- {title:'操作',minWidth:60,align:'center',key:'set',slot:'set'}
- ],
- editTableColumns:[
- {title:'序号',type:'index',align:'center',minWidth:80,key:'index'},
- {title:'区域',minWidth:100,align:'center',key:'region'},
- {title:'产品分类',minWidth:100,align:'center',key:'product_type_title'},
- {title:'产品名称',minWidth:100,align:'center',key:'product_title'},
- {title:'产品图片',minWidth:100,align:'center',key:'product_img',slot:'product_img'},
- {title:'产品特征',minWidth:100,align:'center',key:'product_feature'},
- {title:'计量单位',minWidth:100,align:'center',key:'unit'},
- {title:'工程量',minWidth:100,align:'center',key:'num'},
- {title:'投标单价',minWidth:100,align:'center',key:'bid_price'},
- {title:'投标金额',minWidth:100,align:'center',key:'total_bid_price'}
-
- ]
- }
- },
- created(){
- (this.$route.query.type==1||this.$route.query.type==2)&&this.axios.get('/api/basics_product_index').then(res=>{
- this.bp_list = res.data.data
- })
- },
- mounted(){
- this.$route.query.type!=1&&this.initData();
- },
- methods:{
- checkPrice(row,index){
- if(row.total_bid_price<0){
- row.total_bid_price = '0.00';
- this.tableData[index].total_bid_price = '0.00'
- }else{
- row.total_bid_price = Number(row.total_bid_price).toFixed(2);
- this.tableData[index].total_bid_price=Number(this.tableData[index].total_bid_price).toFixed(2);
- return
- }
- },
- changeTotalBidPrice(e,index){
- this.tableData[index].total_bid_price = e.target.value;
- },
- handleSummary ({ columns, data }) {
- const sums = {};
- columns.forEach((column, index) => {
- const key = column.key;
- if (key === 'index') {
- sums[key] = {
- key,
- value: '合计'
- };
- return;
- }
- const values = data.map(item => Number(item[key]));
- if (key=='total_bid_price') {
- const v = values.reduce((prev, curr) => {
- const value = Number(curr);
- if (!isNaN(value)) {
- return prev + curr;
- } else {
- return prev;
- }
- }, 0);
- sums[key] = {
- key,
- value: (v*1).toFixed(2)
- };
-
- this.formData.bid_price = (v*1).toFixed(2);
- if(this.formData.phase.indexOf(5)>=0){
- this.formData.agreement_price = this.formData.bid_price;
- }
- }else{
- sums[key] = {
- key,
- value:''
- }
- }
- });
-
- return sums;
-
- },
- selectBpId(e,index){
- this.tableData[index].bp_id = e;
- },
- changePhase(e){
- if(e.indexOf(5)>=0){
- this.formData.agreement_price = this.formData.bid_price;
- }else{
- this.formData.agreement_price = '';
- }
- },
- getPhase(){
- let arr = [];
- arr = this.agreementList.filter(v=>{
- return this.formData.phase.indexOf(v.id)>=0;
- })
- let val = [];
- arr.forEach(v=>{
- val.push(v.title);
- })
- return val.toString();
- },
- delItems(n, arr) {
- arr.splice(n, 1);
- },
- delTableItems(row,index){
- row.product_img = '';
- this.tableData[index].product_img = '';
- },
- looks(img,type) {
- if(!type){
- return
- }
- const array = [{ img_url: img }];
- this.$previewImg({
- list: array,
- baseUrl: this.$store.state.ip,
- baseImgField: "img_url",
- baseTitleField: "",
- });
- },
- exportData(url,type,name) {
-
- // window.open(url)
- if(type){
- this.downloadIamge(url,name)
- }else{
- location.href = url;
- }
-
- },
- downloadIamge(imgsrc, name) {
- //下载图片地址和图片名
- var image = new Image()
- // 解决跨域 Canvas 污染问题
- image.setAttribute('crossOrigin', 'anonymous')
- image.onload = function () {
- var canvas = document.createElement('canvas')
- canvas.width = image.width
- canvas.height = image.height
- var context = canvas.getContext('2d')
- context.drawImage(image, 0, 0, image.width, image.height)
- var url = canvas.toDataURL('image/png') //得到图片的base64编码数据
- var a = document.createElement('a') // 生成一个a元素
- var event = new MouseEvent('click') // 创建一个单击事件
- a.download = name || 'photo' // 设置图片名称
- a.href = url // 将生成的URL设置为a.href属性
- a.dispatchEvent(event) // 触发a的单击事件
- }
- image.src = imgsrc
- },
- recordIndex(index){
- this.showPicIndex = index;
- },
- handleTotalTableSuccess(res,file){
- if(file.name.indexOf('+')<0){
- return this.$Message.error("请上传‘区域’+‘产品名称’的图片名称!")
- }
- if(res.code==200){
- let content = file.name.split('.')[0];
-
- let arr = content.split('+');
- console.log(arr);
- this.tableData.forEach((v,index)=>{
- if(v.region===arr[0]&&v.product_title===arr[1]){
- this.tableData[index].product_img = res.data.url;
- }
- })
- }
- },
- handleTableSuccess(res,file){
- // console.log(this.tableData)
- if(res.code==200){
- this.tableData[this.tableIndex].product_img = res.data.url;
- // let obj = this.tableData[this.initData];
- // obj.product_img = res.data.url;
- // this.$set(this.tableData,this.initData,obj)
- // this.tableData.splice(this.tableIndex,1,obj)
- // console.log(this.tableData)
-
- }
- },
- updTableImg(index){
- this.tableIndex = index;
- },
- handleSuccess(res,file){
- if(res.code==200){
- let obj = {};
- obj.url = res.data.url;
- let config = ['jpg', 'png', 'gif', "jpeg"];
- let text = file.name.split('.');
- if(config.indexOf(text[text.length-1])>=0){
- obj.is_pic = true;
- }else{
- obj.is_pic = false;
- }
- obj.name=file.name;
- this.showList[this.showPicIndex].url.push(obj);
-
- }
-
- },
- sureAdd(){
- if(this.showList.length==0){
- this.list.forEach(v=>{
- let obj = {};
- obj.title = v;
- obj.phase = v=='立项'?1:v=='评审'?2:v=='报价'?3:v=='投标'?4:v=='中标'?5:v=='废标'?6:'';
- obj.url=[];
- this.showList.push(obj)
- })
- }else{
- let titles= [];
- this.showList.forEach(v=>{
- titles.push(v.title)
- })
- this.list.forEach(ele=>{
- if(titles.indexOf(ele)<0){
- let obj = {};
- obj.title = ele;
- obj.phase = ele=='立项'?1:ele=='评审'?2:ele=='报价'?3:ele=='投标'?4:ele=='中标'?5:ele=='废标'?6:'';
- obj.url=[];
- this.showList.push(obj)
- }
- })
- }
-
-
- },
- initData(){
- this.axios.post('/api/contract_detail',{order_no:this.$route.query.order_no}).then(res=>{
- this.formData = JSON.parse(JSON.stringify(res.data));
- this.formData.project_date = this.formData.project_date?this.func.replaceDateNoHMS(this.formData.project_date):'';
- this.formData.phase = [];
- res.data.phase.forEach(el => {
- this.formData.phase.push(Number(el))
- });
- delete this.formData.list;
- delete this.formData.file;
- this.showList = res.data.file;
- this.tableData = res.data.list;
- })
- },
- del(index){
- this.tableData.splice(index,1);
- },
- addStage(){
- this.list = [];
- this.showList.forEach(v=>{
- this.list.push(v.title);
- })
- this.show_stage = true;
- },
- uploadSuccess(res) {
- if (res.code == 200) {
- this.$Message.success(res.msg || "上传成功");
- res.data.forEach(v=>{
- v.product_img='';
- })
- if(this.tableData.length==0){
-
- // this.tableData = JSON.parse(JSON.stringify(res.data))
- this.tableData = Object.assign(res.data,this.tableData)
- this.$forceUpdate();
- }else{
- // let data = JSON.parse(JSON.stringify(this.tableData));
- res.data.forEach(v => {
- let arr = [];
- arr = this.tableData.filter(x=>{
- return x.region == v.region&&x.product_title == v.product_title
- })
- if(arr.length==0){
- this.tableData.push(v);
- }else{
- this.tableData.forEach((ele,index)=>{
- if(ele.region == v.region&&ele.product_title == v.product_title){
- this.tableData.splice(index,1,v)
- }
- })
- }
- });
- // this.tableData = JSON.parse(JSON.stringify(data));
- }
-
- } else {
- this.$Message.warning(res.msg || "上传失败");
- }
- },
- uploadError(err) {
- this.$Message.error(err.msg || "上传失败");
- },
- back(){
- this.$router.go(-1)
- },
- postData(){
-
- let data = JSON.parse(JSON.stringify(this.formData));
- data.project_date = this.formData.project_date?Date.parse(this.formData.project_date).toString().slice(0,10):'';
- data.phase = data.phase?this.formData.phase.toString():'';
- switch (this.$route.query.type){
- case '1':
- this.axios.post('/api/contract_add',{...data,children:this.tableData,file:this.showList}).then(res=>{
- if(res.code == 200){
- this.$Message.success(res.msg);
- this.back()
- }
- })
-
- break;
- case '2':
- console.log(111);
- this.axios.post('/api/contract_edit',{...data,children:this.tableData,order_no:this.$route.query.order_no,file:this.showList}).then(res=>{
- if(res.code == 200){
- this.$Message.success(res.msg);
- this.back()
- }
- })
- break;
- }
- },
- totalDel(){
- if(this.selectData.length == 0){
- return this.$Message.warning('请先选择要删除的数据!')
- }
-
- this.confirmDelete({
- title:'批量删除确认?',
- content:"是否确定批量删除?",
- then: ()=>{
- for(let i = 0;i<this.tableData.length;i++){
- let obj ={};
- obj.region= this.tableData[i].region;
- obj.product_title = this.tableData[i].product_title;
- let arr=[];
- arr = this.selectData.filter(v=>{
- return v.region == obj.region&&v.product_title==obj.product_title;
- })
- if(arr.length==1){
- this.tableData.splice(i,1);
- i--;
- }
- }
- if(this.tableData.length==0){
- this.formData.bid_price = '';
- this.formData.agreement_price = ''
- }
- }
- })
-
- },
- handleSelect(e){
- this.selectData = e;
- console.log(this.selectData);
- },
- }
- }
- </script>
- <style lang="scss" scoped>
- .content{
- display: flex;
- flex-wrap: wrap;
- }
- .form_item{
- width:200px
- }
- .upd_file{
- background: rgb(242, 242, 242);
- width: 200px;
- height: 160px;
- cursor: pointer;
- .ico{
- width: 100%;
- line-height: 300%;
- }
- }
- .form_span{
- width:200px;
- display:inline-block;
- }
- .img_content{
- width: 150px;
- height: 150px;
- }
- .img_table_content{
- width: 50px;
- height: 50px;
- }
- .delete-img {
- position: absolute;
- right: 0px;
- top: 0px;
- color: red;
- cursor: pointer;
- }
- .total_img{
- display: flex;
- flex-wrap:wrap;
- .img_item{
- margin-right: 40px;
- position: relative;
- .img_title{
- text-align: center;
- }
- }
-
- }
- .model_agreement{
- display: flex;
- span{
- width: 100px;
- }
- }
- .img_box{
- position: relative;
- }
- </style>
|