<div class="box box-solid"> <div class="box-body"> @(Html.Kendo().Grid<CompanyServiceModel>() .Name("grid") .Columns(columns => { columns.Bound(c => c.ServiceName).Title("服务项目").HtmlAttributes(new { style = "white-space:nowrap;" }); columns.Bound(c => c.SuitableFor).Title("适用人群").HtmlAttributes(new { style = "white-space:nowrap;" }); columns.Bound(c => c.OriginPrice).Title("原价").HtmlAttributes(new { style = "white-space:nowrap;" }); columns.Bound(c => c.DiscountPrice).Title("折扣价").HtmlAttributes(new { style = "white-space:nowrap;" }); columns.Bound(c => c.policy).Title("优惠政策").HtmlAttributes(new { style = "white-space:nowrap;" }); columns.Bound(c => c.Id).Title("操做").Width(240) .ClientTemplate( @"<button class='k-button k-grid-delete' onclick='delService(" + "#:Id #" + ")'>删除</button>" + "<button class='k-button k-grid-delete' id='showDialogBtn2' data-role='button' role='button' aria-disabled='false' tabindex='0' onclick='editService("+"#:Id #"+")'>编辑服务</button>") ; }) .HtmlAttributes(new { style = "height:600px;" }) .Pageable(p => p.PageSizes(new int[] { 20, 30, 50, 100 }).Refresh(true).Messages(model => model.ItemsPerPage("条/页"))) .Scrollable() .Resizable(f => f.Columns(true)) .DataSource(dataSource => dataSource .Ajax() .PageSize(20) .Read(read => read.Action("GetCompanyServiceList2", "Company").Data("onDataBinding")) ) ) </div> </div>
$(function () { search(); }); var searchModel = { }; function onDataBinding() { return searchModel; } function search() { searchModel = { "CompanyId": $("#Id").val() } var grid = $("#grid").data("kendoGrid"); grid.dataSource.page(1); }
// GET: Company private ICompanyService CompanyService { get; set; } private ICompanyServiceService CompanyServiceService { get; set; } public CompanyController(ICompanyService companyService, ICompanyServiceService companyServiceService) { CompanyService = companyService; CompanyServiceService = companyServiceService; } /// <summary> /// 获取公司服务列表kendo ui 用的 /// </summary> /// <param name="request"></param> /// <returns></returns> public ActionResult GetCompanyServiceList2([DataSourceRequest]DataSourceRequest request, CompanyServiceSearchModel model) { SearchModel searchModel = new SearchModel() { PageNo = request.Page, PageSize = request.PageSize }; ; searchModel.Filters = model.ToFilters(); searchModel.Sorts = model.ToSorts(); ApiListResult<CompanyServiceModel> apiListResult = CompanyServiceService.Search(searchModel); return Json(apiListResult.ToDataSourceResult()); }
注意:返回的是:Json(apiListResult.ToDataSourceResult());javascript
<!--人事服务--> <div class="company-service" id="human-resource"> <div class="category-item"> <div class="catagory-name">人事服务</div> <div class="catagory-desc">(提供专业的人力资源,社保、公积金开户及管理代缴服务,人事外包服务,员工福利等)</div> </div> <div class="company-list" id="human-resource-companies"> </div> </div> <!--财务服务--> <div class="company-service" id="fiance-service"> <div class="category-item"> <div class="catagory-name">财务服务</div> <div class="catagory-desc">(提供全方位的、专业化的财税服务,解决企业财务、税务、工商、年检等各种“疑难杂症”,有效的帮助企业节省时间、经理和资金)</div> </div> <div class="company-list" id="fiance-service-companies"> </div> </div>
根据id 作html 的拼接css
<script type="text/javascript"> //服务商数据获取 $(function () { $.ajax({ type: "post", //提交方式 dataType: "json", //数据类型 //data: JSON.stringify(jsonIds),//{ItemType: $("#itemType").val().trim()}自定义数据参数,视状况添加 url: '/Company/GetList', //请求url async: false, contentType: "application/json", success: function (json_data) { json_data.forEach(function (item) { if (item['ServiceCategory'] == "人事服务") { $("#human-resource-companies").append( '<a href="/company/detail/' + item['Id'] +'" data-toggle="modal" data-target="#modal" >' +'<div class="card-item-outer ">' + '<div class="card-item">' + '<div class="card-img">' + '<img src="' + item['ImageUrl'] + '" alt="' + item['CompanyName'] + 'image">' + '</div >' + '<div class="card-content">' + '<span class="card-company-name">' + item['CompanyName'] + '</span>' + '<ul class="service-info" id ="CompanyId' + item['Id']+'">' + '</ul>' + '</div>' + '</div>' + '</div>' +'</a>'); getCompanyService(item['Id']); } else (item['ServiceCategory'] == "财务服务") { $("#fiance-service-companies").append( '<a href="/company/detail/' + item['Id'] + '" data-toggle="modal" data-target="#modal" >' + '<div class="card-item-outer ">' + '<div class="card-item">' + '<div class="card-img">' + '<img src="' + item['ImageUrl'] + '" alt="' + item['CompanyName'] + 'image">' + '</div >' + '<div class="card-content">' + '<span class="card-company-name">' + item['CompanyName'] + '</span>' + '<ul class="service-info" id ="CompanyId' + item['Id'] + '">' + '</ul>' + '</div>' + '</div>' + '</div>' + '</a>'); getCompanyService(item['Id']); } }); }, error: function (XMLHttpRequest, textStatus, errorThrown) { alert(XMLHttpRequest.responseText); } }) }) //服务项目数据获取 function getCompanyService(id) { var jsonCompanyId = eval('(' + '{"CompanyId":"' + id+ '"}' + ')'); $.ajax({ type: "post", //提交方式 dataType: "json", //数据类型 //data: JSON.stringify(jsonIds),//{ItemType: $("#itemType").val().trim()}自定义数据参数,视状况添加 url: '/Company/GetCompanyServiceList', //请求url async: false, contentType: "application/json", data: JSON.stringify(jsonCompanyId), success: function (json_data) { json_data.forEach(function (item) { $("#CompanyId" + id).after( '<li style="font-size: 12px;color: rgba(0, 0, 0, 0.43); list-style: none;">' + item['ServiceName'] + '</li>' ); }); }, error: function (XMLHttpRequest, textStatus, errorThrown) { alert(XMLHttpRequest.responseText); } }); } </script>
这里作了两次ajax 获取数据,一个是Company ,一个是CompanyServicehtml
public class CompanyController : Controller { // GET: Company private ICompanyService CompanyService { get; set; } private ICompanyServiceService CompanyServiceService { get; set; } public CompanyController(ICompanyService companyService, ICompanyServiceService companyServiceService) { CompanyService = companyService; CompanyServiceService = companyServiceService; } #region 公司列表 [CustomAuthorize("CompanyPage")] public ActionResult Index() { return View(); } /// <summary> /// 获取列表 /// </summary> /// <param name="request"></param> /// <returns></returns> public ActionResult GetList([DataSourceRequest]DataSourceRequest request, CompanySearchModel model) { SearchModel searchModel = new SearchModel(); searchModel.Filters = model.ToFilters(); searchModel.Sorts = model.ToSorts(); ApiListResult<CompanyModel> apiListResult = CompanyService.Search(searchModel); return Json(apiListResult.Result); } /// <summary> /// 获取公司服务列表ajax 用的 /// </summary> /// <param name="request"></param> /// <returns></returns> public ActionResult GetCompanyServiceList([DataSourceRequest]DataSourceRequest request, CompanyServiceSearchModel model) { SearchModel searchModel = new SearchModel(); searchModel.Filters = model.ToFilters(); searchModel.Sorts = model.ToSorts(); ApiListResult<CompanyServiceModel> apiListResult = CompanyServiceService.Search(searchModel); return Json(apiListResult.Result); } }
传出来的是model 或者model list ,相似c#同样遍历数据前端
@model CompanyModel @{ Layout = null; ViewBag.Title = "服务商详情"; } <div class="company-body" id="company-body" style="padding: 10px; background-color:#ecf0f5;" > <div class="company-body-loading" style="position: relative;"> <!--第一个卡板--> <div class="company-base-card"> <div class="company-card-title"> 服务商信息 <hr style="margin-top: 5px;"/> </div> <div class="company-detail-info"> <div class="company-detail-left-info"> <div class="name"> @Model.CompanyName <span class="text-primary"> (@Model.ServiceCategory) </span> </div> <div class="desc"> @Model.Introduction </div> </div> <input type="text" id="ModelId" value="@Model.Id" style="display:none"/> <input type="text" id="CompanyName" value="@Model.CompanyName" style="display:none"/> <div class="company-detail-right-logo"> <div class="card-img" id="image" > <img id="Image" src="@Model.ImageUrl"/> </div> </div> </div> </div> <!--第二个卡板--> <div class="company-base-card"> <div class="company-card-title"> 申请及咨询方式 <hr style="margin-top: 5px;" /> </div> <div class="company-detail-info"> <div class="contact-mode"> <div class="mode-item"> <div class="left-lable">咨询电话:</div> @if (Model.Tel.Length > 0) { <div class="flex-item">@Model.Tel</div> } else { <div class="flex-item">-</div> } </div> <div class="mode-item"> <div class="left-lable">官网:</div> @if (!string.IsNullOrEmpty(@Model.Website)) { <div class="flex-item">@Model.Website</div> } else { <div class="flex-item">-</div> } </div> <div class="mode-item"> <div class="left-lable">邮箱:</div> @if (!string.IsNullOrEmpty(@Model.Email)) { <div class="flex-item">@Model.Email</div> } else { <div class="flex-item">-</div> } </div> </div> </div> </div> <!--第三个卡板--> <div class="company-base-card"> <div class="company-card-title"> 服务项目 <hr style="margin-top: 5px;" /> </div> <div class="company-detail-info"> <div class="service-list"> @foreach (var x in Model.CompanyServices) { <div class="service-item"> <div class="service-item-left"> <div class="name">@x.ServiceName</div> <div class="mode-item"> <div class="left-lable">使用人群:</div> <div class="flex-item">@x.SuitableFor</div> </div> <div class="mode-item"> <div class="left-lable" style="color: #f8ab3c;">优惠政策:</div> <div class="flex-item" style="color: #f8ab3c;">@x.policy</div> </div> </div> <div class="service-item-right"> @if (!string.IsNullOrWhiteSpace(x.OriginPrice) && !string.IsNullOrWhiteSpace(x.DiscountPrice)) { <div class="text-danger" style="color: #f04134;">@x.DiscountPrice</div> <div class="original-price" style="text-decoration: line-through;">@x.OriginPrice</div> } else if (!string.IsNullOrWhiteSpace(x.OriginPrice) && string.IsNullOrWhiteSpace(x.DiscountPrice)) { <div>-</div> <div class="original-price">@x.OriginPrice</div> } else if (string.IsNullOrWhiteSpace(x.OriginPrice) && !string.IsNullOrWhiteSpace(x.DiscountPrice)) { <div class="text-danger" style="color: #f04134;">@x.DiscountPrice</div> <div class="original-price">-</div> } else { <div>-</div> <div>-</div> } </div> </div> } </div> </div> </div> </div> </div>
#region 详情页 [HttpGet] public ActionResult Detail(int id) { CompanyModel viewModel = CompanyService.GetById(id).Result; return View(viewModel); } #endregion
<button class='k-button k-grid-delete' id='showDialogBtn2' data-role='button' role='button' aria-disabled='false' tabindex='0' onclick='editService("1")'>编辑服务</button> <!--编辑弹窗--> <div class="box box-solid" id="example2" style="display:none;"> </div>
1. editService("1") js 方法,并传入一个参数 ,原来的方法是有kendo ui 的动态数据onclick='editService("+"#:Id #"+")' java
2. id='showDialogBtn2' 这个id 能够随意设置jquery
3.弹窗的内容会设置在 id=“example2” 的div 中间web
function editService(id) { $("#example2").kendoWindow({ title: "服务项目", width: 500, content: "/Company/EditService/" + id, actions: [ "Close" ], modal: true });
/// <summary> /// 弹窗修改服务项目 /// </summary> /// <param name="id"></param> /// <returns></returns> public ActionResult EditService(int id) { CompanyServiceModel companyServiceModel = CompanyServiceService.GetById(id).Result; ; return View(companyServiceModel); }
跳转页面,并传一个model 的方法ajax
另一个html 内容根据实际自行编辑数据库
<style> /*左边或者右边弹出框 的css 样式*/ .mybtn { position: fixed; right: 10px; bottom: 20px; display: block; width: 50px; height: 50px; border-radius: 50px; padding: 0px; text-align: center; line-height: 50px; } .modal.left .modal-dialog, .modal.right .modal-dialog { top: 140px; bottom: 0px; width: 770px; position: fixed; margin: auto; height: 100%; -webkit-transform: translate3d(0%, 0, 0); -ms-transform: translate3d(0%, 0, 0); -o-transform: translate3d(0%, 0, 0); transform: translate3d(0%, 0, 0); box-shadow: 0 7px 21px rgba(0,0,0,.3); } .modal.left .modal-content, .modal.right .modal-content { height: 100%; overflow-y: auto; } .modal.left .modal-body, .modal.right .modal-body { padding: 15px 15px 80px; } /*Left*/ .modal.left.fade .modal-dialog { left: -320px; -webkit-transition: opacity 0.3s linear, left 0.3s ease-out; -moz-transition: opacity 0.3s linear, left 0.3s ease-out; -o-transition: opacity 0.3s linear, left 0.3s ease-out; transition: opacity 0.3s linear, left 0.3s ease-out; } .modal.left.fade.in .modal-dialog { left: 0; } /*Right*/ .modal.right.fade .modal-dialog { right: -320px; -webkit-transition: opacity 0.3s linear, right 0.3s ease-out; -moz-transition: opacity 0.3s linear, right 0.3s ease-out; -o-transition: opacity 0.3s linear, right 0.3s ease-out; transition: opacity 0.3s linear, right 0.3s ease-out; } .modal.right.fade.in .modal-dialog { right: 0; } /* ----- 右边弹窗背景不是灰色 ----- */ #modal .modal-dialog.modal-content { border-radius: 0; border: none; } #modal .modal-dialog.modal-content.modal-header { border-bottom-color: #EEEEEE; background-color: #FAFAFA; } #modal .modal-backdrop { opacity: 0 !important; filter: alpha(opacity=0) !important; } /* ----- 右边弹窗背景不是灰色 ----- */ </style> <!--弹窗到其余网页的a标签--> <a href="/company/detail/1" data-toggle="modal" data-target="#modal" >弹窗</a> <!--右边Detail弹窗--> <div class="modal right fade" id="modal" tabindex="-1" role="dialog" aria-labelledby="modal" style="background-color: rgba(0, 0, 0, 0);"> <div class="modal-dialog" role="document" > <div class="modal-content"> <!--Detail/id 内容加载在这里面--> </div> </div> </div> <!--右边Detail弹窗-->
并须要在header 里面引入对应的bootstrap 模态框的css js json
<link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css"> <script src="https://cdn.bootcss.com/jquery/2.1.1/jquery.min.js"></script> <script src="https://cdn.bootcss.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
JS 代码
<!--清除弹窗数据--> $("#modal").on("hidden.bs.modal", function () { $(this).removeData("bs.modal"); });
bootstrap 的弹窗数据不会再关闭弹窗后消失,因此须要添加清空数据的js
Controller 代码
#region 详情页 [HttpGet] public ActionResult Detail(int id) { CompanyModel viewModel = CompanyService.GetById(id).Result; return View(viewModel); } #endregion
<div class="company-close" style="width: 18px; height: 18px; border-radius: 18px;display: inline-block;box-sizing: border-box;" aria-label="Close" data-dismiss="modal" > <i class="k-icon k-i-logout"></i> </div>
这个是关闭弹窗的功能键
引入jquery 和 ajasfileupload 的js
<script src="@Url.Content("~/Scripts/kendo/2017.3.1026/jquery.min.js")"></script> <script src="~/Scripts/ajaxfileupload.js"></script>
页面的图片输入框和显示框
<style> #oDiv { height: 129px; width: 329px; border: 1px solid #000; text-align: center; margin-bottom: 10px; } </style> <div class="col-sm-8"> <div class="all"> <div id="oDiv"> <img src="~/Content/images/companies/1.jpg" id="showPic" style="height:100%;width:100%" /> </div> <input type="file" id="oInput" name="file" onchange="upload_cover(this)" placeholder="上传图片"/> <input type="text" id="ImageUrl" name="ImageUrl" placeholder="上传图片后显示实际路径" value="~/Content/images/companies/1.jpg" style="display:none" /> </div> </div>
function upload_cover(obj) { //回传后缀 var filePath = $("input[name='file']").val(); var extStart = filePath.lastIndexOf("."); var ext = filePath.substring(extStart, filePath.length).toUpperCase(); ajax_upload(obj.id, function (data) { //function(data)是上传图片的成功后的回调方法 var isrc = data.relatPath.replace(/\/\//g, '/'); //获取的图片的绝对路径 $('#image').attr('src', basePath + isrc).data('img-src', isrc); //给<input>的src赋值去显示图片 }, ext); } //具体的上传图片方法 function ajax_upload(feid, callback, ext) { if (image_check(feid)) { $.ajaxFileUpload({ url: "/Company/UploadImage", secureuri: false, fileElementId: feid, dataType: 'json', data: {fileType: ext},//增长推送的属性 type: 'post', async: true, secureuri: false, success: function (data) { alert(data.imagePath); $("#ImageUrl").val(data.imagePath); $("#showPic").attr("src", data.imagePath); }, error: function (data) { alert(data); } }); } }; function image_check(feid) { //本身添加的文件后缀名的验证 var img = document.getElementById(feid); return /.(jpg|png|gif|bmp)$/.test(img.value) ? true : (function () { modals.info('图片格式仅支持jpg、png、gif、bmp格式,且区分大小写。'); return false; })(); }
#region 图片上传 /// <summary> /// 图片上传控件 /// </summary> /// <param name="fileNames"></param> /// <returns></returns> [HttpPost] public ActionResult UploadImage(HttpPostedFileBase file) { //获取图片后缀 string fileType = Request.Form["fileType"]; // 时间 string now = DateTime.Now.ToString("yyyyMMddHHmmssffff"); //文件存放的文件路径 string folder = HttpContext.Server.MapPath("/Content/images/companies/"); // 保存文件 string filePath = Path.Combine(folder, now + fileType); file.SaveAs(filePath); //切出相对路径 string subFilePath = filePath.Substring(filePath.LastIndexOf("\\Content")); JsonResult json = new JsonResult(); json.ContentType = "text/html"; json.Data = new { imagePath = subFilePath, success = true }; return json; //return Content(filePath); } #endregion
须要注意:
前端录入文件的input 的 name=”file“ ,必定要和 controller 里面的接收的参数 HttpPostedFileBase file 后面的file 名字是同样的
框架里面的读写分离,数据层的 entity 是和数据交接的类,服务层 viewmodel 是前端显示的动态数据,当前端post 一个viewmodel 到服务层的额时候,适用auto mapping 就不须要一个个属性作对接,viewmodel=》entity 的属性对接
例如Create
public virtual ApiResult<TViewModel> Create<TViewModel>(TViewModel model, Action<TEntity> action) { TEntity entity = Mapper.Map<TEntity>(model); action(entity); _context.Set<TEntity>().Add(entity); bool isSaved = false; try { isSaved = _context.SaveChanges() > 0; } catch (DbEntityValidationException exception) { var errorMessages = exception.EntityValidationErrors .SelectMany(validationResult => validationResult.ValidationErrors) .Select(m => m.ErrorMessage); var fullErrorMessage = string.Join(", ", errorMessages); //记录日志 //Log.Error(fullErrorMessage); var exceptionMessage = string.Concat(exception.Message, " 验证异常消息是:", fullErrorMessage); throw new DbEntityValidationException(exceptionMessage, exception.EntityValidationErrors); } if (!isSaved) { return ApiResult<TViewModel>.Error("新增记录失败!"); } var result = _context.Set<TEntity>().ProjectToFirst<TEntity, TViewModel>(p => p.Id.Equals(entity.Id)); return new ApiResult<TViewModel>() { Result = result }; }
保存的时候只须要
TEntity entity = Mapper.Map<TEntity>(model);
就能够经过字段名和属性一一匹配,不须要写匹配,只须要写一个格式转换的profile
using AutoMapper; using SP.Data; using SP.Models.ViewModels; using SP.WorkerLoan2.Models.Response; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace SP.Services.Impl.Extensions.Profiles { public class CompanyProfile : Profile { public CompanyProfile() { CreateMap<CompanyResponse, CompanyModel>(); CreateMap<SP.Data.Company, CompanyModel>(); CreateMap<CompanyModel, SP.Data.Company>() .ForMember(p => p.CreatedTime, opt => opt.Ignore()) .ForMember(p => p.CreatedBy, opt => opt.Ignore()); } } }
其中。Ignore 的属性是表示entity属性值不会匹配viewmodel的,这样,就能够对于部分字段作逻辑更新;
在调用 Create<TViewModel>(TViewModel model, Action<TEntity> action)
/// <summary> /// 新增 /// </summary> /// <param name="model"></param> /// <returns></returns> public override ApiResult<CompanyModel> Create(CompanyModel model) { return Create<CompanyModel>(model, entity => { entity.IsDeleted = false; entity.CreatedTime = DateTime.Now; entity.CreatedBy = model.CreatedBy; entity.UpdatedTime = DateTime.Now; entity.UpdatedBy = model.UpdatedBy; }); }
手动上部分须要匹配的内容便可。
建立枚举值的类
using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.Linq; using System.Text; using System.Threading.Tasks; namespace SP.Infrastructure.Enums { /// <summary> /// 客户类型枚举 /// </summary> public enum CustomerType { /// <summary> /// 意向客户 /// </summary> [Display(Name = "意向客户")] Intention = 1, /// <summary> /// 成交客户 /// </summary> [Display(Name = "成交客户")] Deal = 2, /// <summary> /// 流失客户 /// </summary> [Display(Name = "流失客户")] Loss = 3 } }
其中, Intention = 1, 左边是model 或者entity 的 CustomerType 的值,右边 1 是数据库保存的值
public class Customer : BaseEntity { /// <summary> /// 客户类型 /// </summary> public CustomerType CustomerType { get; set; } }
建立类的时候,using 枚举值的类就能够直接使用
前端显示和更改的时候
<div class="form-group"> @Html.Label("CustomerType", "客户类型:", new { @class = "col-sm-2 control-label" }) <div class="col-sm-8"> @(Html.Kendo().DropDownList().Name("CustomerType") .BindTo(new List<SelectListItem>() { new SelectListItem(){Text="意向客户",Value="Intention"}, new SelectListItem(){Text="成交客户",Value="Deal"}, new SelectListItem(){Text="流失客户",Value="Loss"} }).Value(Model.CustomerType.ToString()) .HtmlAttributes(new { placeholder = "请选择客户类型", style = "width:100%;", type = "text" })) </div> </div>
注意:
一、Value 为 model 的值,Text 是 前端显示选择的值,
二、Model.CustomerType.ToString() 显示数据的是须要ToString显示,若是字段类型不是枚举值就就直接显示Model.CustomerType 便可
如 : company 里面有多个 companyservice ,companyservice 里面只有一个company ,并经过外键companyId 关联
Company
namespace SP.Data { /// <summary> /// 服务市场的公司 /// </summary> public class Company : BaseEntity { /// <summary> /// 公司名字 /// </summary> public string CompanyName { get; set; } /// <summary> /// 公司服务 /// </summary> public virtual List<CompanyService> CompanyServices { get; set; } } }
CompanyService
namespace SP.Data { public class CompanyService : BaseEntity { /// <summary> /// 服务项目 /// </summary> public int? CompanyId { get; set; } /// <summary> /// 服务项目 /// </summary> public string ServiceName { get; set; } /// <summary> /// 所属公司 /// </summary> public virtual Company Company { get; set; } } }
在作mapping的时候
CompanyMap 只须要写本身那部分的内容
而CompanyServiceMap
namespace SP.Data.Mapping { public class CompanyServiceMap : BaseEntityTypeConfiguration<CompanyService> { public CompanyServiceMap() { this.ToTable("CompanyService"); this.HasKey(p => p.Id); this.Property(p => p.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity); this.Property(p => p.ServiceName).HasMaxLength(500); this.HasRequired(p => p.Company); } } }
系统会自动识别出CompanyId 为外键,
若是另外在CompanyServiceMap 里面,设置手工写一个外键上去,系统会也会自动帮你建立一个,数据库的company_id 的字段,致使一共有两个 同样的字段两个外键