当前位置:网站首页>How does a R & d make a small demand bigger and bigger step by step

How does a R & d make a small demand bigger and bigger step by step

2022-06-24 05:00:00 vannding

Play with the cloud development of Tencent cloud through a small demand

Preface

I have a colleague .

His name is Xiaocao .

It's a development , male .

Demand background

Grass cloth , Recently, I was working on a small open source project .

Find me these two days ,” Xiaoding , Give me a little function . Simple !“

demand : Add several input boxes to the page , Fill in an email address in an input box , After the user submits , Send an email to this mailbox .

Start working

” Grass , This requirement is simple , Give me an interface , I cut a page one by one , After that, you can adjust an interface , well-done .“

Cutaway , Cut the page

The project of Xiaocao , It's a nuxt Project ,UI In the framework of ant-design.nuxt Well , As we all know , Follow vue Almost the same way , It's simple , If you have a hand . Open up and open up .

First , Write an interface .

<a-form-model
    :labelCol="{ span: 2, offset: 0 }"
    :wrapperCol="{ span: 16, offset: 0 }"
    ref="refForm"
    :model="emailModel"
    :rules="rules"
    v-if="showForm"
>
    <a-form-model-item  ref="name"  label=" Your name :"  prop="name">
        <a-input  size="large"  v-model="emailModel.name" />
    </a-form-model-item>
    <a-form-model-item  ref="email"  label=" Your email :"  name="email"  prop="email">
        <a-input  size="large"  v-model="emailModel.email" />
    </a-form-model-item>
    <a-form-model-item  ref="content"  label=" Your content :"  prop="content">
        <a-textarea v-model="emailModel.content" placeholder=" The content of the email " :rows="4" />
    </a-form-model-item>
    <a-form-model-item :wrapper-col="{ span: 2, offset: 2 }">
        <a-button  size="large"  type="primary" @click="onSubmit" :loading="loading"> send out </a-button>
    </a-form-model-item>
</a-form-model>

then , Writing point JS Well .

/***********data The data in ***************/
data() {
    return {
        loading: false,
        showForm: true,
        rules: {
            content: [{ required: true, message: ' Fill in whatever you like ', trigger: 'blur' }],
            email: [
                { required: true, message: ' Mailbox is still required ', trigger: 'blur' },
                { type: 'email', message: ' Pay attention to the email format ', trigger: 'blur' },
            ],
        },
        emailModel: {
            name: '',
            email: '',
            content: '',
        },
    };
},
    
/*********** Write a function ***************/
methods: {
    onSubmit() {
        this.$refs.refForm.validate((valid) => {
            if (valid) {
               this.loading  =  true;
               //  Start to adjust the interface 
            } else {
                console.log('error submit!!');
                return  false;
            }
        });
    },
}

Get it done , Go to find Xiaocao and ask for an interface .

” The grass , Give me the interface , Joint debugging !“

” Interface ? What interface !“

” This little function also needs a special interface ? Can't you ?”

“!!!!!@@##1****”

Create a cloudbase, Build a cloud function development environment

Open up and open up

First of all cloudbase Environmental Science

This is because we simply write a function , Just create an empty template .

Because the project of Xiaocao is not in login status . Allow anonymous access here .

Let's add a few more domain names .

Start creating a cloud function .

After creation , You can start writing code online .

however , As a great programmer , Of course, you have to write code locally .

Continue configuration

Install Tencent cloud development cli Tools

sudo npm install -g @cloudbase/cli

After that , Find an empty folder .

tcb -h

Uh , List the commands to see .

Sign in -> Synchronize cloud function list -> Synchronize the cloud function contents . Read the document yourself

Start writing cloud functions , Write an email service .

How to write ?

Certainly First Search it !

Start writing interface code

Learned from the vast number of Internet brick movers , use node Write mail service , Of course, the library is used !

The name of the library used here is nodemailer

According to the example, let's do it carefully copy.

     npm install nodemailer
const nodemailer = require('nodemailer');

const transporter = nodemailer.createTransport({
    service: 'qq',
    auth: {
        user: ' Your email address ',// Sender email 
        pass: ' Authorization code ' // Authorization code , The authorization code when starting the service in the preparation work 
    }
});

const mailOptions = {
    from: '[email protected]', //  sender 
    to: '[email protected]', //  The recipient , You can send multiple , Separated by commas 
    cc: ',[email protected]',// CC 
    subject: ' Send email test ', //  title 
    text: 'Hello world', //  Text 
    html: `<h2>NodeJS Send email test </h2>`
};

transporter.sendMail(mailOptions, function (err, info) {
   if (err) {
       console.log(err);
       return;
   }
   console.log(` Send successfully :${info.accepted}`);
});

It's finished , I touched my thinning hair . Lost in thought !

There is also a need for sender email authentication ! Well, I have to get it . Let's do it again .

Take mine first qq Mailbox do an experiment , After going in , Get the authorization code . Steps are as follows .

Look again , It's still wrong ! here Sender Does it need to be configured . You can't write dead ! What will others do with it . You have to write a configuration table .

that !

Solution : Open a cloud database , Select a specific configuration sheet .

1、 Create a collection

2、 Write a piece of configuration data first

Next , Get down to business , Write code .

const  nodemailer  =  require("nodemailer");
const  cloudbase  =  require("@cloudbase/node-sdk");

const  cloudApp  =  cloudbase.init({
    region: "ap-guangzhou",
    //  Environment can not write , Default to the current environment 
});

const  db  =  cloudApp.database();

function  getEmailInstance(options) {
    const  transport  = {
        host: options.host,
        secureConnection: true, //  Use SSL The way ( safe mode , Prevent information from being stolen )
        auth: {
            user: options.email,
            pass: options.pass,
        },
    };
    return  nodemailer.createTransport(transport);
}

function  sendEmail(opt, sendData) {
    return  new  Promise((resolve, reject) => {
        const  mailTransport  =  getEmailInstance(opt);
        const  options  = {
            from: `"${opt.name}" <${opt.email}>`,
            // to: sendData.to,
            // // cc : '' // CC 
            // // bcc : '' // Send off 
            // subject: " One from Node Mailer The mail ",
            // text: " One from Node Mailer The mail ",
            // html: '<p>html Label text </p>',
            ...sendData,
        };
        mailTransport.sendMail(options, function (err, msg) {
            if (err) {
                reject(err);
            } else {
                resolve();
            }
        });
    });
}

  
const  email  = {
    send: async (data, context) => {
    //  Check the library , obtain options
        try {
            const  dbRes  =  await  db.collection("email-user").doc(data.appid).get();
            const  row  =  dbRes.data[0];
            await  sendEmail(row, data);
            return { code: 0, msg: " Send successfully " };
        } catch (e) {
            console.error(e);
            return { code: 500, msg: " Failed to send mail ", error: e };
        }
    },
};

good , Mail service api The main body is basically finished , however , I found an interesting place .

This nodemailer , It can send html As email text . For mail parameters, please refer to nodemailer Parameter configuration

The front end must not have a rich text editor , Otherwise , It's boring. !

That must be done !!!

Rich text editor

What's going on ? First ask ?

My fishing friends recommended two to me , Have a look , choose wangeditor Well , After all, the document is in Chinese .

Write code write code ~~~

the reason being that nuxt Introduce external libraries into the project , So you have to write a plug-in to introduce

nuxt.config.js

plugins: [
    { src: '~/plugins/wangEditor', ssr: false },
],

plugins/wangEditor.js

import  Wangeditor  from  'wangeditor';
import  Vue  from  'vue';

Vue.prototype.$wangeditor  = (content) =>  new  Wangeditor(content);

WangEditor.vue Components

<template>
    <div :id="id"></div>
</template>

<script>
export  default {
    name: 'WangEditor',
    data() {
        return {
            id: 'e',
            editor: null,
        };
    },
    model: {
        prop: 'val',
        event: 'change',
    },
    props: {
        val: {
            type: String,
            defalut() {
                return  '';
            },
        },
    },
    watch: {},
    mounted() {
        this.id  =  `e${new  Date().getTime()}`;
        this.$nextTick(this.initEditor);
    },
    methods: {
        initEditor() {
            const  editor  =  this.$wangeditor(`#${this.id}`);
            this.editor  =  editor;
            //  To configure  onchange  Callback function 
            editor.config.onchange  = (newHtml) => {
                this.$emit('change', newHtml);
            };
        //  Configure trigger  onchange  Time and frequency , The default is  200ms
            editor.config.onchangeTimeout  =  500; //  It is amended as follows  500ms
            editor.config.customUploadImg  =  this.uploadEditorFile;
            editor.config.customUploadVideo  =  this.uploadEditorFile;
            editor.config.menus  = [
                'head',
                'bold',
                'fontSize',
                'fontName',
                'italic',
                'underline',
                'strikeThrough',
                'indent',
                'lineHeight',
                'foreColor',
                'backColor',
                'link',
                'justify',
                'quote',
                'image',
                'table',
                'code',
                'splitLine',
                'undo',
                'redo',
            ];
            editor.create();
            editor.txt.html(this.val);
        },
    },
};

</script>

effect :

then , Seems to be , Something is wrong !!!

Rich text picture editing , It is not necessary to have the ability to store a picture object .

???

cloudebase Use of cloud storage

First work out the configuration .

Because Xiaocao doesn't need to log in , Therefore, for the time being, we will make it public reading and writing .

This is not safe , Please don't follow

Then write two front-end methods , To upload files .

function  uploadFile(file) {
    const cloudPath = `${new  Date().toLocaleDateString().replace(/\//gi, '-')}/${new  Date().getTime()}.${file.name.split('.').reverse()[0]}`;
    return  cloudApp.uploadFile({
        cloudPath,
        filePath: file,
    });
}

function  uploadFiles(arr) {
    return  Promise.all(arr.map((v) =>  uploadFile(v)));
}

then , Just use wangeditor The method of binding user-defined uploaded files becomes . Reference documents

then , I found out again , We are now at the front , There are already two that need to be called cloudebase The function of . That's not good ?

Pull it out !!! Pull it out . stay nuxt In the words of , Just make it a plug-in unit Well .

import  cloudbase  from  '@cloudbase/js-sdk';
import  Vue  from  'vue';
  
const  FUNCTION_NAME  =  'tools';
const  APPID  =  '< The configuration sheet generated in the cloud database id>';

const  cloudApp  =  cloudbase.init({
    env: '< Environmental Science >',
    region: '< regional >',
});

function  sendEmail(data) {
    return  cloudApp.callFunction({
        name: FUNCTION_NAME,
        data: {
            action: 'email.send',
            data: {
                appid: APPID,
                ...data,
            },
        },
    });
}

function  uploadFile(file) {
    return  cloudApp.uploadFile({
        cloudPath: `${new  Date().toLocaleDateString().replace(/\\//gi, '-')}/${new  Date().getTime()}.${
        file.name.split('.').reverse()[0]
        }`,
        filePath: file,
    });
}
  
function  uploadFiles(arr) {
    return  Promise.all(arr.map((v) =>  uploadFile(v)));
}
  
Vue.prototype.$cloudtool  = {
    uploadFiles,
    uploadFile,
    sendEmail,
};

This is the time , The functions are almost realized .

I touched my thin hair again , Since the front end has been drawn into an independent plug-in , My server has only realized one function with so much effort , Can't it be expanded ?

Extend the functions of cloud functions

The basic idea is , When calling cloud functions , One of the routing parameters represents the function to be accessed , Then the cloud function entry is distributed according to different routes .

Cloud function entry index.js

'use strict';

const  actions  =  require("./actions/index.js");

exports.main  =  async (event, context, callback) => {
    try{
        return  actions(event, context)
    } catch (e) {
        return {
            code: 401,
            msg: ' Parameter error ',
            e
        }
    }
};

Main route /actions/index.js

const  email  =  require("./email");
module.exports  =  async  function(event, context) {
    //  Total route interception 
    try {
        const {action,data} =  event
        const  farr  =  action.split('.')
        return  email({
            action: farr[1],
            data,
        }, context)
    } catch(e) {
        throw  new  Error()
    }
}

Sub route /actions/email.js

const  email  = {
    send: async (data, context) => {
        try {
            const  dbRes  =  await  db.collection("email-user").doc(data.appid).get();
            const  row  =  dbRes.data[0];
            await  sendEmail(row, data);
            return { code: 0, msg: " Send successfully " };
        } catch (e) {
            console.error(e);
            return { code: 500, msg: " Failed to send mail ", error: e };
        }
    },
};

module.exports  =  async  function (event, context) {
    const { action, data } =  event;
    return  email[action](data, event);
};

Front end calls , The format of parameter transfer is as follows :

return  cloudApp.callFunction({
    name: 'tools',
    data: {
        action: 'email.send',
        data: {
            appid: APPID,
            ...
        },
    },
});

that , from now on , My cloud function , You can expand many routes . perfect !

I'm on duty

I found the grass , I showed him the effect confidently .

Grass also touched his sparse hair , Think about it .

“ great , however , Exposed mailbox sending function , There must be a safety problem ? Do you have to find a way to deal with it ?”

that , I have a heavy heart , I searched Tencent cloud ...


To be continued .................................................

原网站

版权声明
本文为[vannding]所创,转载请带上原文链接,感谢
https://yzsam.com/2021/08/20210828124716668F.html