第60章 用户增、修、删的前端实现

news2024/10/6 8:33:38

1  \src\components\Users\AddUser.vue

<template>

    <!--

    elmentUI 子页面的渲染显示注意事项说明:

    子页面的渲染显示必须的使用“<el-dialog></el-dialog>标签及其所包含的子标签,否则子页面将不会被渲染显示出来。

    -->

    <el-dialog width="30%">

        <template #header>

            <div class="my-header">

                <h1 style="margin: 0px; padding: 0px; ">

                    <el-icon style="margin-right:5px; font-size: 25px; color:#337ecc; vertical-align: middle">

                        <CirclePlusFilled />

                    </el-icon>

                    添加用户

                </h1>

            </div>

        </template>

        <el-form label-width="100px" class="demo-ruleForm" label-position="left" status-icon :model="formAdd"

            :rules="ruleAdd" ref="refRule">

            <el-form-item label="账户:" prop="name">

                <el-input v-model="formAdd.name" />

            </el-form-item>

            <el-form-item label="电子邮箱:" prop="email">

                <el-input v-model="formAdd.email" />

            </el-form-item>

            <el-form-item label="手机号:" prop="phone">

                <el-input v-model="formAdd.phone" />

            </el-form-item>

            <el-form-item label="角色:" prop="roleIdList">

                <el-checkbox-group v-model="formAdd.roleIdList">

                    <el-checkbox v-for="item in formAdd.roleList" :key="item.id" :label="item.id">

                        {{item.name}}

                    </el-checkbox>

                </el-checkbox-group>

            </el-form-item>

        <!--    <el-form-item label="系统帐户:" prop="isSystemAccount">

                <el-select v-model="formAdd.isSystemAccount" style="width: 100%;">

                    <el-option label="系统帐户" :value="true" />

                    <el-option label="其它" :value="false" />

                </el-select>

            </el-form-item> -->

            <el-form-item label="激活:" prop="isActive">

                <el-select v-model="formAdd.isActive" style="width: 100%;">

                    <el-option label="激活" :value="true" />

                    <el-option label="禁用" :value="false" />

                </el-select>

            </el-form-item>

            <el-form-item label="可用:" prop="deleted">

                <el-select v-model="formAdd.deleted" style="width: 100%;">

                    <el-option label="已被删除" :value="true" />

                    <el-option label="可用" :value="false" />

                </el-select>

            </el-form-item>

        </el-form>

        <template #footer>

            <span class="dialog-footer">

                <el-button @click="this.formAdd.centerDialogVisible = false"> </el-button>

                <el-button type="primary" @click="onSubmit"> </el-button>

            </span>

        </template>

    </el-dialog>

</template>

<script>

    import {

        getCustomerByEmail,

        getCustomerByPhone,

        getRoleIndex,

        createCustomer,

    } from '../../common/http.api.js';

    export default {

        /*namepropParent属性用于在子页面成功提交后,控制对父页面的自动刷新*/

        name: 'AddUser',

        props: {

            propParent: {},

        },

        data() {

            //验证1个指定的电子邮箱已经是否被注册。

            const validateEmailUnique = async (rule, value, callback) => {

                if (value) {

                    let data = await this.isEmailUnique(value);

                    //console.log(data);

                    if (data.status == 200 && data.response) {

                        callback(new Error("该电子邮箱已经被注册!"));

                    } else {

                        callback();

                    }

                }

            };

            //验证1个指定的手机号已经是否被注册。

            const validatePhoneUnique = async (rule, value, callback) => {

                if (value) {

                    let data = await this.isPhoneUnique(value);

                    if (data.status == 200 && data.response) {

                        callback(new Error("该手机号已经被注册!"));

                    } else {

                        callback();

                    }

                }

            };

            return {

                formAdd: {

                    name: '',

                    email: '',

                    phone: '',

                    roleIdList: [],

                    roleList: [],

                    deleted: false,

                    isActive: true,

                    //该实例用于指示,当前页面角色编辑子页面是否在父窗口中显示出来。

                    centerDialogVisible: false,

                },

                //用户添加表单输入验证初始化。

                ruleAdd: {

                    name: [{

                            required: true,

                            message: '请输入账号名!',

                            trigger: 'blur',

                        },

                        {

                            min: 2,

                            max: 16,

                            message: '账号名的长度应在216个字符之间!',

                            trigger: 'blur'

                        },

                    ],

                    email: [{

                            required: true,

                            message: '请输入电子邮箱!',

                            trigger: 'blur',

                        },

                        {

                            pattern: /^([a-zA-Z0-9_-])+@([a-zA-Z0-9_-])+(.[a-zA-Z0-9_-])+/,

                            message: "电子邮箱格式错误!"

                        },

                        {

                            validator: validateEmailUnique,

                            trigger: "blur",

                        },

                    ],

                    phone: [{

                            required: true,

                            message: "请输入手机号!",

                            trigger: 'blur',

                        },

                        {

                            pattern: 11 && /^((13|14|15|16|17|18|19)[0-9]{1}\d{8})$/,

                            message: "手机号格式错误!"

                        },

                        {

                            validator: validatePhoneUnique,

                            trigger: "blur",

                        },

                    ],

                    roleIdList: [{

                            required: true,

                            message: "必须选择1指定的角色!",

                            trigger: 'blur',

                        },

                    ],

                },

            };

        },

        //监视父窗口传递的参数实例,来监视弹出对话框的不显示。

        watch: {

            async propParent(val) {

                //console.log(val);

                /*this.formAdd = val用于在子页面成功提交后,控制对子页面的自动关闭和父页面的自动刷新*/

                this.formAdd = val;

                this.formAdd.isActive = true;

                this.formAdd.deleted = false;

                let param = {

                    isActive: this.formAdd.isActive,

                };

                let res = await getRoleIndex(param);

                this.formAdd.roleList = res.data.response;

                //获取默认被选中的角色

                this.formAdd.roleIdList=[];

                this.formAdd.roleIdList.push(this.formAdd.roleList.find(route => route.name == "Register").id);

                //console.log(this.formAdd.roleIdList.push(this.formAdd.roleList.find(route => route.name == "Register").id));

            },

        },

        methods: {

            //通过1个指定电子邮箱获取1个指定的用户实例,验证电子邮箱的唯一性。

            async isEmailUnique(email) {

                let emailParam = {

                    email: email,

                };

                let res = await getCustomerByEmail(emailParam);

                return res.data;

            },

            //1个指定手机号获取1个指定的用户实例,验证手机号的唯一性。

            async isPhoneUnique(phone) {

                let phoneParam = {

                    phone: phone,

                };

                let res = await getCustomerByPhone(phoneParam);

                return res.data;

            },

            //添加提交事件

            async onSubmit() {

                this.$refs.refRule.validate(async (valid) => {

                    if (valid) {

                        let para = {

                            name: this.formAdd.name,

                            email: this.formAdd.email,

                            phone: this.formAdd.phone,

                            roleIdList: this.formAdd.roleIdList,

                            isSystemAccount: this.formAdd.isSystemAccount,

                            isActive: this.formAdd.isActive,

                            deleted: this.formAdd.deleted,

                        };

                        console.log(para);

                        let res = await createCustomer(JSON.stringify(para));

                        console.log(res.data);

                        if (res.status == 200) {

                            this.$message.success("成功添加");

                            //"runParent":自定义事件名,= @runParent(父控件)

                            this.$emit("runParent");

                            this.formAdd.centerDialogVisible = false;

                        } else {

                            this.$message.error(res.msg);

                            this.formAdd.centerDialogVisible = true;

                        }

                    } else {

                        this.$message.error('输入不能通过验证 !');

                        this.formAdd.centerDialogVisible = true;

                        return false;

                    }

                });

            },

        },

        async mounted() {

        },

    };

</script>

<style scoped lang="scss">

    .my-header {

        display: flex;

        flex-direction: row;

        justify-content: space-between;

    }

</style>

2  \src\components\Users\ EditUser.vue

<template>

    <!--

    elmentUI 子页面的渲染显示注意事项说明:

    子页面的渲染显示必须的使用“<el-dialog></el-dialog>标签及其所包含的子标签,否则子页面将不会被渲染显示出来。

    -->

    <el-dialog width="30%">

        <template #header>

            <div class="my-header">

                <h1 style="margin: 0px; padding: 0px; ">

                    <el-icon style="margin-right:5px; font-size: 25px; color:#337ecc; vertical-align: middle">

                        <Edit />

                    </el-icon>

                    编辑用户

                </h1>

            </div>

        </template>

        <el-form :model="formUser" label-width="100px" class="demo-ruleForm" label-position="left" status-icon

            :rules="ruleEdit" ref="refRule">

            <!--

            elmentUI Upload组件注意事项说明:

            v-model:file-list:文件上传--需要或已经被上传的文件。

            :action:必须被实例化的属性,文件上传--上传文件所需要调用的指定的后端控制器行为方法。

            name:如果指定的后端控制器行为方法中使用IFormFile参数实例,则该属性是必须被实例化的属性,且属性实例化值与IFormFile参数名必须相同。

            :limit="1"//1次上传操作中,最大能够上传多文件的个数值。

            :headers(注意):很多网上的示例把headers属性实例化为“mutipart/form-data,在此我重申一下,没有必要。elementUI已经封装加工过了,

                同时如果设定headers属性实例,还会造成异常:"Failed to read the request form. Missing content-type boundary"

                或异常:"body length limit 16384 exceeded"

            :before-upload:文件上传前验证文件是否符合所规则的上传规则。

            -->

            <el-upload v-model:file-list="fileList" class="upload-demo" list-type="picture" :action="actionRequestUrl"

                name="formFile" :before-upload="beforeUpload" :on-change="onUploadChange" :data="paramData">

                <el-button type="primary">点击上传</el-button>

            </el-upload>

            <el-form-item label="编号:">

                <el-input v-model="formUser.id" disabled />

            </el-form-item>

            <el-form-item label="名称:" prop="name">

                <el-input v-model="formUser.name" />

            </el-form-item>

            <el-form-item label="邮箱:" prop="email">

                <el-input v-model="formUser.email" />

            </el-form-item>

            <el-form-item label="手机号:" prop="phone">

                <el-input v-model="formUser.phone" />

            </el-form-item>

            <el-form-item label="角色:" prop="roleIdList">

                <el-checkbox-group v-model="formUser.roleIdList">

                    <el-checkbox v-for="item in formUser.roleList" :key="item.id" :label="item.id">

                        {{item.name}}

                    </el-checkbox>

                </el-checkbox-group>

            </el-form-item>

            <!-- 注意:必须使用 :value="true",不能使用 value=true,否则会出现:

            “ [Vue warn]: Invalid prop: type check failed for prop "modelValue". Expected String | Number | Object, got Boolean with value true. ”

            警告信息 -->

            <!-- <el-form-item label="系统帐户:" prop="isSystemAccount">

                <el-select v-model="formUser.isSystemAccount" style="width: 100%;">

                    <el-option label="系统帐户" :value="true" />

                    <el-option label="其它" :value="false" />

                </el-select>

            </el-form-item> -->

            <el-form-item label="激活:" prop="isActive">

                <el-select v-model="formUser.isActive" style="width: 100%;">

                    <el-option label="激活" :value="true" />

                    <el-option label="禁用" :value="false" />

                </el-select>

            </el-form-item>

            <el-form-item label="可用:" prop="deleted">

                <el-select v-model="formUser.deleted" style="width: 100%;">

                    <el-option label="已被删除" :value="true" />

                    <el-option label="可用" :value="false" />

                </el-select>

            </el-form-item>

        </el-form>

        <template #footer>

            <span class="dialog-footer">

                <el-button @click="onCancel"> </el-button>

                <el-button type="primary" @click="submitEdit"> </el-button>

            </span>

        </template>

    </el-dialog>

</template>

<script>

    import {

        getCustomerByEmail,

        getCustomerByPhone,

        getRoleIndex,

        editCustomer,

    } from '../../common/http.api.js';

    export default {

        name: 'EditUser',

        props: {

            propParent: {},

        },

        data() {

            //验证1个指定的电子邮箱已经是否被注册。

            const validateEmailUnique = async (rule, value, callback) => {

                if (value) {

                    let data = await this.isEmailUnique(value);

                    //console.log(data);

                    if (data.status == 200 && data.response) {

                        callback(new Error("该电子邮箱已经被注册!"));

                    } else {

                        callback();

                    }

                }

            };

            //验证1个指定的手机号已经是否被注册。

            const validatePhoneUnique = async (rule, value, callback) => {

                if (value) {

                    let data = await this.isPhoneUnique(value);

                    if (data.status == 200 && data.response) {

                        callback(new Error("该手机号已经被注册!"));

                    } else {

                        callback();

                    }

                }

            };

            return {

                //用户编辑表单实例初始化。

                formUser: {

                    id: 0,

                    name: '',

                    email: '',

                    phone: '',

                    avatar: '',

                    roleIdList: [],

                    roleList: [],

                    isSystemAccount: false,

                    isActive: true,

                    deleted: false,

                    //该实例用于指示,当前页面角色编辑子页面是否在父窗口中显示出来。

                    centerDialogVisible: false,

                },

                //文件上传--需要或已经被上传的文件。

                fileList: [{

                    name: '',

                    url: '',

                }],

                //文件上传--上传文件所需要调用的指定的后端控制器行为方法。

                actionRequestUrl: '',

                //文件上传--允许被上传文件的类型规则

                fileType: ["bmp", "gif", "jpeg", "jpg", "jpe", "jfif", "pjpeg", "webp", "png", "svg", "tiff", "tif"],

                //文件上传--允许被上传文件的最大大小值规则,单位:MB

                fileSize: 10,

                paramData: {

                    customerId: 0,

                },

                //用户添加表单输入验证初始化。

                ruleEdit: {

                    name: [{

                            required: true,

                            message: '请输入账号名!',

                            trigger: 'blur',

                        },

                        {

                            min: 2,

                            max: 16,

                            message: '账号名的长度应在216个字符之间!',

                            trigger: 'blur'

                        },

                    ],

                    email: [{

                            required: true,

                            message: '请输入电子邮箱!',

                            trigger: 'blur',

                        },

                        {

                            pattern: /^([a-zA-Z0-9_-])+@([a-zA-Z0-9_-])+(.[a-zA-Z0-9_-])+/,

                            message: "电子邮箱格式错误!"

                        },

                        {

                            validator: validateEmailUnique,

                            trigger: "blur",

                        },

                    ],

                    phone: [{

                            required: true,

                            message: "请输入手机号!",

                            trigger: 'blur',

                        },

                        {

                            pattern: 11 && /^((13|14|15|16|17|18|19)[0-9]{1}\d{8})$/,

                            message: "手机号格式错误!"

                        },

                        {

                            validator: validatePhoneUnique,

                            trigger: "blur",

                        },

                    ],

                    roleIdList: [{

                        required: true,

                        message: "必须选择1指定的角色!",

                        trigger: 'blur',

                    }, ],

                },

            };

        },

        //监视父窗口传递的参数实例,使当前子页面中的表单始终显示父窗口最新传递的参数实例。

        watch: {

            async propParent(val) {

                //console.log(val);

                /*this.formUser = val用于在子页面成功提交后,控制对子页面的自动关闭和父页面的自动刷新*/

                this.formUser = val;

                this.fileList[0].name = "";

                this.fileList[0].url = this.formUser.avatar;

                //获取所有角色。

                let param = {

                    isActive: this.formUser.isActive,

                };

                let res = await getRoleIndex(param);

                this.formUser.roleList = res.data.response;

                //获取默认被选中的角色。

                this.formUser.roleIdList = [];

                this.formUser.roleIdList = val.roleCollection.map((item) => item.id);

            },

        },

        methods: {

            //上传文件之前,验证指定上传文件是否符合上传规则。

            beforeUpload(file) {

                if (file.type != "" || file.type != null || file.type != undefined) {

                    //清空已上传的文件列表

                    //this.$refs.upload.clearFiles();

                    //截取文件的后缀,判断文件类型

                    let fileExt = file.name.replace(/.+\./, "").toLowerCase();

                    //计算指定上传文件大小是否大于10MB

                    let isMaxFileSize = file.size / 1024 / 1024 <= 10;

                    //如果大于i大于10MB

                    if (!isMaxFileSize) {

                        this.$message.error("上传文件大小不能超过 10MB!");

                        return false;

                    }

                    //如果文件类型不在允许上传的范围内

                    if (this.fileType.includes(fileExt)) {

                        return true;

                    } else {

                        this.$message.error("上传文件格式不正确!");

                        return false;

                    }

                }

            },

            //头像图片文件发生变更时,实现头像图片文件的上传操作。

            //注意:该方法必须包含“file”参数。

            async onUploadChange(file, fileList) {

                /* console.log("需要或已经被上传的文件列表:", fileList);

               

                console.log("1个指定的需要被上传的文件:", file);

                console.log("1个指定的需要被上传文件的大小:", file.size);

                console.log("1个指定的需要被上传文件的文件名:", file.name);

                console.log("1个指定的需要被上传文件的完整信息(作为传递参数的实例值):", file.raw);

                console.log("1个指定的需要被上传文件的URL", file.url);

                console.log("上传操作后所返回的成功/失败的数据信息:", file.response);

                console.log("1个指定用户的长整型编号值:", this.formUser.id); */

                this.paramData.customerId = this.formUser.id;

                this.actionRequestUrl = "";

                //this.actionRequestUrl = "https://localhost:7239/Customer/PostAvatarStream?customerId=" + this.formUser.id;

                this.actionRequestUrl = " https://localhost:7239/Customer/PostAvatarStream";

                //需要或已经被上传的文件列表中只渲染显示最新的1个上传文件。

                this.fileList = fileList.slice(-1);

                //console.log("渲染显示的文件列表:", this.fileList);

            },

            //通过1个指定电子邮箱获取1个指定的用户实例,验证电子邮箱的唯一性。

            async isEmailUnique(email) {

                let emailParam = {

                    email: email,

                    customerId: this.formUser.id,

                };

                let res = await getCustomerByEmail(emailParam);

                return res.data;

            },

            //1个指定手机号获取1个指定的用户实例,验证手机号的唯一性。

            async isPhoneUnique(phone) {

                let phoneParam = {

                    phone: phone,

                    customerId: this.formUser.id,

                };

                let res = await getCustomerByPhone(phoneParam);

                return res.data;

            },

            //编辑提交事件

            async submitEdit() {

                this.$refs.refRule.validate(async (valid) => {

                    if (valid) {

                        let para = {

                            id: this.formUser.id,

                            name: this.formUser.name,

                            email: this.formUser.email,

                            phone: this.formUser.phone,

                            roleIdList: this.formUser.roleIdList,

                            isSystemAccount: this.formUser.isSystemAccount,

                            isActive: this.formUser.isActive,

                            deleted: this.formUser.deleted,

                        };

                        let res = await editCustomer(JSON.stringify(para));

                        //console.log(res.data);

                        if (res.status == 200) {

                            this.$message.success("成功修改");

                            //"runParent":自定义事件名,= @runParent(父控件)

                            this.$emit("runParent");

                            this.formUser.centerDialogVisible = false;

                        } else {

                            this.$message.error(res.msg);

                            this.formUser.centerDialogVisible = true;

                        }

                    } else {

                        this.$message.error('输入不能通过验证 !');

                        this.formUser.centerDialogVisible = true;

                        return false;

                    }

                });

            },

           async onCancel() {

                //"runParent":自定义事件名,= @runParent(父控件)

                this.$emit("runParent");

                this.formUser.centerDialogVisible = false;

            },

        },

        async mounted() {

        },    };

</script>

<style scoped lang="scss">

    .my-header {

        display: flex;

        flex-direction: row;

        justify-content: space-between;

    }

</style>

 

3  \src\views\Users\UserView.vue

<template>

    <div class="wrap">

        <!--注意:1回到顶部组件及其回滚内容都必须包含到同1div容器中。-->

        <!-- 2div容器中必须有1个唯1性的样式类(例如:wrap)的定义,以便回到顶部组件进行回滚时进行定位。 -->

        <!-- 3回到顶部组件  必须在所有的回滚内容之上。 -->

        <el-backtop :bottom="100" target=".wrap" style="background-color: #666;">

            <el-icon style="color: #99ffff; font-size: 40px; margin-top: -2px;">

                <CaretTop />

            </el-icon>

        </el-backtop>

        <el-form :model="queryForm" :rules="queryRule" ref="refRule" label-width="120px" label-position="left">

            <el-row :gutter="20">

                <el-col :span="18">

                    <el-form-item label="账户:">

                        <el-input v-model="queryForm.name" type="text" />

                    </el-form-item>

                </el-col>

                <el-col :span="6">

                    <el-form-item label="激活:">

                        <el-select v-model="queryForm.isActive">

                            <el-option label="不限" value="" />

                            <el-option label="激活" value=true />

                            <el-option label="禁用" value=false />

                        </el-select>

                    </el-form-item>

                </el-col>

            </el-row>

            <el-row :gutter="20">

                <el-col :span="18">

                    <el-form-item label="电子邮箱:">

                        <el-input v-model="queryForm.email" type="text" />

                    </el-form-item>

                </el-col>

                <el-col :span="6">

                    <el-form-item label="系统账户:">

                        <el-select v-model="queryForm.isSystemAccount">

                            <el-option label="不限" value="" />

                            <el-option label="系统账户" value=true />

                            <el-option label="其它" value=false />

                        </el-select>

                    </el-form-item>

                </el-col>

            </el-row>

            <el-row :gutter="20">

                <el-col :span="18">

                    <el-form-item label="手机:">

                        <el-input v-model="queryForm.phone" type="text" />

                    </el-form-item>

                </el-col>

                <el-col :span="6">

                    <el-form-item label="可用:">

                        <el-select v-model="queryForm.deleted">

                            <el-option label="不限" value="" />

                            <el-option label="已被删除" value=true />

                            <el-option label="可用" value=false />

                        </el-select>

                    </el-form-item>

                </el-col>

            </el-row>

            <el-row :gutter="20">

                <el-col :span="12">

                    <el-form-item label="开始日期:" prop="createdDateTimeFrom">

                        <el-date-picker style="width: 100%" v-model="queryForm.createdDateTimeFrom" type="date"

                            format="YYYY-MM-DD" value-format="YYYY-MM-DD" :append-to-body="false">

                        </el-date-picker>

                    </el-form-item>

                </el-col>

                <el-col :span="12">

                    <el-form-item label="结束日期:" prop="createdDateTimeTo">

                        <el-date-picker style="width: 100%" v-model="queryForm.createdDateTimeTo" type="date"

                            format="YYYY-MM-DD" value-format="YYYY-MM-DD" :append-to-body="false"> </el-date-picker>

                    </el-form-item>

                </el-col>

            </el-row>

            <el-row :gutter="20">

                <el-col :span="24">

                    <el-button type="primary" @click="onSubmit">

                        <el-icon style="margin-right:5px; font-size: 16px;">

                            <Search />

                        </el-icon>

                       

                    </el-button>

                    <el-button @click="onResert">

                        <el-icon style="margin-right:5px; font-size: 16px;">

                            <RefreshRight />

                        </el-icon>

                       

                    </el-button>

                </el-col>

            </el-row>

        </el-form>

        <el-row type="flex" justify="end" style="margin:5px 0px;">

            <el-col :span="8">

                <div class="lightgreen-box">

                    <el-button style="background-color: #79bbff; color: #FFFFFF; margin-right:10px" @click="addUser()">

                        <el-icon style="margin-right:5px; font-size: 22px;">

                            <CirclePlusFilled />

                        </el-icon>

                       

                    </el-button>

                    <el-button type="danger" @click="deleteSelected()">

                        <el-icon style="margin-right:5px; font-size: 22px;">

                            <Delete />

                        </el-icon>

                        删除所选

                    </el-button>

                </div>

            </el-col>

        </el-row>

        <!-- 指定页面渲染显示,handleTableSort:排序;selectionChange:所选择的复选框控件,为删除所选操作提供数据支撑;-->

        <el-table :data="currentPageList" style="width: 100%" :default-sort="{

                    'prop': JSON.parse(this.pagination.OrderByModel).OrderByFiled,

                    'order':JSON.parse(this.pagination.OrderByModel).OrderByType}" @sort-change="handleTableSort" ref="refTable"

            @selection-change="selectionChange">

            <el-table-column type="selection" width="50px" />

            <el-table-column property="id" label="编号" width="80px" sortable />

            <el-table-column property="name" label="帐号" sortable>

                <template #default="scope">

                    <el-avatar shape="square" :size="80" style="vertical-align: middle; margin-right: 3px; float: left;"

                        :src="scope.row.avatar" :fit="fitCover">

                    </el-avatar>

                    <div class="userinfo-inner">

                        <span style="width: 100%; height: 20px; line-height: 20px;">

                            {{scope.row.name}}

                        </span>

                        <br />

                        <span

                            style=" width: 100%; height: 10px; line-height: 10px; font-size: 60%; color: #999999; font-weight: 400;">

                            {{scope.row.email}}

                        </span>

                        <br />

                        <span

                            style=" width: 100%; height: 10px; line-height: 10px; font-size: 60%; color: #999999; font-weight: 400;">

                            {{scope.row.phone}}

                        </span>

                    </div>

                </template>

            </el-table-column>

            <el-table-column label="角色" align="center" width="100px">

                <template #default="scope">

                    <el-tag v-for="tag in scope.row.roleCollection" :key="tag.id" effect="plain"

                        style="margin-bottom: 3px;">

                        {{ tag.name }}

                    </el-tag>

                </template>

            </el-table-column>

            <el-table-column label="状态" align="center" width="85px">

                <template #default="scope">

                    <!--    <el-tag effect="plain" v-show="scope.row.isSystemAccount">系统帐户</el-tag>

                <el-tag type="success" v-show="!scope.row.isSystemAccount">其它</el-tag> -->

                    <el-tag effect="plain" v-show="scope.row.isSystemAccount">系统帐户</el-tag>

                    <el-tag type="success" effect="plain" v-show="!scope.row.isSystemAccount"

                        style="letter-spacing:7px; text-indent:10px">其它</el-tag>

                    <el-tag type="success" effect="plain" style="letter-spacing:7px; text-indent:10px; margin: 3px 0px;"

                        v-show="scope.row.isActive">激活</el-tag>

                    <el-tag type="danger" effect="plain" style="letter-spacing:7px; text-indent:10px; margin: 3px 0px;"

                        v-show="!scope.row.isActive">禁用</el-tag>

                    <el-tag type="success" effect="plain" v-show="!scope.row.deleted"

                        style="letter-spacing:7px; text-indent:10px">可用</el-tag>

                    <el-tag type="danger" effect="plain" v-show="scope.row.deleted">已被删除</el-tag>

                </template>

            </el-table-column>

            <el-table-column prop="createdDateTime" label="注册时间" :formatter="dateTimeformat" width="155" sortable />

            <el-table-column prop="updatedDateTime" label="最后更新时间" :formatter="dateTimeformat" width="155" sortable />

            <el-table-column align="center" width="85px">

                <template #default="scope">

                    <el-button type="primary" size="small" style="" :disabled="scope.row.email=='admin@yourStore.com'"

                        @click="onResertPassword(scope.row)">

                        密码重置

                    </el-button>

                    <el-button type="primary" size="small"

                        style="letter-spacing:7px; text-indent:10px; margin: 7px 0px;"

                        :disabled="scope.row.email=='admin@yourStore.com'" @click="editUser(scope.row)">

                        编辑

                    </el-button>

                    <el-button type="danger" size="small" style="letter-spacing:7px; text-indent:10px; margin:0px;"

                        :disabled="scope.row.email=='admin@yourStore.com'" @click="deleteSingle(scope.row)">

                        删除

                    </el-button>

                </template>

            </el-table-column>

        </el-table>

        <!--  “->”:设定 “el-pagination”分页组件靠右显示。 -->

        <el-pagination v-model:current-page="this.pagination.pageIndex" v-model:page-size="this.pagination.pageSize"

            :page-sizes="[3, 10, 15, 20, 50, 100]" :total="this.pagination.totalCount" prev-text="上一页" next-text="下一页"

            background layout="->, total, sizes, prev, pager, next" @size-change="handleSizeChange"

            @current-change="handleCurrentChange" />

        <!-- 注意: @runParent,不能与"editDialogClose"同名,否则会出现:

                “ [Vue warn]:emitted event "editDialogClose" but it is neither declared in the emits option nor as an "onEditDialogClose" prop. ”

                警告信息 -->

        <EditUser v-model="this.formEidt.centerDialogVisible" :propParent="this.formEidt" @runParent="editDialogClose">

        </EditUser>

        <AddUser v-model="this.formAdd.centerDialogVisible" :propParent="this.formAdd" @runParent="addDialogClose">

        </AddUser>

    </div>

</template>

<script>

    import moment from 'moment';

    import {

        postCustomerIndex,

        resertPassword,

        deleteCustomer,

        deleteSelectedCustomer,

    } from '../../common/http.api.js';

    import EditUser from '@/components/Users/EditUser.vue';

    import AddUser from '@/components/Users/AddUser.vue'

    export default {

        components: {

            EditUser,

            AddUser,

        },

        data() {

            //验证查询表单中的开始日期必须小于等于当前时间。

            const validateDateTimeFrom = (rule, value, callback) => {

                if (value != null || value != '') {

                    if (this.moment(value) > Date.now())

                        callback(new Error("开始日期必须小于等于当前时间!"));

                }

                callback();

            };

            //验证查询表单中的开始日期必须小大于等于开始日期;且小于等于当前时间。

            const validateDateTimeTo = (rule, value, callback) => {

                if (this.queryForm.createdDateTimeFrom != '') {

                    if (value == null || value == '') {

                        callback(new Error("请输入结束日期!"));

                    } else if (this.moment(value) > Date.now()) {

                        callback(new Error("结束日期必须小于等于当前时间!"));

                    } else if (this.moment(value) < this.moment(this.queryForm.createdDateTimeFrom)) {

                        callback(new Error("结束日期必须大于等于开始日期!"));

                    }

                }

                callback();

            };

            return {

                //获取日期格式化类的1个指定实例。

                moment: moment,

                //查询表单实例初始化。

                queryForm: {

                    name: '',

                    email: '',

                    phone: '',

                    isSystemAccount: '',

                    isActive: '',

                    deleted: '',

                    createdDateTimeFrom: '',

                    createdDateTimeTo: '',

                },

                queryRule: {

                    createdDateTimeFrom: [{

                        validator: validateDateTimeFrom,

                        trigger: "blur"

                    }],

                    createdDateTimeTo: [{

                        validator: validateDateTimeTo,

                        trigger: "blur"

                    }]

                },

                //分页表实例初始化。

                pagination: {

                    pageIndex: 1, //初始化当前页,即第1页。

                    pageSize: 15, //初始化每页最多所包含的项数值,即每页最多所包含15项。

                    totalCount: 0, //初始化数据源的总计项数值,由于还没有加载数据源所以该值为:0

                    //初始化排序字段及其方式。

                    OrderByModel: JSON.stringify({

                        OrderByFiled: 'createdDateTime',

                        OrderByType: 'descending',

                    }),

                    QueryCondition: ""

                },

                //初始化当前页的渲染数据集列表实例。

                currentPageList: [],

                //初始化图片的填充方式:按照长宽比填充整个图片(https://www.w3school.com.cn/css/css3_object-fit.asp)。

                fitCover: "cover",

                //当前页面中被选择选复选框中的值。

                selectIdArray: [],

                //编辑子页参数实例。

                formEidt: {

                    id: 0,

                    name: '',

                    email: '',

                    phone: '',

                    avatar: '',

                    isSystemAccount: false,

                    isActive: true,

                    deleted: false,

                    //该实例用于指示,当前页面角色编辑子页面是否在父窗口中显示出来。

                    centerDialogVisible: false,

                },

                //添加子页参数实例,由于添加子页,不需要获取监视父窗口传递的参数实例,所以可以只有“centerDialogVisible”

                formAdd: {

                    //该实例用于指示,当前页面角色编辑子页面是否在父窗口中显示出来。

                    centerDialogVisible: false,

                },

            };

        },

        methods: {

            //格式化日期显示。

            dateTimeformat: function(row, column) {

                let data = row[column.property];

                if (data == null) {

                    return null;

                }

                return moment(data).format('YYYY-MM-DD HH:mm:ss');

            },

            //获取当前页面渲染显示所需的数据源。

            async currentPageInit() {

                let res = await postCustomerIndex(this.pagination);

                //console.log(res.data.response.data);

                this.currentPageList = res.data.response.data;

                this.pagination.totalCount = res.data.response.totalCount;

            },

            //表单查询事件

            async onSubmit() {

                this.$refs.refRule.validate(async (valid) => {

                    if (valid) {

                        var where = {};

                        if (this.queryForm.name != '') {

                            where.name = this.queryForm.name;

                        }

                        if (this.queryForm.email != '') {

                            where.email = this.queryForm.email;

                        }

                        if (this.queryForm.phone != '') {

                            where.phone = this.queryForm.phone;

                        }

                        if (this.queryForm.isSystemAccount != '') {

                            where.isSystemAccount = this.queryForm.isSystemAccount;

                        }

                        if (this.queryForm.isActive != '') {

                            where.isActive = this.queryForm.isActive;

                        }

                        if (this.queryForm.deleted != '') {

                            where.deleted = this.queryForm.deleted;

                        }

                        if (this.queryForm.createdDateTimeFrom != '') {

                            where.createdDateTimeFrom = this.moment(this.queryForm.createdDateTimeFrom)

                                .format('YYYY-MM-DD HH:mm:ss');

                        }

                        if (this.queryForm.createdDateTimeTo != '') {

                            where.createdDateTimeTo = this.moment(this.queryForm.createdDateTimeTo).add(

                                1, 'days').format('YYYY-MM-DD HH:mm:ss');

                        }

                        //console.log(where);

                        this.pagination.QueryCondition = JSON.stringify(where);

                        //console.log(this.pagination.QueryCondition);

                        await this.currentPageInit();

                    } else {

                        this.$message.error('输入不能通过验证 !');

                        return false;

                    }

                });

            },

            //重置页面样式及其数据。

            async onResert() {

                //重置查询表单。

                this.queryForm = {

                    name: '',

                    email: '',

                    phone: '',

                    isSystemAccount: '',

                    isActive: '',

                    deleted: '',

                    createdDateTimeFrom: '',

                    createdDateTimeTo: '',

                };

                //重置排序字段试及其排序方式。

                this.pagination = {

                    pageIndex: 1,

                    pageSize: 15,

                    totalCount: 0,

                    OrderByModel: JSON.stringify({

                        OrderByFiled: 'createdDateTime',

                        OrderByType: 'descending',

                    }),

                    QueryCondition: ""

                };

                await this.$refs.refTable.sort(JSON.parse(this.pagination.OrderByModel).OrderByFiled,

                    JSON.parse(this.pagination.OrderByModel).OrderByType);

                await this.currentPageInit();

            },

            // 单击排序三角图标时所触发的事件。

            async handleTableSort({

                column

            }) {

                //防止排序方式的值为:null

                if (column.property == null && column.order == null) {

                    column.property = 'createdDateTime',

                        column.order = "descending";

                } else if (column.property != null && column.order == null) {

                    column.order = "ascending";

                }

                this.pagination.OrderByModel = JSON.stringify({

                    OrderByFiled: column.property,

                    OrderByType: column.order,

                });

                await this.currentPageInit();

            },

            //该事件在改变每页最多所包含的项数值后,把数据源加载到当前页面中,并重新对当前页进行渲染显示。

            async handleSizeChange(size) {

                this.pagination.pagesize = size;

                //console.log(this.pagesize); //每页最多所包含的项数值。

                await this.currentPageInit();

            },

            //该事件在改变当前页的索引值后,把数据源加载到当前页面中,并重新对当前页进行渲染显示。

            async handleCurrentChange(currentPage) {

                this.pagination.PageIndex = currentPage;

                //console.log(this.PageIndex); //当前页的索引值。

                await this.currentPageInit();

            },

            //1个指定用户的密码进行重置。

            async onResertPassword(row) {

                let res = await resertPassword({

                    customerId: row.id

                });

                console.log(res.data);

                if (res.status == 200) {

                    this.$message.success("成功密码重置");

                } else {

                    this.$message.error(res.msg);

                }

            },

            //从用户表中删除单行指定数据后,并重新渲染显示当前页面。

            async deleteSingle(row) {

                await this.$confirm(`确认删除记录:${row.id}!`, '提示', {

                        type: 'warning'

                    })

                    .then(async () => { // 确定操作

                        let para = {

                            customerId: row.id,

                        };

                        let res = await deleteCustomer(para);

                        console.log(res.data);

                    })

                    .catch(() => { // 取消操作

                        this.$message({

                            type: 'info',

                            message: '已取消退出'

                        });

                    });

                await this.currentPageInit();

            },

            //获取将要被删除的编号值集,编号之间用隔开。

            async selectionChange(selectIdArray) {

                this.selectIdArray = selectIdArray;

                //console.log("选中的值", selectIdArray.map((item) => item.id));

                //console.log("this.selectIdArray选中的值", this.selectIdArray);

            },

            //从用户表中删除多行指定数据后,并重新渲染显示当前页面。

            async deleteSelected() {

                let idArray = this.selectIdArray.map((item) => item.id);

                // 根据后台想要的参数格式选择

                //console.log(idArray.join(",")); //1,2,3,4

                //console.log(idArray); //[1,2,3,4]

               

                if (idArray.length <= 0) {

                    this.$message.error("请选择要删除的一行数据!");

                    return;

                }

                await this.$confirm(`确认删除记录:${idArray}!`, '提示', {

                        type: 'warning'

                    })

                    .then(async () => { // 确定操作

                        // 根据后台想要的参数格式选择

                        //console.log(this.selectIdArray.join(",")); //1,2,3,4

                        //console.log(this.selectIdArray); //[1,2,3,4]

                        await deleteSelectedCustomer({

                            selectIdArray: idArray.join(",")

                        });

                    })

                    .catch(() => { // 取消操作

                        this.$message({

                            type: 'info',

                            message: '已取消退出'

                        });

                    });

                await this.currentPageInit();

            },

            //编辑单击事件,为子编辑页面的渲染显示提供数据支撑。

            async editUser(row) {

                this.formEidt = Object.assign({}, row);

                this.formEidt.centerDialogVisible = true;

            },

            //子编辑页面提交成功时,自动刷新当前页。

            async editDialogClose() {

                await this.currentPageInit();

            },

            //添加单击事件,为子添加页面的渲染显示提供数据支撑。

            async addUser() {

                this.formAdd = Object.assign({}, {});

                this.formAdd.centerDialogVisible = true;

            },

            //子添加页面提交成功时,自动刷新当前页。

            async addDialogClose() {

                await this.onResert();

            },

        },

        async mounted() {

            await this.currentPageInit();

        },

    };

</script>

<style scoped lang="scss">

    .wrap {

        height: 100%;

        overflow-x: hidden;

    }

    //表单“label”字体样式

    :deep(.el-form-item__label) {

        font-weight: 400;

    }

    // 修改表头样式。

    :deep(.el-table__header thead th) {

        background-color: #000000;

        color: #ffd04b;

        font-weight: 400;

        text-align: center;

    }

    //修改复选框控件样式。

    :deep(.el-checkbox) {

        display: flex;

        align-items: center;

        width: 25px;

        height: 25px;

        //修改选中框的大小

        .el-checkbox__inner {

            width: 20px;

            height: 20px;

            border: #409EFF solid 2px;

            //修改选中框中的对勾的大小和位置

            &::after {

                // 对号

                border: 4px solid #FFFFFF;

                // 不覆盖下面的 导致对号变形

                box-sizing: content-box;

                content: "";

                border-left: 0;

                border-top: 0;

                height: 15px;

                position: absolute;

                top: -3px;

            }

        }

        //修改点击文字颜色不变

        .el-checkbox__input.is-checked+.el-checkbox__label {

            color: #333333;

        }

        .el-checkbox__label {

            line-height: 25px;

            //padding-left: 8px;

        }

    }

    //表格隔行变换颜色。

    :deep(.el-table__body tbody tr:nth-child(odd)) {

        background-color: #FFFFFF;

    }

    :deep(.el-table__body tbody tr:nth-child(even) td) {

        background-color: #CCFFFF;

    }

    .userinfo-inner {

        cursor: pointer;

        float: left;

    }

    //标签控件字体样式。

    .el-tag {

        font-weight: 400;

        padding: 5px 5px;

    }

    //按钮控件字体样式。

    .el-button {

        font-weight: 400;

        padding: 5px 5px;

    }

    //“el-pagination”分页组件样式。

    .el-pagination {

        margin-top: 10px;

        //font-size: 25px;

        //"上一页"样式。

        :deep(.btn-prev) {

            background-color: transparent;

            height: 40px;

            margin-right: 20px;

        }

        //"下一页"样式。

        :deep(.btn-next) {

            background-color: transparent;

            height: 40px;

            margin-left: 20px;

        }

        //分页索引样式。

        :deep(.number) {

            background-color: transparent;

            min-width: 40px;

            height: 40px;

            margin-right: 15px;

        }

    }

    //“el-pagination”分页组件中下拉框控件字体样式。

    :deep(.el-input__wrapper) {

        //font-size: 25px;

    }

    .lightgreen-box {

        //background-color: lightgreen;

        //height: 24px;

        float: right;

    }
</style>

 

 

对以上功能更为具体实现和注释见:230412_016shopvue(用户增、修、删的前端实现)。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/416183.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Python学习笔记--判断语句

&#xff08;一&#xff09; 布尔类型和比较运算符 1. 布尔类型&#xff1a;判断结果 True&#xff1a;表示真&#xff08;是、肯定&#xff09; False&#xff1a;表示假&#xff08;否、否定&#xff09; """ 演示布尔类型的定义 以及比较运算符的应用 "…

BCM系统组成及控制原理

1 输入控制 由于负载能力、抗干扰能力等客观情况。许多信号量无法直接施加至MCU之上&#xff0c;须有适当的输入电路(Input circuit)将信号进行隔离、调理&#xff0c;方可安全可靠地传递给MCU。 下面以开关信号和脉冲信号2种来分述。 1)开关信号的输入。 即将系统与电源正…

高频算法:Leetcode53 最大子数组和

今天讲的是Leetcode第53题&#xff0c;最大子数组和 首先观察题目&#xff0c;题目需要我们找出具有最大和的连续子数组&#xff0c;直接拿题目中的示例来做一个演示&#xff0c;找一找什么规律下的连续子数组才能得到最大的和 先从-2开始&#xff0c;-2 1 -1 此时我们的和…

【Python】Python读写.xlsx文件(基本操作、空值补全等)

【Python】Python读写.xlsx文件&#xff08;Pandas&#xff09; 文章目录【Python】Python读写.xlsx文件&#xff08;Pandas&#xff09;1. 介绍2. Pandas读写xlsx文件2.1 基本操作2.1.1 实现任务2.1.2 代码2.1.3 结果2.2 进阶操作2.2.1 写操作2.2.2 查看数据表的基本信息2.2.2…

集中一个主题,密集学习几个月,突飞猛进

集中一个主题&#xff0c;密集学习几个月大长进 诺贝尔奖获得者西蒙发现 密集学习了几个月品牌营销的知识 长进明显 原来是有科学规律的 趣讲大白话&#xff1a;大力出奇迹 【趣讲信息科技132期】 **************************** 西蒙学习法&#xff1a;“对于一个有一定基础的人…

KANO模型-产品需求调研利器

最近要做一个项目&#xff0c;需要调研客户的真实需求&#xff0c;我们有一些可提供的功能&#xff0c;需要通过问卷调研出客户对功能的优先级需求。但问卷调研的结果能反映客户的真实需求和痛点吗&#xff1f;如何给这些需求排优先级&#xff0c;以及所占的权重&#xff1f;如…

【python】只需一段代码,剪辑一个视频——Moviepy详解

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录前言一、准备二、视频剪辑三、视频拼接四、逐帧变化四、导出GIF总结前言 知道吗&#xff0c;用moviepy一行代码就能够快速剪辑视频中某个区间的片段&#xff1a; cl…

mac m1系统安装安卓手机模拟器

背景&#xff1a;本人是一名开发人员&#xff0c;本地小程序上的需要地图导航到手机上&#xff0c;所以找到一个mac&#xff08;m1&#xff09;安装安卓模拟器的方案&#xff0c;这里记录分享一下。 废话不多说直接上步骤&#xff0c;很详细跟着步骤走就能完成&#xff01;&am…

【MySQL】delete和truncate的用法和区别

一、delete和truncate的用法 有如下数据表t_student 关键字delete和truncate都用来清除表中数据&#xff0c;语法结构为&#xff1a; delete from t_student;truncate table t_student; 两条SQL操作后的结果一样&#xff1a;删除了表中数据&#xff0c;但是会保留表的结构&a…

OpenAI Embedding:快速实现聊天机器人(一)

theme: orange 本文正在参加「金石计划」 上文 OpenAI Embedding&#xff1a;基于人工智能的搜索新篇章 有讲到Embedding的基础概念以及OpenAI Embedding 的能力和应用场景&#xff0c;这篇文章讲讲如何手把手构建聊天机器人。 聊天机器人介绍 聊天机器人作为一项重要的企业级服…

Qt 数据库SQL

Qt 数据库SQL用户接口层SQL接口层驱动层创建连接数据库查询两个数据库示例用户接口层、SQL接口层和驱动层是数据库系统中的三个重要组成部分&#xff0c;它们分别负责不同的功能。 用户接口层 用户接口层 用户接口层是用户与数据库系统交互的界面。它提供了一些简单易用的工具…

HDSF 简介

目录 一、HDFS 的设计特点是 二、什么零拷贝 2.1 传统情况&#xff1a; 2.2 零拷贝技术&#xff1a; 三、什么是DMA 四、HDFS 的关键元素 五、HDFS 运行原理 六、HDFS 数据合并原理 七、HDFS 写的原理 八、HDFS 读的原理 九、分块存储 十、 安全模式 十一、 MapRedu…

如何使用微服务架构?使用过程需要注意什么?

一、使用微服务架构的规范 1.1 服务拆分 微服务的服务拆分是根据业务领域和业务功能来划分的&#xff0c;目的是将复杂的单体应用程序分解为小型、自治的服务&#xff0c;每个服务都专注于处理一个特定的业务领域或功能。 以下是微服务拆分的一些常见策略&#xff1a; 领域…

JavaEE——volatile、wait、notify三个关键字的解释

文章目录一、volatile和内存可见性1.解释内存可见性问题2. volatile 的使用与相关问题二、wait 和 notify1.wait 方法2.notify() 方法3. 关于 notifyAll() 方法4. wait 和 sleep 之间的简单比较一、volatile和内存可见性 前面的文章&#xff0c;我们已经提及到了内存可见性问题…

硬件设计--stm32自动下载电路设计

1 参考博客&#xff1a; 1、Stm32 一键下载电路详解 2、启动模式&#xff0c;BOOT0和BOOT1详解 3、STM32自动ISP电路设计 4、STM32 USB接口 一键下载电路详解与过程分析 2 下载软件分享&#xff1a; 参考博客&#xff1a;FlyMcu - 用于STM32芯片ISP串口程序一键下载的免费软…

【速记】Postgresql中几个ResourceOwner的含义

几个ResourceOwner的含义 总结下几个resowner的含义&#xff1a; 事务结构内的resowner&#xff1a;TransactionState→curTransactionOwner 含义&#xff1a;跟随事务结构体创建&#xff0c;会申请内存&#xff0c;跟随事务结构释放。每层事务都有自己的curTransactionOwner…

Vivado 下按键实验

Vivado下按键实验 实验原理 PL通过按键的开关状态控制led的亮灭&#xff0c;按键按下的时候灯亮&#xff0c;按键未按下的时候灯灭。 这里的描述有些问题&#xff0c;PL_LED1为高的时候&#xff0c;LED两端的电压都为高&#xff0c;灯应该是不亮的&#xff0c;所以按照下面实…

口令暴力破解--Ftp协议暴力破解与Ssh协议暴力破解

Ftp协议暴力破解 FTP服务检测 FTP服务 FTP是一种文件传输协议&#xff0c; FTP服务默认端口为21。利用FTP服务器可以在本地主机和远程主机间进行文件传输。当FTP没有配置好安全控制&#xff0c;如对登录的源地址及密码尝试次数做限制&#xff0c;那么就会存在暴力破解可能。…

uniapp - 实现车牌号键盘与格子间隔显示组件,汽车牌照录入支持自定义样式、新能源等(附带组件完整源码,开箱即用,稍微改改就能用)

效果图 uniapp 全平台兼容,车牌号键盘输入、分格显示功能示例源码,注释很多! 可以直接复制一下,然后自己改改样式或功能就能使了。 示例源码 复制,运行。 &

基于神经网络的协同过滤-NCF

目录 1、摘要 2、引言 2.1协同过滤 2.2矩阵分解 3.准备工作 3.1学习隐性数据 3.2矩阵分解 ​3.3神经协同过滤 3.4广义矩阵分解 3.5多层感知器 3.6GMF和MLP的融合-NeuMF(神经矩阵分解) 4.总结 1、摘要 尽管最近的一些工作已经把深度学习运用到了推荐中&#xff0…