vue+django 实现上传文件保存数据后并发送邮件功能

28 篇文章 1 订阅

提交弹窗的表单数据,
在这里插入图片描述

#在项目中创建一个upload目录,用于存放上传的文件  
PROJECT_BASE_DIR = Path(__file__).resolve().parent.parent.parent
# 获取本机的IP
HOST_IP = socket.gethostbyname(socket.gethostname())
UPLOAD_ROOT = r'\\' + HOST_IP
MAIL_DOMAIN = '@unisoc.com'
MAIL_FROM = 'ibuildmaster' + MAIL_DOMAIN

def validatefilename(filename):  # 验证文件名,有/ \ < > : " |这些字符时去掉,windows系统不能包含这些字符
    rstr = r"[\/\\\:\*\?\"\<\>\|]"  # '/\:*?"<>|'
    new_filename = re.sub(rstr, "", filename)
    return new_filename


def send_html_mail(subject, html_content, recipient_list, sender, cc, build_info=''):
    EmailThread(subject, html_content, recipient_list, sender, cc, build_info).start()


class EmailThread(threading.Thread):
    def __init__(self, subject, html_content, recipient_list, sender, cc, build_info):
        self.subject = subject
        self.recipient_list = recipient_list
        self.html_content = html_content
        self.sender = sender.encode('utf-8')
        self.cc = cc
        self.build_info = build_info
        threading.Thread.__init__(self)

def get_mail_format_content_new_ticket(dict_info):
    content = '<table cellspacing="0" cellPadding="1"  border="1"  style="BORDER-RIGHT: #000000 1px groove; BORDER-TOP: #000000 1px groove; BORDER-LEFT: #000000 1px groove; BORDER-COLLAPSE: collapse" >" >'
    content += '<tr ><th style="background-color: rgba(177, 98, 230, 0.39);">ID:</th><td width="500px"><a  href=' + 'http://10.29.68.61:8080' + '/support-vue/ticket/?ticketid=' + \
               dict_info['ID'] + '>' + dict_info['ID'] + '</a></td></tr>'
    content += '<tr ><th style="background-color: rgba(177, 98, 230, 0.39);">Type:</th><td>' + dict_info['Type'] + '</td></tr>'
    content += '<tr ><th style="background-color: rgba(177, 98, 230, 0.39);">Title:</th><td>' + dict_info['Title'] + '</td></tr>'
    content += '<tr ><th style="background-color: rgba(177, 98, 230, 0.39);">Status:</th><td>' + dict_info['Status'] + '</td></tr>'
    content += '<tr ><th style="background-color: rgba(177, 98, 230, 0.39);">Submitter:</th><td>' + dict_info['Submitter'] + '</td></tr>'
    content += '<tr ><th style="background-color: rgba(177, 98, 230, 0.39);">Submitter_Time:</th><td>' + dict_info['Submitter_Time'] + '</td></tr>'
    content += '<tr ><th style="background-color: rgba(177, 98, 230, 0.39);">Assignee:</th><td>' + dict_info['Assignee'] + '</td></tr>'
    issue_description = dict_info['Description'].decode().split('\n')
    content += '<tr ><th style="background-color: rgba(177, 98, 230, 0.39);">Description:</th><td style="word-wrap:break-word; word-break:break-all;">'
    for issue_index in issue_description:
        content += issue_index.replace("<", "&lt;").replace(">",
                                                            "&gt;") + '<br/>'  # 在 HTML 中不能使用小于号(<)和大于号(>),这是因为浏览器会误认为它们是标签,应使用实体字符替换
    content += '</td></tr>'
    content += '<tr ><th style="background-color: rgba(177, 98, 230, 0.39);">Attachedfile_Url:</th><td style="word-wrap:break-word; word-break:break-all;">' + dict_info[
        'Attachedfile_Url'] + '</td></tr></table>'

    return content


class TestDialog(View):
	def post(self, request):

        current_user = request.user.username

        status = 'Opened'
        title = request.POST.get('title', '')
        ticket_type = request.POST.get('type', '')
        assignee = request.POST.get('assignee', '')
        assignee_name = assignee.strip()
        issue_description = request.POST.get('description', '')
        files = request.FILES.getlist('fileOBJ')

        assigned_to_id = User.objects.get(username=assignee_name)
        issue_attachedfile_url = ''
        create_ticket_success = False  # 标记创建的ticket是否成功
        try:
            check_attached_status = 0
            ticket_obj = Ticket.objects.create(title=title, status=status, ticket_type=ticket_type,
                                               submitter=request.user, assigned_to=assigned_to_id,
                                               issue_description=issue_description,
                                               issue_attachedfile_url=issue_attachedfile_url)
            create_ticket_success = True  # 执行到这里说明ticket创建成功了

            if files:
                uploaded_folder_name = str(ticket_obj.id)
                BASE_DIR_UPLOAD = os.path.join(PROJECT_BASE_DIR, 'upload\\' + uploaded_folder_name)
                if not os.path.exists(BASE_DIR_UPLOAD):
                    os.mkdir(BASE_DIR_UPLOAD)
                for uploadFile in files:
                    try:
                        uploadFilename = validatefilename(uploadFile.name)  # 处理文件中含有/ \ < > : " |这些字符串的异常
                        destination = open(os.path.join(BASE_DIR_UPLOAD, uploadFilename), 'wb+')
                        for chunk in uploadFile.chunks():
                            destination.write(chunk)
                        destination.close()
                        check_attached_status = 1
                    except:
                        print(sys.exc_info())
                        s_error_log = str(sys.exc_info())
                        return HttpResponse(
                            json.dumps({'success': False, 'info': s_error_log,
                                        'create_ticket_success': create_ticket_success}),
                            content_type="application/json")

            if check_attached_status == 1:
                ticket_obj.issue_attachedfile_url = os.path.join(settings.UPLOAD_ROOT, 'upload', str(ticket_obj.id))
                ticket_obj.save()

            history_note = new_history(request.user, ticket_obj, 'new ticket was created', comment="")
                # send the email after created the ticket
			# mail_from =ibuildmaster@unisoc.com 
            mail_from = settings.MAIL_FROM
            mail_to_set = set()
            mail_to_set.add(current_user + settings.MAIL_DOMAIN)
            mail_to_set.add(assignee + settings.MAIL_DOMAIN)
            # mail_to=['xuan.li@unisoc.com', ' young.yu@unisoc.com']
            mail_to = list(mail_to_set)
			# mail_cc=['yihui.hu@unisoc.com', 'young.yu@unisoc.com', 'nina.leng@unisoc.com', 'ran.ju@unisoc.com', 'ming.jiang1@unisoc.com', 'panda.luo@unisoc.com', 'olivine.peng@unisoc.com', 'blake.zhu@unisoc.com', 'peng.yang@unisoc.com', 'qingqing.he@unisoc.com', 'chun.li@unisoc.com', 'hanmeng.zhang@unisoc.com']
            mail_cc = []

            for cm_user in cm_user_list:
                mail_cc.append(cm_user + settings.MAIL_DOMAIN)

            mail_title = 'New Ticket was submitted ---- ID : %d' % (ticket_obj.id)

            print("mail_from =%s \nmail_to=%s\nmail_cc=%s" % (mail_from, mail_to, mail_cc))

            info_content = {}
            info_content['ID'] = str(ticket_obj.id)
            info_content['Type'] = ticket_type
            info_content['Status'] = status
            info_content['Submitter'] = current_user
            info_content['Submitter_Time'] = str(ticket_obj.submitted_time.strftime('%Y-%m-%d %H:%M:%S'))
            info_content['Assignee'] = assignee
            info_content['Title'] = ticket_obj.title
            info_content['Description'] = issue_description.encode('utf-8')
            info_content['Attachedfile_Url'] = ticket_obj.issue_attachedfile_url
            if 'xxxxxx.com' in mail_cc:
                mail_cc.remove('xxxxx.com')
            print('-----------',get_mail_format_content_new_ticket(info_content))
            #send_html_mail(email标题,email正文,email发给谁,)
            send_html_mail(mail_title, get_mail_format_content_new_ticket(info_content), mail_to, mail_from, mail_cc)
        except:
            print(sys.exc_info())

            s_error_log = str(sys.exc_info())
            return HttpResponse(
                json.dumps({'success': False, 'info': s_error_log, 'create_ticket_success': create_ticket_success}),
                content_type="application/json")

        info = []
        info.append(ticket_obj.toJSON())
        return HttpResponse(json.dumps({'success': True, 'info': info, 'history_note': history_note}),
                            content_type="application/json")
<!-- 弹窗 -->
    <el-dialog :title="dialogTitle" :visible.sync="dialogVisible" width="50%" @close="closeDialogForm()" :close-on-click-modal="false" v-alterELDialogMarginTop="{marginTop:'5vh'}">
      <el-divider></el-divider>
      
      <el-form :model='ticketform' :rules="rules" ref="newTicket" label-position="right" label-width='100px'>
        <el-row>
          <el-col :span="24">
            <el-form-item label="Title" >
            <!-- <el-input v-model="ticketform.title"  @input="changeValue" @select="handleSelect(ticketform.title)" placeholder="简短描述你的问题..." title="请使用简短的文字总结你遇到的问题,我们会根据关键词搜索你的问题" style="width:90%" type="text" ></el-input> -->

              <!-- <el-input v-model="ticketform.title" placeholder="简短描述你的问题..." title="请使用简短的文字总结你遇到的问题,我们会根据关键词搜索你的问题" style="width:90%" v-on:input ="inputFunc"></el-input> -->
            <el-autocomplete 
                  v-model="state"
                  :fetch-suggestions="querySearchAsync"
                  placeholder="请输入内容"
                  @select="handleSelect(state)"
                  style="width:90%"
                  @input="loadAll"
                ></el-autocomplete>
            </el-form-item>
          </el-col>
        </el-row>
    
        <el-row>
          <el-col :span='12'>
            <el-form-item label="Type" required>
              <el-select v-model="ticketform.type" placeholder="请选择" @change="changeSelect()" style="width:75%" >
              
                <el-option
                  v-for="(item,index) in Newticket_Type"
                  :key="index"
                  :label="item"
                  :value="item"
                >
                </el-option>        
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span='12'>
            <el-form-item label="Assignee" required>
              <el-select v-model="ticketform.assignee" placeholder="请选择" style="width:75%">           
                <el-option
                  v-for="(item1,index1) in ass_options"
                    :key="index1"
                    :label="item1"
                    :value='item1'
                  >   
                  </el-option>   
                    
              </el-select>
            </el-form-item> 
          </el-col>
        </el-row>
          

           <el-form-item label="Description">
          <el-input v-model="ticketform.data3" type="textarea" :rows="8" style="width:90%" 
          ></el-input>
          </el-form-item> 
          
    </el-form> 
     
        <el-upload
              class="upload-demo"
              ref="upload"
              action=""
              multiple
              :on-exceed="handleExceed"
              :on-remove="handleRemove"
              :limit="1"
              :file-list="fileList"
              
              :auto-upload="false"
              :on-change="fileChange"
              >
              <el-button slot="trigger" size="small" type="primary" v-model="fileList" style="margin-left:100px">选取文件</el-button>

              <div slot="tip" class="el-upload__tip" style="display: inline-block;margin-left: 20px">请选择单个文件上传</div>
            </el-upload>     
      <span slot="footer" class="dialog-footer">
        <el-button type="primary" @click="httpRequest('newTicket')">确 定</el-button>
        <el-button type="info" @click="closeDialogForm()">取 消</el-button>
    
    </span>


    </el-dialog>






 //newTicket弹窗
    
   httpRequest(param){
      console.log(param,'请求')
      let formdata = new FormData()
      formdata.append('fileOBJ', this.ticketform.file)
      formdata.append('title', this.state)
      formdata.append('type', this.ticketform.type)
      formdata.append('assignee', this.ticketform.assignee)
      formdata.append('description', this.ticketform.data3)
      let that = this
      that.$axios.post(that.baseURL+'PROD/testdialog/documents/',formdata)
     .then(res =>{
        console.log(res.data)
        if(res.data.code== 1){
          that.ticketform.url  = res.data.name
          // 拼接imageuri
          that.$message.success(`${res.data.msg}`);
          
        }
        else{
          this.$message.error(`${res.data.msg}`);
        }
      })
      .catch(err=>{
        console.log(err);
        that.$message.error('获取后端查询结果出现异常!')
      })

      
    },
    handleExceed(files, fileList) {
      this.$message.warning(`当前限制选择单个文件`);
    },
    fileChange(file, fileList) {
      this.ticketform.file=file.raw;
      console.log(this.fileList);
    },
    // 文件删除时
      handleRemove (file, fileList) {
        console.log(file, fileList,'-------------')
        this.fileList = [] // 文件列表置空
      },

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Vue是一种流行的JavaScript框架,用于构建用户界面。Django是一个用于构建Web应用程序的Python框架。使用这两种框架可以很容易地实现文件下载的功能。 首先,在Django中,你需要创建一个视图函数来处理文件下载的请求。你可以使用Python的内置模块`open`来打开文件,并将其内容发送给浏览器。具体代码如下: ```python from django.http import FileResponse import os def download_file(request): file_path = '/path/to/your/file.pdf' # 文件路径 file_name = os.path.basename(file_path) # 获取文件名 response = FileResponse(open(file_path, 'rb'), as_attachment=True) response['Content-Disposition'] = f'attachment; filename="{file_name}"' return response ``` 在Vue中,你可以创建一个按钮或链接来触发文件下载的请求。使用`axios`库来发起HTTP请求并下载文件。具体代码如下: ```javascript <template> <div> <button @click="downloadFile">下载文件</button> </div> </template> <script> import axios from 'axios'; export default { methods: { downloadFile() { axios({ url: 'http://your-api-url/download', method: 'GET', responseType: 'blob', // 必须设置为blob }).then(response => { const url = window.URL.createObjectURL(new Blob([response.data])); const link = document.createElement('a'); link.href = url; link.setAttribute('download', 'file.pdf'); // 设置下载文件文件名 document.body.appendChild(link); link.click(); }); } } } </script> ``` 以上是一个简单的示例,演示了如何在VueDjango实现文件下载的功能。当用户点击“下载文件”按钮时,Vue发送一个HTTP请求到Django后端,后端会返回文件的内容,然后前端利用Blob对象创建一个URL,最终通过创建一个a标签实现文件下载。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

季布,

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值