| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210 |
- <template>
- <div class="app-container">
- <!-- 页面头部 -->
- <div class="detail-header">
- <el-icon class="back-icon" @click="goBack"><ArrowLeft /></el-icon>
- <span class="header-title">查看供应商</span>
- </div>
- <!-- 标签页 -->
- <el-tabs v-model="activeTab" class="detail-tabs">
- <!-- 基本信息 -->
- <el-tab-pane label="基本信息" name="basic">
- <BasicInfoTab
- v-model:selectedOfficeRegion="selectedOfficeRegion"
- :detailData="detailData"
- :companyOptions="companyOptions"
- :enterpriseScaleOptions="enterpriseScaleOptions"
- :industryCategoryOptions="industryCategoryOptions"
- :supplierLevelOptions="supplierLevelOptions"
- :supplierTypeOptions="supplierTypeOptions"
- :isAddMode="isAddMode"
- :isViewMode="isViewMode"
- :isBasicInfoSaved="isBasicInfoSaved"
- :businessInfo="businessInfo"
- :businessInfoLoading="businessInfoLoading"
- :regionOptions="regionOptions"
- :paymentInfoList="paymentInfoList"
- :formatDate="formatDate"
- @save="handleSave"
- @getBusinessInfo="handleGetBusinessInfo"
- @officeRegionChange="handleOfficeRegionChange"
- @addPayment="handleAddPayment"
- @viewPayment="handleViewPayment"
- @editPayment="handleEditPayment"
- />
- </el-tab-pane>
- <!-- 采购信息 -->
- <el-tab-pane label="采销信息" name="purchase" :disabled="isAddMode && !isBasicInfoSaved">
- <PurchaseInfoTab
- v-model:selectedProductManager="selectedProductManager"
- v-model:selectedBuyer="selectedBuyer"
- :staffOptions="staffOptions"
- :isViewMode="isViewMode"
- @save="handleSavePurchaseInfo"
- />
- </el-tab-pane>
- <!-- 联系人 -->
- <el-tab-pane label="联系人" name="contact" :disabled="isAddMode && !isBasicInfoSaved">
- <ContactTab
- :contactSearchParams="contactSearchParams"
- :contactList="contactList"
- :contactLoading="contactLoading"
- :isViewMode="isViewMode"
- @search="handleContactSearch"
- @reset="handleContactReset"
- @add="handleAddContact"
- @view="handleViewContact"
- @edit="handleEditContact"
- />
- </el-tab-pane>
- <!-- 供应信息 -->
- <el-tab-pane label="供应信息" name="supply" :disabled="isAddMode && !isBasicInfoSaved">
- <SupplyInfoTab
- v-model:selectedCategories="selectedCategories"
- :isViewMode="isViewMode"
- :productCategoryList="productCategoryList"
- :selectedBrands="selectedBrands"
- :supplyAreaList="supplyAreaList"
- :authorizationList="authorizationList"
- :authorizationPagination="authorizationPagination"
- :formatDate="formatDate"
- :getAuthorizedStatusText="getAuthorizedStatusText"
- @saveCategories="handleSaveCategories"
- @addBrand="handleAddBrand"
- @removeBrand="handleRemoveBrand"
- @editSupplyArea="handleEditSupplyArea"
- @authorizationPagination="getAuthorizationList"
- />
- </el-tab-pane>
- <!-- 地址管理 -->
- <el-tab-pane label="地址管理" name="address" :disabled="isAddMode && !isBasicInfoSaved">
- <AddressTab
- :addressList="addressList"
- :isViewMode="isViewMode"
- @add="handleAddAddress"
- @edit="handleEditAddress"
- @delete="handleDeleteAddress"
- />
- </el-tab-pane>
- <!-- 合同管理 -->
- <el-tab-pane label="合同管理" name="contract" :disabled="isAddMode && !isBasicInfoSaved">
- <ContractTab
- :contractSearchParams="contractSearchParams"
- :contractList="contractList"
- :contractPagination="contractPagination"
- :isViewMode="isViewMode"
- :contract-type-dict="contractTypeDict"
- :contract-status-dict="contractStatusDict"
- :formatDate="formatDate"
- :getContractTypeText="getContractTypeText"
- :getContractStatusText="getContractStatusText"
- @search="handleContractSearch"
- @reset="handleContractReset"
- @add="handleAddContract"
- @viewAttachment="handleViewAttachment"
- @view="handleViewContract"
- @edit="handleEditContract"
- @sizeChange="handleContractSizeChange"
- @currentChange="handleContractCurrentChange"
- />
- </el-tab-pane>
- </el-tabs>
- <!-- 付款信息对话框 -->
- <el-dialog
- v-model="paymentDialogVisible"
- :title="paymentDialogTitle"
- width="1000px"
- :close-on-click-modal="false"
- >
- <el-form
- ref="paymentFormRef"
- :model="paymentForm"
- :rules="paymentFormRules"
- label-width="140px"
- :disabled="paymentDialogReadonly"
- >
- <el-form-item label="开票类型:" prop="invoiceTypeNo">
- <el-select
- v-model="paymentForm.invoiceTypeNo"
- placeholder="请选择"
- style="width: 100%;"
- @change="handleInvoiceTypeChange"
- >
- <el-option
- v-for="item in invoiceTypeList"
- :key="item.id"
- :label="item.invoiceTypeName"
- :value="item.id"
- />
- </el-select>
- </el-form-item>
- <el-form-item label="发票抬头:" prop="businessName">
- <el-input v-model="paymentForm.businessName" placeholder="企业工商名称" disabled/>
- </el-form-item>
- <el-form-item label="纳税人识别号:" prop="circlesName">
- <el-input v-model="paymentForm.circlesName" placeholder="请输入纳税人识别号" disabled/>
- </el-form-item>
- <el-form-item label="开户行行号:" prop="bankNum">
- <el-input v-model="paymentForm.bankNum" placeholder="请输入开户行行号" />
- </el-form-item>
- <el-form-item label="开户行名称:" prop="bankInfoNo">
- <el-select
- v-model="paymentForm.bankInfoNo"
- placeholder="请选择"
- style="width: 100%;"
- @change="handleBankChange"
- >
- <el-option
- v-for="item in systemBankList"
- :key="item.id"
- :label="item.bnName"
- :value="item.id"
- />
- </el-select>
- </el-form-item>
- <el-form-item label="银行账户:" prop="bankNo">
- <el-input v-model="paymentForm.bankNo" placeholder="请输入银行账户" />
- </el-form-item>
- <el-form-item label="固定电话:" prop="phone">
- <el-input v-model="paymentForm.phone" placeholder="请输入固定电话" />
- </el-form-item>
- <el-form-item label="地址:" prop="businessAddress">
- <el-input v-model="paymentForm.businessAddress" placeholder="工商地址" disabled />
- </el-form-item>
- <el-form-item label="是否主账号:" prop="num">
- <el-radio-group v-model="paymentForm.num">
- <el-radio :label="1">是</el-radio>
- <el-radio :label="0">否</el-radio>
- </el-radio-group>
- </el-form-item>
- </el-form>
- <template #footer>
- <div class="dialog-footer">
- <el-button @click="paymentDialogVisible = false">取消</el-button>
- <el-button v-if="!paymentDialogReadonly" type="primary" @click="handlePaymentSubmit" :loading="paymentSubmitLoading">确定</el-button>
- </div>
- </template>
- </el-dialog>
- <!-- 联系人对话框 -->
- <el-dialog
- v-model="contactDialogVisible"
- :title="contactDialogTitle"
- width="900px"
- :close-on-click-modal="false"
- >
- <el-form
- ref="contactFormRef"
- :model="contactForm"
- :rules="contactFormRules"
- label-width="140px"
- :disabled="contactDialogReadonly"
- >
- <el-row :gutter="20">
- <el-col :span="12">
- <el-form-item label="员工姓名:" prop="userName">
- <el-input v-model="contactForm.userName" placeholder="请输入员工姓名" />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="手机号:" prop="phone">
- <el-input
- v-model="contactForm.phone"
- placeholder="请输入手机号"
- maxlength="11"
- @input="onContactPhoneInput"
- />
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="20">
- <el-col :span="12">
- <el-form-item label="部门:" prop="departmentNo">
- <el-input v-model="contactForm.departmentNo" placeholder="请输入部门" />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="职位:" prop="position">
- <el-input v-model="contactForm.position" placeholder="请输入职位" />
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="20">
- <el-col :span="12">
- <el-form-item label="角色:" prop="roleNo">
- <el-input v-model="contactForm.roleNo" placeholder="请输入角色" />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="邮箱:" prop="email">
- <el-input v-model="contactForm.email" placeholder="请输入邮箱" />
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="20">
- <el-col :span="12">
- <el-form-item label="主要联系人:" prop="isPrimaryContact">
- <el-select v-model="contactForm.isPrimaryContact" placeholder="请选择" style="width: 100%;">
- <el-option label="是" value="1" />
- <el-option label="否" value="0" />
- </el-select>
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="允许登录供应商端:" prop="isRegister">
- <el-select v-model="contactForm.isRegister" placeholder="请选择" style="width: 100%;">
- <el-option label="是" value="1" />
- <el-option label="否" value="0" />
- </el-select>
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="20">
- <el-col :span="12">
- <el-form-item label="传真:" prop="fax">
- <el-input v-model="contactForm.fax" placeholder="请输入传真" />
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="20">
- <el-col :span="24">
- <el-form-item label="备注:" prop="remark">
- <el-input
- v-model="contactForm.remark"
- type="textarea"
- :rows="3"
- placeholder="请输入备注"
- />
- </el-form-item>
- </el-col>
- </el-row>
- </el-form>
- <template #footer>
- <div class="dialog-footer">
- <el-button @click="contactDialogVisible = false">取消</el-button>
- <el-button v-if="!contactDialogReadonly" type="primary" @click="handleContactSubmit" :loading="contactSubmitLoading">确定</el-button>
- </div>
- </template>
- </el-dialog>
- <!-- 供货区域编辑对话框 -->
- <el-dialog
- v-model="supplyAreaDialogVisible"
- title="编辑供货区域"
- width="700px"
- :close-on-click-modal="false"
- >
- <RegionCascader v-model="selectedSupplyAreaCodes" :multiple="true" :options="supplyAreaOptions" :show-district="false" />
- <template #footer>
- <div class="dialog-footer">
- <el-button @click="supplyAreaDialogVisible = false">取消</el-button>
- <el-button type="primary" @click="handleSupplyAreaSubmit" :loading="supplyAreaSubmitLoading">确定</el-button>
- </div>
- </template>
- </el-dialog>
- <!-- 地址管理对话框 -->
- <el-dialog
- v-model="addressDialogVisible"
- :title="addressDialogTitle"
- width="650px"
- :close-on-click-modal="false"
- >
- <el-form
- ref="addressFormRef"
- :model="addressForm"
- :rules="addressFormRules"
- label-width="120px"
- :disabled="addressDialogReadonly"
- >
- <el-row :gutter="20">
- <el-col :span="12">
- <el-form-item label="供应商编号:">
- <el-input v-model="addressForm.supplierNo" disabled />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="收货人:" prop="shipperName" required>
- <el-input v-model="addressForm.shipperName" placeholder="请输入收货人" />
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="20">
- <el-col :span="12">
- <el-form-item label="手机号码:" prop="shipperPhone" required>
- <el-input v-model="addressForm.shipperPhone" placeholder="请输入手机号码" />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="邮政编码:" prop="shippingPostCode">
- <el-input v-model="addressForm.shippingPostCode" placeholder="请输入邮政编码" />
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="20">
- <el-col :span="24">
- <el-form-item label="地址:" prop="shippingProvincial" required>
- <el-cascader
- v-model="selectedAddressRegion"
- :options="regionOptions"
- placeholder="请选择"
- clearable
- filterable
- style="width: 100%;"
- @change="handleAddressRegionChange"
- />
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="20">
- <el-col :span="24">
- <el-form-item label="详细地址:" prop="shippingAddress" required>
- <el-input
- v-model="addressForm.shippingAddress"
- type="textarea"
- :rows="3"
- placeholder="请输入详细地址"
- />
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="20">
- <el-col :span="12">
- <el-form-item label="默认地址:">
- <el-switch v-model="addressForm.isSelf" :active-value="1" :inactive-value="0" />
- </el-form-item>
- </el-col>
- </el-row>
- </el-form>
- <template #footer>
- <div class="dialog-footer">
- <el-button @click="addressDialogVisible = false">取消</el-button>
- <el-button v-if="!addressDialogReadonly" type="primary" @click="handleAddressSubmit" :loading="addressSubmitLoading">确定</el-button>
- </div>
- </template>
- </el-dialog>
- <!-- 合同管理对话框 -->
- <el-dialog
- v-model="contractDialogVisible"
- :title="contractDialogTitle"
- width="900px"
- :close-on-click-modal="false"
- >
- <el-form
- ref="contractFormRef"
- :model="contractForm"
- :rules="contractFormRules"
- label-width="140px"
- :disabled="contractDialogReadonly"
- >
- <el-row :gutter="20">
- <el-col :span="24">
- <el-form-item label="合同名称:" prop="contractName">
- <el-input v-model="contractForm.contractName" placeholder="请输入合同名称" />
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="20">
- <el-col :span="12">
- <el-form-item label="合同类型:" prop="contractType">
- <el-select v-model="contractForm.contractType" placeholder="请选择" style="width: 100%;">
- <el-option
- v-for="item in contractTypeDict"
- :key="item.dictValue"
- :label="item.dictLabel"
- :value="item.dictValue"
- />
- </el-select>
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="提醒时间:" prop="demandReminderTime">
- <el-input-number
- v-model="contractForm.demandReminderTime"
- :min="1"
- :max="365"
- style="width: 150px;"
- />
- <span style="margin-left: 10px;">天</span>
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="20">
- <el-col :span="12">
- <el-form-item label="开始时间:" prop="contractStartTime">
- <el-date-picker
- v-model="contractForm.contractStartTime"
- type="date"
- placeholder="请选择"
- style="width: 100%;"
- />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="截止时间:" prop="contractEndTime">
- <el-date-picker
- v-model="contractForm.contractEndTime"
- type="date"
- placeholder="请选择"
- style="width: 100%;"
- />
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="20">
- <el-col :span="12">
- <el-form-item label="开票类型:" prop="invoiceType">
- <el-select v-model="contractForm.invoiceType" placeholder="请选择" style="width: 100%;">
- <el-option
- v-for="item in invoiceTypeList"
- :key="item.id"
- :label="item.invoiceTypeName"
- :value="item.id"
- />
- </el-select>
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="合同金额:" prop="contractAmount">
- <el-input v-model="contractForm.contractAmount" placeholder="请输入">
- <template #append>万元</template>
- </el-input>
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="20">
- <el-col :span="12">
- <el-form-item label="税率:" prop="taxRate">
- <el-select v-model="contractForm.taxRate" placeholder="请选择" style="width: 100%;">
- <el-option
- v-for="item in taxRateList"
- :key="item.id"
- :label="item.taxrateName"
- :value="item.id"
- />
- </el-select>
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="结算方式:" prop="settlementMethod">
- <el-select v-model="contractForm.settlementMethod" placeholder="请选择" style="width: 100%;">
- <el-option
- v-for="item in settlementMethodList"
- :key="item.id"
- :label="item.settlementName"
- :value="item.id"
- />
- </el-select>
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="20">
- <el-col :span="24">
- <el-form-item label="合同附件:" prop="contractAttachment">
- <FileUpload
- v-model="contractForm.contractAttachment"
- :limit="10"
- :file-size="50"
- :file-type="['doc', 'docx', 'xls', 'xlsx', 'ppt', 'pptx', 'txt', 'pdf']"
- :disabled="contractDialogReadonly"
- />
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="20">
- <el-col :span="24">
- <el-form-item label="合同说明:" prop="contractDescription">
- <el-input
- v-model="contractForm.contractDescription"
- type="textarea"
- :rows="4"
- placeholder="请输入合同说明"
- />
- </el-form-item>
- </el-col>
- </el-row>
- </el-form>
- <template #footer>
- <div class="dialog-footer">
- <el-button @click="contractDialogVisible = false">取消</el-button>
- <el-button v-if="!contractDialogReadonly" type="primary" @click="handleContractSubmit" :loading="contractSubmitLoading">确定</el-button>
- </div>
- </template>
- </el-dialog>
- <!-- 品牌新增对话框 -->
- <el-dialog
- v-model="brandDialogVisible"
- title="添加品牌"
- width="600px"
- :close-on-click-modal="false"
- class="brand-dialog"
- >
- <div class="brand-dialog__search">
- <el-form @submit.prevent>
- <el-row :gutter="12" align="middle">
- <el-col :span="14">
- <el-form-item label="品牌名称:" style="margin-bottom: 0;">
- <el-input
- v-model="brandSearchKeyword"
- placeholder="请输入品牌名称"
- @keyup.enter="handleSearchBrand"
- />
- </el-form-item>
- </el-col>
- <el-col :span="10" style="display: flex; justify-content: flex-end;">
- <el-form-item label-width="0" style="margin-bottom: 0;">
- <el-button type="primary" @click="handleSearchBrand" :loading="brandSearchLoading">搜索</el-button>
- <el-button type="primary" @click="handleAddBrandToList()">添加</el-button>
- </el-form-item>
- </el-col>
- </el-row>
- </el-form>
- </div>
- <!-- 搜索结果列表 -->
- <div v-if="brandSearchResults.length > 0" class="brand-search-results">
- <div class="search-results-title">搜索结果(点击添加):</div>
- <div class="brand-result-item"
- v-for="brand in brandSearchResults"
- :key="brand.id"
- @click="handleAddBrandToList(brand)"
- style="cursor: pointer;"
- >
- <span class="brand-result-name">{{ brand.brandName }}</span>
- <span class="brand-result-no">编号: {{ brand.brandNo }}</span>
- </div>
- </div>
- <div class="selected-brands-section">
- <div class="section-label">已选择品牌:</div>
- <div class="brand-tags-container">
- <el-tag
- v-for="brand in tempSelectedBrands"
- :key="brand.id"
- closable
- @close="handleRemoveTempBrand(brand)"
- type="info"
- style="margin-right: 10px; margin-bottom: 10px;"
- >
- {{ brand.brandName }}
- </el-tag>
- <span v-if="tempSelectedBrands.length === 0" style="color: #999; font-size: 14px;">暂无已选择品牌</span>
- </div>
- </div>
- <template #footer>
- <div class="dialog-footer">
- <el-button @click="handleBrandDialogClose">取消</el-button>
- <el-button type="primary" @click="handleBrandSubmit" :loading="brandSubmitLoading">保存</el-button>
- </div>
- </template>
- </el-dialog>
- </div>
- </template>
- <script setup lang="ts">
- import { ref, onMounted } from 'vue';
- import { useRoute, useRouter } from 'vue-router';
- import { ArrowLeft, Plus, Search } from '@element-plus/icons-vue';
- import { ElMessage, ElMessageBox } from 'element-plus';
- import { useUserStore } from '@/store/modules/user';
- import RegionCascader from '@/components/RegionCascader/index.vue';
- import FileUpload from '@/components/FileUpload/index.vue';
- import Pagination from '@/components/Pagination/index.vue';
- import { getInfo, addInfo, updateInfo, scmEditInfo, getStaffListSplice, getSupplierStaffIds, getContactListById, getSupplierCategories, getSupplierContractsById, getBankBySupplierId, getAuthorizeDetailList, savePurchaseInfo, getDictData, getTaxRateList, getSettlementMethodList, getInvoiceTypeList, listInfo } from '@/api/customer/info';
- import { getProductCategoryList } from '@/api/product/category';
- import { getBank, updateBank, addBank } from '@/api/customer/bank';
- import { BankForm } from '@/api/customer/bank/types';
- import { getContact, addContact, updateContact } from '@/api/customer/contact';
- import { ContactForm } from '@/api/customer/contact/types';
- import { InfoVO } from '@/api/customer/info/types';
- import { listCompany } from '@/api/company/company';
- import { CompanyVO } from '@/api/company/company/types';
- import { listEnterpriseScale } from '@/api/customer/customerCategory/enterpriseScale';
- import { EnterpriseScaleVO } from '@/api/customer/customerCategory/enterpriseScale/types';
- import { listIndustryCategory } from '@/api/customer/customerCategory/industryCategory';
- import { IndustryCategoryVO } from '@/api/customer/customerCategory/industryCategory/types';
- import { listLevel } from '@/api/system/level';
- import { LevelVO } from '@/api/system/level/types';
- import { listType } from '@/api/system/type';
- import { TypeVO } from '@/api/system/type/types';
- import { listBrand, getBrand } from '@/api/product/brand';
- import { BrandVO } from '@/api/product/brand/types';
- import { listAddress, getAddress, addAddress, updateAddress, delAddress } from '@/api/supplier/address';
- import { AddressForm } from '@/api/supplier/address/types';
- import { addArea, listArea, getArea } from '@/api/supplier/area';
- import { listContract, getContract, addContract, updateContract } from '@/api/supplier/contract';
- import { ContractForm } from '@/api/supplier/contract/types';
- import { getBusinessInformation } from '@/api/customer/bussineInfo/index';
- import { listInvoiceType } from '@/api/system/invoiceType';
- import { InvoiceTypeVO } from '@/api/system/invoiceType/types';
- import { listBank as listSystemBank } from '@/api/system/bank';
- import { BankVO as SystemBankVO } from '@/api/system/bank/types';
- import { getInfoTemporary } from '@/api/supplier/infoTemporary';
- import { getChinaArea } from '@/api/system/addressarea/index';
- import download from '@/plugins/download';
- import BasicInfoTab from './components/BasicInfoTab.vue';
- import PurchaseInfoTab from './components/PurchaseInfoTab.vue';
- import ContactTab from './components/ContactTab.vue';
- import SupplyInfoTab from './components/SupplyInfoTab.vue';
- import AddressTab from './components/AddressTab.vue';
- import ContractTab from './components/ContractTab.vue';
- const route = useRoute();
- const router = useRouter();
- const userStore = useUserStore();
- const activeTab = ref('basic');
- const isAddMode = ref(false); // 是否为新增模式
- const isEditMode = ref(false); // 是否为编辑模式
- const isViewMode = ref(false); // 是否为查看模式
- const isBasicInfoSaved = ref(false); // 基础信息是否已保存(仅用于新增模式)
- const detailData = ref<InfoVO>({} as InfoVO);
- const staffOptions = ref<any[]>([]);
- const selectedProductManager = ref<number | null>(null);
- const selectedBuyer = ref<number | null>(null);
- const companyOptions = ref<CompanyVO[]>([]);
- const enterpriseScaleOptions = ref<EnterpriseScaleVO[]>([]);
- const industryCategoryOptions = ref<IndustryCategoryVO[]>([]);
- const supplierLevelOptions = ref<LevelVO[]>([]);
- const supplierTypeOptions = ref<TypeVO[]>([]);
- // 工商信息对象
- const businessInfo = ref<any>({});
- const businessInfoLoading = ref(false); // 获取工商信息的loading状态
- const businessInfoCache = new Map<string, any>();
- const lastBusinessInfoQuery = ref('');
- const lastBusinessInfoQueryAt = ref(0);
- const businessInfoInFlight = ref(false);
- // 联系人相关数据
- const contactList = ref<any[]>([]);
- const contactLoading = ref(false);
- const contactSearchParams = ref({
- userNo: '',
- userName: ''
- });
- // 联系人对话框相关
- const contactDialogVisible = ref(false);
- const contactDialogTitle = ref('');
- const contactDialogReadonly = ref(false);
- const contactFormRef = ref<ElFormInstance>();
- const contactSubmitLoading = ref(false);
- const contactForm = ref<ContactForm>({
- supplierNo: '',
- supplierId: undefined,
- userNo: '',
- userName: '',
- phone: '',
- roleNo: '',
- departmentNo: '',
- position: '',
- isPrimaryContact: '0',
- isRegister: '0',
- email: '',
- fax: '',
- remark: ''
- });
- const onContactPhoneInput = (val: string) => {
- const next = (val || '').replace(/\D+/g, '').slice(0, 11);
- if (next !== contactForm.value.phone) {
- contactForm.value.phone = next;
- }
- };
- // 联系人表单验证规则
- const contactFormRules = {
- userName: [{ required: true, message: '请输入员工姓名', trigger: 'blur' }],
- phone: [
- { required: true, message: '请输入手机号', trigger: 'blur' },
- { pattern: /^1[3-9]\d{9}$/, message: '请输入正确的11位手机号', trigger: 'blur' }
- ]
- };
- // 供应信息相关数据
- const productCategoryList = ref<any[]>([]);
- const selectedCategories = ref<string[]>([]);
- const supplyAreaList = ref<any[]>([]);
- // 授权详情信息列表(静态数据)
- const authorizationList = ref<any[]>([]);
- const authorizationPagination = ref({
- pageNum: 1,
- pageSize: 10,
- total: 0
- });
- // 供货区域对话框相关
- const supplyAreaDialogVisible = ref(false);
- const supplyAreaSubmitLoading = ref(false);
- const selectedSupplyAreaCodes = ref<string[]>([]); // 选中的供货区域(省/市ID数组)
- const savedAreaData = ref<any[]>([]); // 已保存的供货区域数据
- // 供货区域选择器数据源(从接口获取)
- const supplyAreaOptions = ref<any[]>([]);
- // 详细地址级联选择器相关
- const regionOptions = ref<any[]>([]); // 省市区级联选择器选项
- const selectedOfficeRegion = ref<string[]>([]); // 选中的省市区代码数组
- // 品牌相关数据
- const selectedBrands = ref<BrandVO[]>([]); // 已选择的品牌列表
- const brandDialogVisible = ref(false);
- const brandSearchKeyword = ref(''); // 品牌搜索关键词
- const tempSelectedBrands = ref<BrandVO[]>([]); // 弹框中临时选择的品牌
- const brandSearchResults = ref<BrandVO[]>([]); // 品牌搜索结果
- const allBrandList = ref<BrandVO[]>([]); // 所有品牌列表
- const brandSubmitLoading = ref(false);
- const brandSearchLoading = ref(false);
- /** 获取授权详情列表 */
- const getAuthorizationList = async () => {
- let id = route.query.id as string;
- // 如果URL中没有id,暂时跳过
- if (!id) {
- console.warn('缺少供应商ID,无法获取授权详情列表');
- return;
- }
- try {
- const res = await getAuthorizeDetailList({
- supplierId: id,
- pageNum: authorizationPagination.value.pageNum,
- pageSize: authorizationPagination.value.pageSize
- });
- console.log('授权详情API返回:', res);
- authorizationList.value = res.rows || res.data || [];
- authorizationPagination.value.total = res.total || 0;
- console.log('授权详情列表:', authorizationList.value);
- console.log('分页信息:', authorizationPagination.value);
- } catch (e) {
- console.error('获取授权详情列表失败:', e);
- }
- };
- // 地址管理列表
- const addressList = ref<any[]>([]);
- // 地址管理对话框相关
- const addressDialogVisible = ref(false);
- const addressDialogTitle = ref('');
- const addressDialogReadonly = ref(false);
- const addressFormRef = ref<ElFormInstance>();
- const addressSubmitLoading = ref(false);
- const selectedAddressRegion = ref<string[]>([]); // 地址的省市区代码数组
- const addressForm = ref<AddressForm>({
- supplierNo: '',
- supplierId: undefined,
- shipperName: '',
- shipperPhone: '',
- shippingPostCode: '',
- shippingProvincial: '',
- shippingCity: '',
- shippingCounty: '',
- shippingAddress: '',
- isSelf: 0
- });
- // 地址表单验证规则
- const addressFormRules = {
- shipperName: [{ required: true, message: '请输入收货人', trigger: 'blur' }],
- shipperPhone: [{ required: true, message: '请输入手机号码', trigger: 'blur' }],
- shippingProvincial: [{ required: true, message: '请选择地址', trigger: 'change' }],
- shippingAddress: [{ required: true, message: '请输入详细地址', trigger: 'blur' }]
- };
- // 付款信息列表
- const paymentInfoList = ref<any[]>([]);
- // 付款信息对话框相关
- const paymentDialogVisible = ref(false);
- const paymentDialogTitle = ref('');
- const paymentDialogReadonly = ref(false);
- const paymentFormRef = ref<ElFormInstance>();
- const paymentSubmitLoading = ref(false);
- const paymentForm = ref<BankForm>({
- num: undefined,
- supplierNo: '',
- bankNum: '',
- bankInfoNo: undefined,
- bankName: '',
- bankNo: '',
- isture: '1',
- circlesName: '',
- phone: '',
- invoiceTypeNo: undefined,
- invoiceTypeName: '',
- businessName: '',
- businessAddress: ''
- });
- const fixedPhoneReg = /^(\d{3,4}-?)?\d{7,8}(-\d{1,6})?$/;
- // 发票类型列表和银行列表
- const invoiceTypeList = ref<InvoiceTypeVO[]>([]);
- const systemBankList = ref<SystemBankVO[]>([]);
- // 付款信息表单验证规则
- const paymentFormRules = {
- invoiceTypeNo: [{ required: true, message: '请选择开票类型', trigger: 'change' }],
- bankNum: [
- {
- required: true,
- validator: (_rule: any, value: any, callback: any) => {
- const v = String(value ?? '').trim();
- if (!v) return callback(new Error('请输入开户行行号'));
- if (!/^\d+$/.test(v)) return callback(new Error('开户行行号只能输入数字'));
- callback();
- },
- trigger: 'blur'
- }
- ],
- bankInfoNo: [{ required: true, message: '请选择开户行名称', trigger: 'change' }],
- bankNo: [
- {
- required: true,
- validator: (_rule: any, value: any, callback: any) => {
- const v = String(value ?? '').trim();
- if (!v) return callback(new Error('请输入银行账户'));
- if (!/^\d+$/.test(v)) return callback(new Error('银行账户只能输入数字'));
- callback();
- },
- trigger: 'blur'
- }
- ],
- phone: [
- {
- required: true,
- validator: (_rule: any, value: any, callback: any) => {
- const v = String(value ?? '').trim();
- if (!v) return callback(new Error('请输入固定电话'));
- if (!fixedPhoneReg.test(v)) return callback(new Error('请输入正确的固定电话'));
- callback();
- },
- trigger: 'blur'
- }
- ],
- num: [{ required: true, message: '请选择是否主账号', trigger: 'change' }]
- };
- /** 获取发票类型列表 */
- const getInvoiceTypeData = async () => {
- try {
- const res = await listInvoiceType({ pageNum: 1, pageSize: 1000 });
- invoiceTypeList.value = res.rows || [];
- } catch (e) {
- console.error('获取发票类型失败:', e);
- }
- };
- /** 获取银行列表 */
- const getSystemBankData = async () => {
- try {
- const res = await listSystemBank({ pageNum: 1, pageSize: 1000 });
- systemBankList.value = res.rows || [];
- } catch (e) {
- console.error('获取银行列表失败:', e);
- }
- };
- /** 获取付款信息 */
- const getPaymentInfo = async () => {
- const id = route.query.id as string;
- if (!id) return;
- try {
- const res = await getBankBySupplierId(id);
- // 后端返回数组
- if (res.data) {
- paymentInfoList.value = Array.isArray(res.data) ? res.data : [res.data];
- }
- } catch (e) {
- console.error('获取付款信息失败:', e);
- }
- };
- // 合同管理相关数据
- const contractList = ref<any[]>([]);
- const contractSearchParams = ref({
- contractNo: '',
- contractName: '',
- contractType: '',
- contractStartTime: '' as string | Date | '',
- contractEndTime: '' as string | Date | '',
- contractStatus: ''
- });
- const contractPagination = ref({
- pageNum: 1,
- pageSize: 10,
- total: 0
- });
- const contractStatusDict = ref<any[]>([
- { dictLabel: '待审核', dictValue: '0' },
- { dictLabel: '生效', dictValue: '1' },
- { dictLabel: '失效', dictValue: '2' }
- ]);
- // 合同对话框相关
- const contractDialogVisible = ref(false);
- const contractDialogTitle = ref('');
- const contractDialogReadonly = ref(false);
- const contractFormRef = ref<ElFormInstance>();
- const contractSubmitLoading = ref(false);
- const contractTypeDict = ref<any[]>([]); // 合同类型字典
- const taxRateList = ref<any[]>([]); // 税率列表
- const settlementMethodList = ref<any[]>([]); // 结算方式列表
- const contractForm = ref<ContractForm>({
- supplierNo: '',
- supplierId: undefined,
- contractNo: '',
- contractName: '',
- contractType: '',
- contractStartTime: '',
- contractEndTime: '',
- contractStatus: 0,
- demandReminderTime: 4,
- taxRate: undefined,
- contractAmount: undefined,
- contractDescription: '',
- contractAttachment: '',
- settlementMethod: '',
- invoiceType: ''
- });
- // 合同表单验证规则
- const contractFormRules = {
- contractName: [{ required: true, message: '请输入合同名称', trigger: 'blur' }],
- contractType: [{ required: true, message: '请选择合同类型', trigger: 'change' }],
- contractStartTime: [{ required: true, message: '请选择开始时间', trigger: 'change' }],
- contractEndTime: [{ required: true, message: '请选择截止时间', trigger: 'change' }]
- };
- /** 返回列表页 */
- const goBack = () => {
- // 使用浏览器后退,返回上一页
- router.back();
- };
- /** 获取工商信息 */
- const handleGetBusinessInfo = async () => {
- const queryName = (detailData.value.businessName || '').trim();
- if (!queryName) {
- ElMessage.warning('请先输入工商名称');
- return;
- }
- const now = Date.now();
- if (businessInfoInFlight.value && lastBusinessInfoQuery.value === queryName) {
- return;
- }
- if (lastBusinessInfoQuery.value === queryName && now - lastBusinessInfoQueryAt.value < 1500) {
- return;
- }
- if (businessInfoCache.has(queryName)) {
- const cached = businessInfoCache.get(queryName);
- businessInfo.value = cached;
- if (cached?.businessName) detailData.value.businessName = cached.businessName;
- if (cached?.socialCreditCode) detailData.value.socialCreditCode = cached.socialCreditCode;
- if (cached?.legalPersonName) detailData.value.legalPersonName = cached.legalPersonName;
- if (cached?.registeredCapital) detailData.value.registeredCapital = cached.registeredCapital;
- return;
- }
- try {
- businessInfoLoading.value = true;
- businessInfoInFlight.value = true;
- lastBusinessInfoQuery.value = queryName;
- lastBusinessInfoQueryAt.value = now;
-
- // 调用获取工商信息接口
- const res = await getBusinessInformation(queryName);
-
- if (res.code === 200 && res.data) {
- // 将获取到的工商信息填充到表单
- businessInfo.value = res.data;
- businessInfoCache.set(queryName, res.data);
-
- // 自动填充基本信息表单的相关字段
- if (res.data.businessName) {
- detailData.value.businessName = res.data.businessName;
- }
- if (res.data.socialCreditCode) {
- detailData.value.socialCreditCode = res.data.socialCreditCode;
- }
- if (res.data.legalPersonName) {
- detailData.value.legalPersonName = res.data.legalPersonName;
- }
- if (res.data.registeredCapital) {
- detailData.value.registeredCapital = res.data.registeredCapital;
- }
-
- ElMessage.success('工商信息获取成功');
- } else {
- ElMessage.error(res.msg || '获取工商信息失败');
- }
- } catch (e) {
- console.error('获取工商信息失败:', e);
- ElMessage.error('获取工商信息失败');
- } finally {
- businessInfoLoading.value = false;
- businessInfoInFlight.value = false;
- }
- };
- /** 保存数据 */
- const handleSave = async () => {
- try {
- // 验证必填字段
- if (!detailData.value.ownedCompany) {
- ElMessage.warning('请选择所属公司');
- return;
- }
- if (!detailData.value.enterpriseName) {
- ElMessage.warning('请输入企业名称');
- return;
- }
- if (!detailData.value.businessName) {
- ElMessage.warning('请输入工商名称');
- return;
- }
- if (detailData.value.fixedPhone && !fixedPhoneReg.test(String(detailData.value.fixedPhone).trim())) {
- ElMessage.warning('请输入正确的固定电话');
- return;
- }
- if (!detailData.value.shortName) {
- ElMessage.warning('请输入企业简称');
- return;
- }
- if (!detailData.value.cooperateLevel) {
- ElMessage.warning('请选择供应商等级');
- return;
- }
- if (!detailData.value.membershipSize) {
- ElMessage.warning('请选择企业规模');
- return;
- }
- if (!detailData.value.industrCategory) {
- ElMessage.warning('请选择行业类别');
- return;
- }
- if (!detailData.value.supplierType) {
- ElMessage.warning('请选择供应商类型');
- return;
- }
- if (!detailData.value.officeProvince) {
- ElMessage.warning('请选择详细地址省份');
- return;
- }
- // 准备提交数据,包含工商信息
- const submitData: any = {
- ...detailData.value,
- supplierType: String(detailData.value.supplierType), // 确保是字符串类型
- cooperateLevel: String(detailData.value.cooperateLevel), // 确保是字符串类型
- // 将工商信息对象转换为 JSON 字符串存储到 otherCustomers 字段
- otherCustomers: businessInfo.value && Object.keys(businessInfo.value).length > 0
- ? JSON.stringify(businessInfo.value)
- : detailData.value.otherCustomers
- };
- // 根据模式调用新增或更新接口
- let res;
- if (isAddMode.value && !isBasicInfoSaved.value) {
- // 新增模式,调用新增接口
- res = await addInfo(submitData);
- } else {
- // 编辑模式,调用SCM更新接口(不走审核)
- res = await scmEditInfo(submitData);
- }
- ElMessage.success('保存成功');
- // 如果是新增模式,保存成功后标记为已保存,启用其他标签页
- if (isAddMode.value && !isBasicInfoSaved.value) {
- // 获取新创建的供应商ID
- let newId = null;
- if (res.data && res.data.id) {
- newId = res.data.id;
- } else {
- // 如果后端没返回ID,通过企业名称查询获取ID
- try {
- const listRes = await listInfo({
- enterpriseName: detailData.value.enterpriseName,
- pageNum: 1,
- pageSize: 1
- });
- if (listRes.rows && listRes.rows.length > 0) {
- newId = listRes.rows[0].id;
- }
- } catch (e) {
- console.error('获取新创建的供应商ID失败:', e);
- }
- }
-
- // 更新路由参数(保持 mode=add,添加 id)
- if (newId) {
- await router.replace({
- path: route.path,
- query: { id: newId, mode: 'add' }
- });
-
- // 标记基础信息已保存,启用其他标签页
- isBasicInfoSaved.value = true;
- detailData.value.id = newId;
-
- // 重新加载供应商详情以获取完整信息(包括supplierNo)
- try {
- const detailRes = await getInfo(newId);
- detailData.value = detailRes.data;
- } catch (e) {
- console.error('加载供应商详情失败:', e);
- }
-
- // 加载其他标签页数据
- getContactList();
- getProductCategories();
- getContractList();
- getPaymentInfo();
- getAuthorizationList();
- getAddressList();
- getSupplyAreaList();
- } else {
- ElMessage.warning('无法获取新创建的供应商ID');
- }
- } else {
- // 编辑模式,直接刷新当前数据
- if (detailData.value.id) {
- await getDetail();
- }
- }
- } catch (e) {
- console.error('保存失败:', e);
- }
- };
- /** 初始化省市区级联选择器数据 */
- const initRegionOptions = async () => {
- try {
- const { regionData } = await import('element-china-area-data');
- regionOptions.value = regionData as any[];
- } catch (e) {
- console.error('初始化省市区数据失败:', e);
- }
- };
- /** 初始化供货区域选项数据 */
- const initSupplyAreaOptions = async () => {
- try {
- const res = await getChinaArea();
- const raw = (res as any)?.data || (res as any)?.rows || res || [];
- const mapTree = (nodes: any[]): any[] => {
- return (nodes || []).map((n: any) => ({
- label: n.areaName,
- value: String(n.id),
- areaCode: String(n.areaCode ?? ''),
- parentId: n.parentCode ?? n.parentId,
- level: n.level,
- children: n.children && n.children.length ? mapTree(n.children) : []
- }));
- };
- supplyAreaOptions.value = mapTree(raw);
- } catch (e) {
- console.error('初始化供货区域选项失败:', e);
- supplyAreaOptions.value = [];
- }
- };
- /** 详细地址省市区改变事件 */
- const handleOfficeRegionChange = (value: string[]) => {
- if (value && value.length === 3) {
- // value 是 [省代码, 市代码, 区代码]
- const [provinceCode, cityCode, districtCode] = value;
- // 同时保存 code(后端若支持可直接入库,不支持则忽略;前端回显优先使用 code)
- (detailData.value as any).officeProvinceCode = provinceCode;
- (detailData.value as any).officeCityCode = cityCode;
- (detailData.value as any).officeCountyCode = districtCode;
- // 从 regionOptions 中查找对应的名称
- let provinceName = '';
- let cityName = '';
- let districtName = '';
- const province = regionOptions.value.find((p: any) => p.value === provinceCode);
- if (province) {
- provinceName = province.label;
- const city = province.children?.find((c: any) => c.value === cityCode);
- if (city) {
- cityName = city.label;
- const district = city.children?.find((d: any) => d.value === districtCode);
- if (district) {
- districtName = district.label;
- }
- }
- }
- // 更新 detailData
- detailData.value.officeProvince = provinceName;
- detailData.value.officeCity = cityName;
- detailData.value.officeCounty = districtName;
- } else {
- // 清空
- (detailData.value as any).officeProvinceCode = '';
- (detailData.value as any).officeCityCode = '';
- (detailData.value as any).officeCountyCode = '';
- detailData.value.officeProvince = '';
- detailData.value.officeCity = '';
- detailData.value.officeCounty = '';
- }
- };
- /** 获取详情数据 */
- const getDetail = async () => {
- const id = route.query.id as string;
- const mode = route.query.mode as string;
- // 重置所有模式标志
- isAddMode.value = false;
- isEditMode.value = false;
- isViewMode.value = false;
- isBasicInfoSaved.value = false;
- // 判断模式
- if (mode === 'add') {
- // 新增模式
- isAddMode.value = true;
- if (id) {
- // 如果有ID,说明基础信息已保存
- isBasicInfoSaved.value = true;
- }
- return;
- } else if (mode === 'edit' && id) {
- // 编辑模式(必须有ID)
- isEditMode.value = true;
- } else if (id) {
- // 查看模式(有ID但没有mode或mode=view)
- isViewMode.value = true;
- } else {
- // 没有ID也没有mode,默认为新增模式
- isAddMode.value = true;
- return;
- }
- // 有ID的情况下,加载详情数据
- if (id) {
- const res = await getInfo(id);
- detailData.value = res.data;
- // 如果是edit模式且供应商状态为"待修改审核"(4),需要查询临时表数据
- if (isEditMode.value && detailData.value.supplyStatus === '4') {
- try {
- const tempRes = await getInfoTemporary(id);
-
- if (tempRes.data) {
- // 使用临时表数据覆盖主表数据
- const tempData: any = tempRes.data;
- detailData.value = {
- ...detailData.value, // 保留主表的一些基础字段
- ...tempData, // 使用临时表的修改数据
- id: detailData.value.id, // 确保ID是主表的ID
- supplierNo: detailData.value.supplierNo // 确保supplierNo是主表的
- } as any;
- console.log('已加载临时表数据:', tempData);
- }
- } catch (e) {
- console.error('查询临时表失败:', e);
- // 查询失败,继续使用主表数据
- }
- }
- // 如果 personImageUrl 为空但 personImage 有值,使用 personImage 的值
- if (!detailData.value.personImageUrl && detailData.value.personImage) {
- detailData.value.personImageUrl = detailData.value.personImage;
- }
- // 初始化品牌列表
- initBrandList();
- // 供货区域列表会在 onMounted 中通过 getSupplyAreaList() 获取,这里不需要初始化
- // 注释掉简单的初始化,避免与 getSupplyAreaList 冲突
- // if ((detailData.value as any).province || (detailData.value as any).city) {
- // supplyAreaList.value = [{
- // province: (detailData.value as any).province || '',
- // city: (detailData.value as any).city || ''
- // }];
- // }
- // 初始化详细地址显示:优先使用已保存的 code;没有 code 时再用 name 反查 code
- const officeProvinceCode = (detailData.value as any).officeProvinceCode;
- const officeCityCode = (detailData.value as any).officeCityCode;
- const officeCountyCode = (detailData.value as any).officeCountyCode;
- if (officeProvinceCode && officeCityCode && officeCountyCode) {
- selectedOfficeRegion.value = [String(officeProvinceCode), String(officeCityCode), String(officeCountyCode)];
- } else if (detailData.value.officeProvince && detailData.value.officeCity && detailData.value.officeCounty) {
- const province = detailData.value.officeProvince;
- const city = detailData.value.officeCity;
- const county = detailData.value.officeCounty;
- // 根据省市区名称查找对应的代码
- const provinceItem = regionOptions.value.find((p: any) => p.label === province);
- if (provinceItem) {
- const cityItem = provinceItem.children?.find((c: any) => c.label === city);
- if (cityItem) {
- const districtItem = cityItem.children?.find((d: any) => d.label === county);
- if (districtItem) {
- selectedOfficeRegion.value = [provinceItem.value, cityItem.value, districtItem.value];
- }
- }
- }
- }
- // 解析工商信息,支持 otherCustomersMap 或 otherCustomers
- const otherCustomersData = (detailData.value as any).otherCustomersMap || detailData.value.otherCustomers;
- if (otherCustomersData) {
- try {
- // 如果是字符串,需要解析JSON
- if (typeof otherCustomersData === 'string') {
- businessInfo.value = JSON.parse(otherCustomersData);
- } else {
- businessInfo.value = otherCustomersData;
- }
- console.log('工商信息:', businessInfo.value);
- } catch (e) {
- console.error('解析工商信息失败:', e);
- }
- }
- // 工商信息字段已经在 detailData 中返回,直接使用
- // 将 detailData 的工商信息字段映射到 businessInfo
- businessInfo.value = {
- businessName: detailData.value.businessName,
- registrationAuthority: (detailData.value as any).registrationAuthority,
- establishmentDate: (detailData.value as any).establishmentDate,
- registrationStatus: (detailData.value as any).registrationStatus,
- paidInCapital: (detailData.value as any).paidInCapital,
- socialCreditCode: detailData.value.socialCreditCode,
- legalPersonName: detailData.value.legalPersonName,
- registeredCapital: detailData.value.registeredCapital,
- revocationDate: (detailData.value as any).revocationDate,
- bussinessRange: (detailData.value as any).bussinessRange,
- businessAddress: (detailData.value as any).businessAddress
- };
- console.log('工商信息(从详情接口):', businessInfo.value);
- // 获取当前供应商的产品经理和采购员ID
- try {
- const staffIdsRes = await getSupplierStaffIds(id);
- const staffIds = staffIdsRes.data; // {productManager: 1, purchaser: 2}
- selectedProductManager.value = staffIds.productManager;
- selectedBuyer.value = staffIds.purchaser;
- console.log('当前产品经理ID:', staffIds.productManager);
- console.log('当前采购员ID:', staffIds.purchaser);
- } catch (e) {
- console.error('获取人员ID失败:', e);
- }
- }
- };
- /** 获取人员下拉选项 */
- const getStaffOptions = async () => {
- try {
- const res = await getStaffListSplice();
- const staffMap = res.data; // Map<Long, String> 格式:{1: "00040,郑春风", 2: "00050,王坤"}
- // 转换为下拉框选项格式
- staffOptions.value = Object.entries(staffMap).map(([staffId, displayText]) => ({
- staffId: Number(staffId),
- displayText: displayText,
- label: displayText,
- value: Number(staffId)
- }));
- } catch (e) {
- console.error('获取人员信息失败:', e);
- }
- };
- /** 获取公司下拉选项 */
- const getCompanyOptions = async () => {
- try {
- const res = await listCompany({
- pageNum: 1,
- pageSize: 1000,
- status: '0'
- }); // 只获取正常状态的公司
- companyOptions.value = res.rows || [];
- } catch (e) {
- console.error('获取公司信息失败:', e);
- }
- };
- /** 获取企业规模下拉选项 */
- const getEnterpriseScaleOptions = async () => {
- try {
- const res = await listEnterpriseScale({
- pageNum: 1,
- pageSize: 1000,
- status: '0' // 只获取正常状态的企业规模
- });
- enterpriseScaleOptions.value = res.data || res.rows || [];
- } catch (e) {
- console.error('获取企业规模信息失败:', e);
- }
- };
- /** 获取行业类别下拉选项 */
- const getIndustryCategoryOptions = async () => {
- try {
- const res = await listIndustryCategory({
- pageNum: 1,
- pageSize: 1000,
- status: '0' // 只获取正常状态的行业类别
- });
- industryCategoryOptions.value = res.data || res.rows || [];
- } catch (e) {
- console.error('获取行业类别信息失败:', e);
- }
- };
- /** 获取供应商等级下拉选项 */
- const getSupplierLevelOptions = async () => {
- try {
- const res = await listLevel({
- pageNum: 1,
- pageSize: 1000
- });
- supplierLevelOptions.value = res.data || res.rows || [];
- } catch (e) {
- console.error('获取供应商等级信息失败:', e);
- }
- };
- /** 获取供应商类型下拉选项 */
- const getSupplierTypeOptions = async () => {
- try {
- const res = await listType({
- pageNum: 1,
- pageSize: 1000
- } as any);
- supplierTypeOptions.value = res.data || res.rows || [];
- } catch (e) {
- console.error('获取供应商类型信息失败:', e);
- }
- };
- /** 获取联系人列表 */
- const getContactList = async () => {
- const id = route.query.id as string;
- if (!id) return;
- contactLoading.value = true;
- try {
- const res = await getContactListById(id, {
- pageNum: 1,
- pageSize: 100,
- ...contactSearchParams.value
- });
- contactList.value = res.rows || [];
- } catch (e) {
- console.error('获取联系人列表失败:', e);
- } finally {
- contactLoading.value = false;
- }
- };
- /** 搜索联系人 */
- const handleContactSearch = () => {
- getContactList();
- };
- /** 重置联系人搜索 */
- const handleContactReset = () => {
- contactSearchParams.value = {
- userNo: '',
- userName: ''
- };
- getContactList();
- };
- /** 新增联系人 */
- const handleAddContact = () => {
- // 重置表单
- contactForm.value = {
- supplierNo: detailData.value.supplierNo,
- supplierId: route.query.id as any,
- userNo: '',
- userName: '',
- phone: '',
- roleNo: '',
- departmentNo: '',
- position: '',
- isPrimaryContact: '0',
- isRegister: '0',
- email: '',
- fax: '',
- remark: ''
- };
- contactDialogTitle.value = '新增联系人';
- contactDialogReadonly.value = false;
- contactDialogVisible.value = true;
- };
- /** 查看联系人 */
- const handleViewContact = async (row: any) => {
- try {
- const res = await getContact(row.id);
- Object.assign(contactForm.value, res.data);
- contactDialogTitle.value = '查看联系人';
- contactDialogReadonly.value = true;
- contactDialogVisible.value = true;
- } catch (e) {
- console.error('获取联系人详情失败:', e);
- ElMessage.error('获取联系人详情失败');
- }
- };
- /** 编辑联系人 */
- const handleEditContact = async (row: any) => {
- try {
- const res = await getContact(row.id);
- Object.assign(contactForm.value, res.data);
- contactDialogTitle.value = '编辑联系人';
- contactDialogReadonly.value = false;
- contactDialogVisible.value = true;
- } catch (e) {
- console.error('获取联系人详情失败:', e);
- ElMessage.error('获取联系人详情失败');
- }
- };
- /** 提交联系人 */
- const handleContactSubmit = async () => {
- if (!contactFormRef.value) return;
- contactFormRef.value.validate(async (valid: boolean) => {
- if (!valid) return;
- try {
- contactSubmitLoading.value = true;
- // 设置供应商编号和ID
- if (!contactForm.value.supplierNo && detailData.value.supplierNo) {
- contactForm.value.supplierNo = detailData.value.supplierNo;
- }
- if (!contactForm.value.supplierId && route.query.id) {
- contactForm.value.supplierId = route.query.id as any;
- }
- if ((contactForm.value as any).id) {
- // 更新
- await updateContact(contactForm.value);
- ElMessage.success('更新成功');
- } else {
- // 新增
- await addContact(contactForm.value);
- ElMessage.success('新增成功');
- }
- contactDialogVisible.value = false;
- // 刷新联系人列表
- await getContactList();
- } catch (e) {
- console.error('保存联系人失败:', e);
- ElMessage.error('保存联系人失败');
- } finally {
- contactSubmitLoading.value = false;
- }
- });
- };
- /** 获取产品分类列表 */
- const getProductCategories = async () => {
- try {
- const res = await getProductCategoryList();
- productCategoryList.value = res.rows || res.data || [];
- console.log('产品分类列表:', productCategoryList.value);
- // 获取分类列表后,再获取已选择的品目
- await getSupplierSelectedCategories();
- } catch (e) {
- console.error('获取产品分类失败:', e);
- }
- };
- /** 获取供应商已选择的品目 */
- const getSupplierSelectedCategories = async () => {
- const id = route.query.id as string;
- if (!id) return;
- try {
- // 在edit模式下传递supplyStatus参数
- const supplyStatus = isEditMode.value ? "4" : undefined;
- const res = await getSupplierCategories(id, supplyStatus);
-
- // 确保数据类型一致,转换为字符串数组
- selectedCategories.value = (res.data || []).map(String);
- console.log('供应商已选择的品目ID:', selectedCategories.value);
- console.log('产品分类列表:', productCategoryList.value);
- } catch (e) {
- console.error('获取供应商品目失败:', e);
- }
- };
- /** 保存供货类目 */
- const handleSaveCategories = async () => {
- try {
- const id = route.query.id as string;
- if (!id) {
- ElMessage.error('供应商ID不存在');
- return;
- }
- // 方案B:只提交必要字段,避免EditGroup校验因缺字段失败
- await scmEditInfo({
- id,
- operatingCategory: selectedCategories.value.join(',')
- } as any);
- ElMessage.success('保存成功');
- } catch (e) {
- console.error('保存供货类目失败:', e);
- }
- };
- /** 保存采购信息 */
- const handleSavePurchaseInfo = async () => {
- try {
- const id = route.query.id as string;
- if (!id) {
- ElMessage.error('供应商ID不存在');
- return;
- }
- // 调用保存采购信息接口
- await savePurchaseInfo({
- supplierId: id,
- productManager: selectedProductManager.value,
- purchaser: selectedBuyer.value
- });
- ElMessage.success('保存成功');
- } catch (e) {
- console.error('保存采购信息失败:', e);
- }
- };
- /** 获取所有品牌列表 */
- const getAllBrandList = async () => {
- try {
- const res = await listBrand({
- pageNum: 1,
- pageSize: 1000 // 获取所有品牌
- });
- allBrandList.value = res.rows || [];
- console.log('品牌列表:', allBrandList.value);
- } catch (e) {
- console.error('获取品牌列表失败:', e);
- }
- };
- /** 新增品牌 - 打开弹框 */
- const handleAddBrand = () => {
- // 复制当前已选择的品牌到临时列表
- tempSelectedBrands.value = [...selectedBrands.value];
- brandSearchKeyword.value = '';
- // 显示所有品牌作为初始搜索结果
- brandSearchResults.value = [...allBrandList.value];
- brandDialogVisible.value = true;
- };
- /** 搜索品牌 */
- const handleSearchBrand = async () => {
- // 如果搜索关键词为空,显示所有品牌
- if (!brandSearchKeyword.value.trim()) {
- brandSearchResults.value = [...allBrandList.value];
- return;
- }
- try {
- brandSearchLoading.value = true;
- const res = await listBrand({
- brandName: brandSearchKeyword.value.trim(),
- pageNum: 1,
- pageSize: 50
- });
- brandSearchResults.value = res.rows || [];
- if (brandSearchResults.value.length === 0) {
- ElMessage.info('未找到匹配的品牌');
- }
- } catch (e) {
- console.error('搜索品牌失败:', e);
- ElMessage.error('搜索品牌失败');
- } finally {
- brandSearchLoading.value = false;
- }
- };
- /** 添加品牌到列表 */
- const handleAddBrandToList = (brand?: BrandVO) => {
- // 如果没有传入品牌,则使用搜索关键词手动创建
- if (!brand) {
- if (!brandSearchKeyword.value.trim()) {
- ElMessage.warning('请输入品牌名称或先搜索品牌');
- return;
- }
- // 手动创建品牌对象(临时方案)
- brand = {
- id: brandSearchKeyword.value.trim(),
- brandName: brandSearchKeyword.value.trim()
- } as BrandVO;
- }
- // 检查品牌是否已存在
- const exists = tempSelectedBrands.value.some(b => b.id === brand!.id);
- if (exists) {
- ElMessage.warning('该品牌已添加');
- return;
- }
- // 添加品牌到临时列表
- tempSelectedBrands.value.push(brand);
- // 不清空搜索框和搜索结果,允许用户继续选择多个品牌
- // brandSearchKeyword.value = '';
- // brandSearchResults.value = [];
- ElMessage.success(`已添加品牌:${brand.brandName}`);
- };
- /** 删除临时品牌 */
- const handleRemoveTempBrand = (brand: BrandVO) => {
- const index = tempSelectedBrands.value.findIndex(b => b.id === brand.id);
- if (index > -1) {
- tempSelectedBrands.value.splice(index, 1);
- }
- };
- /** 删除已选择的品牌 */
- const handleRemoveBrand = async (brand: BrandVO) => {
- const index = selectedBrands.value.findIndex(b => b.id === brand.id);
- if (index > -1) {
- selectedBrands.value.splice(index, 1);
- // 立即保存到后端
- await saveBrandsToServer();
- }
- };
- /** 品牌对话框关闭 */
- const handleBrandDialogClose = () => {
- brandDialogVisible.value = false;
- brandSearchKeyword.value = '';
- };
- /** 提交品牌 */
- const handleBrandSubmit = async () => {
- try {
- brandSubmitLoading.value = true;
- // 更新主品牌列表
- selectedBrands.value = [...tempSelectedBrands.value];
- // 保存到服务器
- await saveBrandsToServer();
- ElMessage.success('保存成功');
- brandDialogVisible.value = false;
- } catch (e) {
- console.error('保存品牌失败:', e);
- } finally {
- brandSubmitLoading.value = false;
- }
- };
- /** 保存品牌到服务器 */
- const saveBrandsToServer = async () => {
- const id = route.query.id as string;
- if (!id) {
- ElMessage.error('供应商ID不存在');
- return;
- }
- // 将品牌ID用逗号分隔保存
- const brandIds = selectedBrands.value.map(brand => brand.id).join(',');
- // 方案B:只提交必要字段,避免EditGroup校验因缺字段失败
- await scmEditInfo({
- id,
- operatingBrand: brandIds
- } as any);
- };
- /** 初始化品牌列表 - 从后端数据解析 */
- const initBrandList = async () => {
- if (detailData.value.operatingBrand) {
- // 后端返回的是用逗号分隔的品牌ID
- const brandIds = detailData.value.operatingBrand.split(',').filter(id => id.trim());
- if (brandIds.length > 0) {
- try {
- // 根据品牌ID获取品牌详细信息
- const brandPromises = brandIds.map(id => getBrand(id.trim()));
- const brandResults = await Promise.allSettled(brandPromises);
- selectedBrands.value = brandResults
- .filter(result => result.status === 'fulfilled')
- .map(result => (result as PromiseFulfilledResult<any>).value.data)
- .filter(brand => brand); // 过滤掉空值
- } catch (e) {
- console.error('获取品牌详情失败:', e);
- // 降级处理:如果获取品牌详情失败,使用ID作为显示名称
- selectedBrands.value = brandIds.map(id => ({
- id: id.trim(),
- brandName: id.trim()
- } as BrandVO));
- }
- }
- }
- };
- /** 获取供货区域列表 */
- const getSupplyAreaList = async () => {
- const id = route.query.id as string;
- if (!id) return;
- try {
- // 构建查询参数
- const queryParams: any = {
- supplierId: id,
- pageNum: 1,
- pageSize: 1000
- };
- // 只在编辑模式下添加 supplyStatus
- if (isEditMode.value) {
- queryParams.supplyStatus = "4";
- }
- const res = await listArea(queryParams);
-
- // 保存原始数据,用于编辑时回显
- savedAreaData.value = res.data || res.rows || [];
-
- // 处理返回的数据,按层级组织
- const areaData = savedAreaData.value;
-
- // 第一步:先收集所有省份(用 areaId 做父子关联 key)
- const provinceMap: any = {};
- areaData.forEach((area: any) => {
- if (area.level === '1' || area.level === 1) {
- const pId = String(area.areaId ?? area.areaCode);
- provinceMap[pId] = {
- province: area.areaName,
- city: ''
- };
- }
- });
-
- // 第二步:将城市添加到对应的省份
- areaData.forEach((area: any) => {
- if (area.level === '2' || area.level === 2) {
- const pId = String(area.parentId ?? '0');
- if (provinceMap[pId]) {
- if (provinceMap[pId].city) {
- provinceMap[pId].city += ',' + area.areaName;
- } else {
- provinceMap[pId].city = area.areaName;
- }
- }
- }
- });
-
- // 转换为数组
- supplyAreaList.value = Object.values(provinceMap).filter((item: any) =>
- item.province || item.city
- );
-
- console.log('供货区域列表:', supplyAreaList.value);
- console.log('保存的原始数据:', savedAreaData.value);
- } catch (e) {
- console.error('获取供货区域列表失败:', e);
- }
- };
- /** 编辑供货区域 */
- const handleEditSupplyArea = async () => {
- supplyAreaDialogVisible.value = true;
- // 等待对话框打开后再设置回显数据
- await nextTick();
- selectedSupplyAreaCodes.value = buildSupplyAreaCodesFromSavedData(savedAreaData.value);
- };
- /** 根据已保存的省/市数据生成 RegionCascader 需要的省/市ID列表 */
- const buildSupplyAreaCodesFromSavedData = (areaData: any[]) => {
- const codes = new Set<string>();
- if (!areaData || areaData.length === 0) return [];
- areaData.forEach((area: any) => {
- const level = String(area.level);
- const areaId = String(area.areaId ?? area.id ?? '');
- if (!areaId) return;
- if (level === '1' || level === '2') {
- codes.add(areaId);
- }
- });
- return Array.from(codes);
- };
- /** 根据省/市ID提取供货区域(省/市)展示字符串 */
- const extractRegionDataFromSelectedProvinceCityIds = (selectedIds: string[]) => {
- const provinces: any[] = supplyAreaOptions.value || [];
- const provinceNames: string[] = [];
- const cityNames: string[] = [];
- const addedProvinces = new Set<string>();
- const addedCities = new Set<string>();
- selectedIds.forEach((id) => {
- for (const province of provinces) {
- if (String(province.value) === String(id)) {
- if (!addedProvinces.has(String(province.value))) {
- provinceNames.push(province.label);
- addedProvinces.add(String(province.value));
- }
- return;
- }
- const cities = province?.children || [];
- const hitCity = cities.find((c: any) => String(c.value) === String(id));
- if (hitCity) {
- if (!addedProvinces.has(String(province.value))) {
- provinceNames.push(province.label);
- addedProvinces.add(String(province.value));
- }
- if (!addedCities.has(String(hitCity.value))) {
- cityNames.push(hitCity.label);
- addedCities.add(String(hitCity.value));
- }
- return;
- }
- }
- });
- return {
- provinces: provinceNames.join(','),
- cities: cityNames.join(',')
- };
- };
- /** 构建 areaList 数组(提交给后端:省(1)/市(2)) */
- const buildAreaListFromSelectedProvinceCityIds = (selectedIds: string[]) => {
- const provinces: any[] = supplyAreaOptions.value || [];
- const areaList: any[] = [];
- const addedProvinces = new Set<string>();
- const addedCities = new Set<string>();
- selectedIds.forEach((id) => {
- for (const province of provinces) {
- // 省
- if (String(province.value) === String(id)) {
- if (!addedProvinces.has(String(province.value))) {
- areaList.push({
- areaId: Number(province.value),
- areaCode: province.areaCode || province.value,
- areaName: province.label,
- level: 1,
- parentId: 0
- });
- addedProvinces.add(String(province.value));
- }
- return;
- }
- // 市
- const cities = province?.children || [];
- const hitCity = cities.find((c: any) => String(c.value) === String(id));
- if (hitCity) {
- // city 已选时确保 parent province 也存在(即使组件没回传,也兜底)
- if (!addedProvinces.has(String(province.value))) {
- areaList.push({
- areaId: Number(province.value),
- areaCode: province.areaCode || province.value,
- areaName: province.label,
- level: 1,
- parentId: 0
- });
- addedProvinces.add(String(province.value));
- }
- if (!addedCities.has(String(hitCity.value))) {
- areaList.push({
- areaId: Number(hitCity.value),
- areaCode: hitCity.areaCode || hitCity.value,
- areaName: hitCity.label,
- level: 2,
- parentId: Number(province.value)
- });
- addedCities.add(String(hitCity.value));
- }
- return;
- }
- }
- });
- return areaList;
- };
- /** 提交供货区域 */
- const handleSupplyAreaSubmit = async () => {
- try {
- supplyAreaSubmitLoading.value = true;
- const id = route.query.id as string;
- if (!id) {
- ElMessage.error('供应商ID不存在');
- return;
- }
- if (!detailData.value.supplierNo) {
- ElMessage.error('供应商编号不存在,请先保存基础信息');
- return;
- }
- console.log('提交前的选中省/市ID:', selectedSupplyAreaCodes.value);
- // 构建 areaList 数组
- const areaList = buildAreaListFromSelectedProvinceCityIds(selectedSupplyAreaCodes.value);
- console.log('构建的 areaList:', areaList);
- const areaListToSubmit = areaList || [];
- // 从选中的编码中提取区域信息(用于显示)
- const regionData = extractRegionDataFromSelectedProvinceCityIds(selectedSupplyAreaCodes.value);
- console.log('提取的区域数据:', regionData);
- // 构建提交数据
- const submitData: any = {
- supplierId: id,
- supplyNo: detailData.value.supplierNo,
- areaList: areaListToSubmit
- };
-
- console.log('提交的数据:', submitData);
- await addArea(submitData);
- // 更新本地数据
- (detailData.value as any).province = regionData.provinces;
- (detailData.value as any).city = regionData.cities;
- // edit模式下,保存供货区域后需要同步更新主表信息(保留其他字段的修改)
- if (isEditMode.value) {
- try {
- const tempRes = await getInfoTemporary(id);
-
- let mainSubmitData: any;
- if (tempRes.data) {
- // 临时表已有记录,使用临时表数据作为基础
- const tempData = tempRes.data;
- mainSubmitData = {
- ...tempData, // 临时表中的数据(保留之前的所有修改)
- ...detailData.value, // 当前页面的数据
- supplierType: String(detailData.value.supplierType),
- cooperateLevel: String(detailData.value.cooperateLevel),
- };
- } else {
- // 临时表没有记录,使用当前数据
- mainSubmitData = {
- ...detailData.value,
- supplierType: String(detailData.value.supplierType),
- cooperateLevel: String(detailData.value.cooperateLevel),
- };
- }
-
- // 删除后端返回的展示字段
- delete mainSubmitData.supplierTypeName;
- delete mainSubmitData.cooperateLevelName;
- delete mainSubmitData.membershipSizeName;
- delete mainSubmitData.industrCategoryName;
- delete mainSubmitData.productManager;
- delete mainSubmitData.buyer;
- delete mainSubmitData.brandName;
- delete mainSubmitData.province;
- delete mainSubmitData.city;
-
- // 更新主表信息
- await updateInfo(mainSubmitData);
- } catch (e) {
- console.error('更新主表信息失败:', e);
- }
- }
- ElMessage.success('保存成功');
- supplyAreaDialogVisible.value = false;
- await getSupplyAreaList();
- } catch (e) {
- console.error('保存供货区域失败:', e);
- } finally {
- supplyAreaSubmitLoading.value = false;
- }
- };
- /** 供货区域选择变化 */
- const handleSupplyAreaChange = (value: any) => {
- console.log('供货区域选择变化:', value);
- };
- /** 格式化日期 */
- const formatDate = (date: string | Date) => {
- if (!date) return '-';
- const d = new Date(date);
- return d.toISOString().split('T')[0];
- };
- /** 获取合同状态类型 */
- const getContractStatusType = (status: number) => {
- const statusMap = {
- 0: 'info', // 草稿
- 1: 'success', // 已生效
- 2: 'warning', // 已到期
- 3: 'danger', // 已终止
- 4: 'danger' // 已作废
- };
- return statusMap[status] || 'info';
- };
- /** 获取合同状态文本 */
- const getContractStatusText = (status: number) => {
- const statusMap = {
- 0: '待审核',
- 1: '生效',
- 2: '失效'
- };
- return statusMap[status] || '未知';
- };
- /** 获取合同类型文本 */
- const getContractTypeText = (type: string | number) => {
- const typeMap = {
- '0': '年度合作',
- '1': '项目采购',
- '2': '其他合作',
- };
- return typeMap[type] || '未知';
- };
- /** 获取授权状态文本 */
- const getAuthorizedStatusText = (status: string) => {
- const statusMap = {
- '0': '待审核',
- '1': '已生效',
- '2': '已过期'
- };
- return statusMap[status] || '未知';
- };
- /** 搜索合同 */
- const handleContractSearch = () => {
- console.log('搜索合同:', contractSearchParams.value);
- getContractList();
- };
- /** 重置合同搜索 */
- const handleContractReset = () => {
- contractSearchParams.value = {
- contractNo: '',
- contractName: '',
- contractType: '',
- contractStartTime: '',
- contractEndTime: '',
- contractStatus: ''
- };
- getContractList();
- };
- const wanToYuanString = (value: unknown): string => {
- const raw = String(value ?? '').trim();
- if (!raw) return '';
- const normalized = raw.replace(/,/g, '');
- const match = normalized.match(/^(-?)(\d+)(?:\.(\d+))?$/);
- if (!match) return '';
- const sign = match[1] ? '-' : '';
- const intPart = match[2] || '0';
- const fracRaw = match[3] || '';
- const fracPart = (fracRaw + '0000').slice(0, 4);
- const base = BigInt(intPart) * 10000n + BigInt(fracPart);
- return sign ? '-' + base.toString() : base.toString();
- };
- const yuanToWanString = (value: unknown): string => {
- const raw = String(value ?? '').trim();
- if (!raw) return '';
- const normalized = raw.replace(/,/g, '');
- const match = normalized.match(/^(-?)(\d+)$/);
- if (!match) return '';
- const sign = match[1] ? '-' : '';
- const amount = BigInt(match[2] || '0');
- const intPart = amount / 10000n;
- const fracPart = amount % 10000n;
- const fracPadded = fracPart.toString().padStart(4, '0');
- const fracTrimmed = fracPadded.replace(/0+$/, '');
- const result = fracTrimmed ? `${intPart.toString()}.${fracTrimmed}` : intPart.toString();
- return sign ? '-' + result : result;
- };
- /** 获取合同列表 */
- const getContractList = async () => {
- const id = route.query.id as string;
- if (!id) return;
- try {
- // 构建查询参数,排除日期字段
- const { contractStartTime, contractEndTime, ...otherParams } = contractSearchParams.value;
-
- const params: any = {
- pageNum: contractPagination.value.pageNum,
- pageSize: contractPagination.value.pageSize,
- ...otherParams
- };
-
- // 如果有开始时间,格式化为 YYYY-MM-DD
- if (contractStartTime) {
- const date = new Date(contractStartTime);
- params.contractStartTime = `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}-${String(date.getDate()).padStart(2, '0')}`;
- }
-
- // 如果有结束时间,格式化为 YYYY-MM-DD
- if (contractEndTime) {
- const date = new Date(contractEndTime);
- params.contractEndTime = `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}-${String(date.getDate()).padStart(2, '0')}`;
- }
-
- console.log('合同查询参数:', params); // 添加日志方便调试
-
- const res = await getSupplierContractsById(id, params);
- contractList.value = (res.rows || []).map((row: any) => ({
- ...row,
- contractAmount: yuanToWanString(row?.contractAmount)
- }));
- contractPagination.value.total = res.total || 0;
- } catch (e) {
- console.error('获取合同列表失败:', e);
- }
- };
- /** 查看附件 */
- const handleViewAttachment = (row: any) => {
- console.log('查看附件:', row);
-
- if (!row.contractAttachment) {
- ElMessage.warning('该合同没有附件');
- return;
- }
- try {
- // 如果 contractAttachment 是文件ID(数字),使用 oss 方法下载
- if (/^\d+$/.test(row.contractAttachment)) {
- download.oss(row.contractAttachment);
- } else {
- // 如果是文件路径或URL,直接下载
- const link = document.createElement('a');
- link.href = row.contractAttachment;
- link.download = `合同附件_${row.contractName || row.contractNo || 'attachment'}`;
- document.body.appendChild(link);
- link.click();
- document.body.removeChild(link);
- }
- } catch (e) {
- console.error('下载附件失败:', e);
- ElMessage.error('下载附件失败');
- }
- };
- /** 查看合同 */
- const handleViewContract = async (row: any) => {
- try {
- const res = await getContract(row.id);
- Object.assign(contractForm.value, res.data);
- contractForm.value.contractAmount = yuanToWanString((res.data as any)?.contractAmount);
- contractDialogTitle.value = '查看合同';
- contractDialogReadonly.value = true;
- contractDialogVisible.value = true;
- } catch (e) {
- console.error('获取合同详情失败:', e);
- ElMessage.error('获取合同详情失败');
- }
- };
- /** 编辑合同 */
- const handleEditContract = async (row: any) => {
- try {
- const res = await getContract(row.id);
- Object.assign(contractForm.value, res.data);
- contractForm.value.contractAmount = yuanToWanString((res.data as any)?.contractAmount);
- contractDialogTitle.value = '编辑合同';
- contractDialogReadonly.value = false;
- contractDialogVisible.value = true;
- } catch (e) {
- console.error('获取合同详情失败:', e);
- ElMessage.error('获取合同详情失败');
- }
- };
- /** 获取合同类型字典 */
- const getContractTypeDict = async () => {
- try {
- const res = await getDictData('contract_type');
- contractTypeDict.value = res.data || [];
- } catch (e) {
- console.error('获取合同类型字典失败:', e);
- }
- };
- /** 获取税率列表 */
- const getTaxRateData = async () => {
- try {
- const res = await getTaxRateList();
- taxRateList.value = res.rows || res.data || [];
- } catch (e) {
- console.error('获取税率列表失败:', e);
- }
- };
- /** 获取结算方式列表 */
- const getSettlementMethodData = async () => {
- try {
- const res = await getSettlementMethodList();
- settlementMethodList.value = res.rows || res.data || [];
- } catch (e) {
- console.error('获取结算方式列表失败:', e);
- }
- };
- /** 新增合同 */
- const handleAddContract = () => {
- // 重置表单
- contractForm.value = {
- supplierNo: detailData.value.supplierNo,
- supplierId: route.query.id as any,
- contractNo: '',
- contractName: '',
- contractType: '',
- contractStartTime: '',
- contractEndTime: '',
- contractStatus: 0,
- demandReminderTime: 4,
- taxRate: undefined,
- contractAmount: undefined,
- contractDescription: '',
- contractAttachment: '',
- settlementMethod: '',
- invoiceType: ''
- };
- contractDialogTitle.value = '添加合同';
- contractDialogReadonly.value = false;
- contractDialogVisible.value = true;
- };
- /** 提交合同 */
- const handleContractSubmit = async () => {
- if (!contractFormRef.value) return;
- contractFormRef.value.validate(async (valid: boolean) => {
- if (!valid) return;
- try {
- contractSubmitLoading.value = true;
- // 设置供应商编号和ID
- if (!contractForm.value.supplierNo && detailData.value.supplierNo) {
- contractForm.value.supplierNo = detailData.value.supplierNo;
- }
- if (!contractForm.value.supplierId && route.query.id) {
- contractForm.value.supplierId = route.query.id as any;
- }
- const payload = {
- ...contractForm.value,
- contractAmount: wanToYuanString(contractForm.value.contractAmount)
- };
- if ((contractForm.value as any).id) {
- // 更新
- await updateContract(payload);
- ElMessage.success('更新成功');
- } else {
- // 新增
- await addContract(payload);
- ElMessage.success('新增成功');
- }
- contractDialogVisible.value = false;
- // 刷新合同列表
- await getContractList();
- } catch (e) {
- console.error('保存合同失败:', e);
- ElMessage.error('保存合同失败');
- } finally {
- contractSubmitLoading.value = false;
- }
- });
- };
- /** 分页大小改变 */
- const handleContractSizeChange = (size: number) => {
- contractPagination.value.pageSize = size;
- getContractList();
- };
- /** 当前页改变 */
- const handleContractCurrentChange = (page: number) => {
- contractPagination.value.pageNum = page;
- getContractList();
- };
- /** 查看付款信息 */
- const handleViewPayment = async (row: any) => {
- try {
- const res = await getBank(row.id);
- Object.assign(paymentForm.value, res.data);
- paymentDialogTitle.value = '查看付款信息';
- paymentDialogReadonly.value = true;
- paymentDialogVisible.value = true;
- } catch (e) {
- console.error('获取付款信息详情失败:', e);
- ElMessage.error('获取付款信息详情失败');
- }
- };
- /** 编辑付款信息 */
- const handleEditPayment = async (row: any) => {
- try {
- const res = await getBank(row.id);
- Object.assign(paymentForm.value, res.data);
- // 从供应商详情中获取企业工商名称和工商地址
- paymentForm.value.businessName = detailData.value.businessName || '';
- paymentForm.value.businessAddress = detailData.value.businessAddress || '';
- // 纳税人识别号使用社会信用代码
- paymentForm.value.circlesName = detailData.value.socialCreditCode || paymentForm.value.circlesName || '';
- paymentDialogTitle.value = '编辑付款信息';
- paymentDialogReadonly.value = false;
- paymentDialogVisible.value = true;
- } catch (e) {
- console.error('获取付款信息详情失败:', e);
- ElMessage.error('获取付款信息详情失败');
- }
- };
- /** 新增付款信息 */
- const handleAddPayment = () => {
- // 检查是否已保存供应商基本信息
- if (!detailData.value.id || !detailData.value.supplierNo) {
- ElMessage.warning('请先保存供应商基本信息后再新增付款信息');
- return;
- }
-
- // 重置表单
- paymentForm.value = {
- num: undefined,
- supplierNo: detailData.value.supplierNo,
- supplierId: detailData.value.id,
- bankNum: '',
- bankInfoNo: undefined,
- bankName: '',
- bankNo: '',
- isture: '1',
- circlesName: detailData.value.socialCreditCode || '',
- phone: '',
- invoiceTypeNo: undefined,
- invoiceTypeName: '',
- businessName: detailData.value.businessName || '',
- businessAddress: detailData.value.businessAddress || ''
- };
- paymentDialogTitle.value = '新增付款信息';
- paymentDialogReadonly.value = false;
- paymentDialogVisible.value = true;
- };
- /** 发票类型选择改变 */
- const handleInvoiceTypeChange = (value: string | number) => {
- const selectedInvoice = invoiceTypeList.value.find(item => item.id === value);
- if (selectedInvoice) {
- paymentForm.value.invoiceTypeNo = selectedInvoice.id;
- paymentForm.value.invoiceTypeName = selectedInvoice.invoiceTypeName;
- }
- };
- /** 银行选择改变 */
- const handleBankChange = (value: string | number) => {
- const selectedBank = systemBankList.value.find(item => item.id === value);
- if (selectedBank) {
- paymentForm.value.bankInfoNo = selectedBank.id;
- paymentForm.value.bankName = selectedBank.bnName;
- }
- };
- /** 提交付款信息 */
- const handlePaymentSubmit = async () => {
- if (!paymentFormRef.value) return;
- paymentFormRef.value.validate(async (valid: boolean) => {
- if (!valid) return;
- try {
- paymentSubmitLoading.value = true;
- // 纳税人识别号使用社会信用代码
- paymentForm.value.circlesName = detailData.value.socialCreditCode || paymentForm.value.circlesName || '';
- // 设置供应商编号和ID
- if (!paymentForm.value.supplierNo && detailData.value.supplierNo) {
- paymentForm.value.supplierNo = detailData.value.supplierNo;
- }
- if (!paymentForm.value.supplierId && detailData.value.id) {
- paymentForm.value.supplierId = detailData.value.id;
- }
- if ((paymentForm.value as any).id) {
- // 更新
- await updateBank(paymentForm.value);
- ElMessage.success('更新成功');
- } else {
- // 新增
- await addBank(paymentForm.value);
- ElMessage.success('新增成功');
- }
- paymentDialogVisible.value = false;
- // 刷新付款信息列表
- await getPaymentInfo();
- } catch (e) {
- console.error('保存付款信息失败:', e);
- ElMessage.error('保存付款信息失败');
- } finally {
- paymentSubmitLoading.value = false;
- }
- });
- };
- /** 获取地址列表 */
- const getAddressList = async () => {
- const id = route.query.id as string;
-
- // add状态不查询地址列表(新增时没有地址)
- if (!id || isAddMode.value) {
- addressList.value = [];
- return;
- }
- try {
- const res = await listAddress({
- supplierId: id, // 使用supplierId作为查询条件
- pageNum: 1,
- pageSize: 1000
- });
- addressList.value = res.data || res.rows || [];
- } catch (e) {
- console.error('获取地址列表失败:', e);
- }
- };
- /** 新增地址 */
- const handleAddAddress = () => {
- // 重置表单
- addressForm.value = {
- supplierNo: detailData.value.supplierNo,
- supplierId: detailData.value.id,
- shipperName: '',
- shipperPhone: '',
- shippingPostCode: '',
- shippingProvincial: '',
- shippingCity: '',
- shippingCounty: '',
- shippingAddress: '',
- isSelf: 0
- };
- selectedAddressRegion.value = [];
- addressDialogTitle.value = '添加地址';
- addressDialogReadonly.value = false;
- addressDialogVisible.value = true;
- };
- /** 查看地址 */
- const handleViewAddress = async (row: any) => {
- try {
- const res = await getAddress(row.id);
- Object.assign(addressForm.value, res.data);
- // 回显省市区选择器
- if (res.data.shippingProvincial && res.data.shippingCity && res.data.shippingCounty) {
- const province = res.data.shippingProvincial;
- const city = res.data.shippingCity;
- const county = res.data.shippingCounty;
- // 根据省市区名称查找对应的代码
- const provinceItem = regionOptions.value.find((p: any) => p.label === province);
- if (provinceItem) {
- const cityItem = provinceItem.children?.find((c: any) => c.label === city);
- if (cityItem) {
- const districtItem = cityItem.children?.find((d: any) => d.label === county);
- if (districtItem) {
- selectedAddressRegion.value = [provinceItem.value, cityItem.value, districtItem.value];
- }
- }
- }
- }
- addressDialogTitle.value = '查看地址';
- addressDialogReadonly.value = true;
- addressDialogVisible.value = true;
- } catch (e) {
- console.error('获取地址详情失败:', e);
- ElMessage.error('获取地址详情失败');
- }
- };
- /** 编辑地址 */
- const handleEditAddress = async (row: any) => {
- try {
- const res = await getAddress(row.id);
- Object.assign(addressForm.value, res.data);
- // 回显省市区选择器
- if (res.data.shippingProvincial && res.data.shippingCity && res.data.shippingCounty) {
- const province = res.data.shippingProvincial;
- const city = res.data.shippingCity;
- const county = res.data.shippingCounty;
- // 根据省市区名称查找对应的代码
- const provinceItem = regionOptions.value.find((p: any) => p.label === province);
- if (provinceItem) {
- const cityItem = provinceItem.children?.find((c: any) => c.label === city);
- if (cityItem) {
- const districtItem = cityItem.children?.find((d: any) => d.label === county);
- if (districtItem) {
- selectedAddressRegion.value = [provinceItem.value, cityItem.value, districtItem.value];
- }
- }
- }
- }
- addressDialogTitle.value = '编辑地址';
- addressDialogReadonly.value = false;
- addressDialogVisible.value = true;
- } catch (e) {
- console.error('获取地址详情失败:', e);
- ElMessage.error('获取地址详情失败');
- }
- };
- /** 删除地址 */
- const handleDeleteAddress = async (row: any) => {
- try {
- await ElMessageBox.confirm('确认删除该地址吗?', '提示', {
- confirmButtonText: '确认',
- cancelButtonText: '取消',
- type: 'warning'
- });
- await delAddress(row.id);
- ElMessage.success('删除成功');
-
- // 刷新地址列表
- getAddressList();
- } catch (e: any) {
- if (e !== 'cancel') {
- console.error('删除地址失败:', e);
- ElMessage.error('删除地址失败');
- }
- }
- };
- /** 地址省市区改变事件 */
- const handleAddressRegionChange = (value: string[]) => {
- if (value && value.length === 3) {
- // value 是 [省代码, 市代码, 区代码]
- const [provinceCode, cityCode, districtCode] = value;
- // 从 regionOptions 中查找对应的名称
- let provinceName = '';
- let cityName = '';
- let districtName = '';
- const province = regionOptions.value.find((p: any) => p.value === provinceCode);
- if (province) {
- provinceName = province.label;
- const city = province.children?.find((c: any) => c.value === cityCode);
- if (city) {
- cityName = city.label;
- const district = city.children?.find((d: any) => d.value === districtCode);
- if (district) {
- districtName = district.label;
- }
- }
- }
- // 更新 addressForm
- addressForm.value.shippingProvincial = provinceName;
- addressForm.value.shippingCity = cityName;
- addressForm.value.shippingCounty = districtName;
- } else {
- // 清空
- addressForm.value.shippingProvincial = '';
- addressForm.value.shippingCity = '';
- addressForm.value.shippingCounty = '';
- }
- };
- /** 提交地址 */
- const handleAddressSubmit = async () => {
- if (!addressFormRef.value) return;
- addressFormRef.value.validate(async (valid: boolean) => {
- if (!valid) return;
- try {
- addressSubmitLoading.value = true;
- // 设置供应商编号和ID
- if (!addressForm.value.supplierNo && detailData.value.supplierNo) {
- addressForm.value.supplierNo = detailData.value.supplierNo;
- }
- if (!addressForm.value.supplierId && detailData.value.id) {
- addressForm.value.supplierId = detailData.value.id;
- }
- if ((addressForm.value as any).id) {
- // 更新
- await updateAddress(addressForm.value);
- ElMessage.success('更新成功');
- } else {
- // 新增
- await addAddress(addressForm.value);
- ElMessage.success('新增成功');
- }
- addressDialogVisible.value = false;
- // 刷新地址列表
- await getAddressList();
- } catch (e) {
- console.error('保存地址失败:', e);
- ElMessage.error('保存地址失败');
- } finally {
- addressSubmitLoading.value = false;
- }
- });
- };
- onMounted(async () => {
- // 先初始化省市区数据
- initRegionOptions();
- // 初始化供货区域选项数据
- initSupplyAreaOptions();
-
- // 并行加载所有下拉框选项数据
- await Promise.all([
- getStaffOptions(),
- getCompanyOptions(), // 获取公司下拉选项
- getEnterpriseScaleOptions(), // 获取企业规模下拉选项
- getIndustryCategoryOptions(), // 获取行业类别下拉选项
- getSupplierLevelOptions(), // 获取供应商等级下拉选项
- getSupplierTypeOptions(), // 获取供应商类型下拉选项
- getContractTypeDict(), // 获取合同类型字典
- getTaxRateData(), // 获取税率列表
- getSettlementMethodData(), // 获取结算方式列表
- getInvoiceTypeData(), // 获取发票类型列表
- getAllBrandList(), // 获取所有品牌列表
- getInvoiceTypeData(), // 获取开票类型列表
- getSystemBankData() // 获取银行列表
- ]);
-
- // 下拉框选项加载完成后,再获取详情数据,确保下拉框能正确显示文字标签
- await getDetail();
- // 只有在编辑模式或基础信息已保存时才加载其他数据
- const id = route.query.id as string;
- const mode = route.query.mode as string;
- if (id && mode !== 'add') {
- getContactList();
- getProductCategories(); // 这个方法内部会调用 getSupplierSelectedCategories
- getContractList(); // 获取合同列表
- getPaymentInfo(); // 获取付款信息
- getAuthorizationList(); // 获取授权详情列表
- getAddressList(); // 获取地址列表
- getSupplyAreaList(); // 获取供货区域列表
- }
- });
- </script>
- <style scoped>
- .app-container {
- background: #f0f2f5;
- min-height: 100vh;
- padding: 0;
- }
- .detail-header {
- background: #fff;
- padding: 16px 24px;
- display: flex;
- align-items: center;
- border-bottom: 1px solid #e8e8e8;
- margin-bottom: 0;
- }
- .back-icon {
- font-size: 18px;
- cursor: pointer;
- margin-right: 12px;
- color: #666;
- }
- .back-icon:hover {
- color: #409eff;
- }
- .header-title {
- font-size: 16px;
- font-weight: 500;
- color: #333;
- }
- .detail-tabs {
- background: #fff;
- margin: 0;
- padding: 0 24px;
- margin-top: 16px;
- }
- .detail-tabs :deep(.el-tabs__header) {
- margin: 0;
- border-bottom: 1px solid #e8e8e8;
- }
- .detail-tabs :deep(.el-tabs__nav-wrap) {
- padding: 0;
- }
- .detail-tabs :deep(.el-tabs__item) {
- height: 48px;
- line-height: 48px;
- font-size: 14px;
- color: #666;
- }
- .detail-tabs :deep(.el-tabs__item.is-active) {
- color: #409eff;
- font-weight: 500;
- }
- .app-container :deep(.tab-content) {
- padding: 24px;
- background: #fff;
- }
- .app-container :deep(.info-section) {
- margin-bottom: 40px;
- }
- .app-container :deep(.section-title) {
- font-size: 15px;
- font-weight: 500;
- color: #333;
- margin-bottom: 24px;
- padding-bottom: 12px;
- border-bottom: 1px solid #e8e8e8;
- }
- .app-container :deep(.section-title-row) {
- display: flex;
- justify-content: space-between;
- align-items: center;
- margin-bottom: 24px;
- padding-bottom: 12px;
- border-bottom: 1px solid #e8e8e8;
- }
- .app-container :deep(.section-title-left) {
- display: flex;
- align-items: center;
- }
- .app-container :deep(.section-title-text) {
- font-size: 15px;
- font-weight: 500;
- color: #409eff;
- }
- .app-container :deep(.section-title-divider) {
- margin: 0 8px;
- color: #999;
- }
- .app-container :deep(.supplier-no) {
- color: #409eff;
- font-weight: normal;
- font-size: 14px;
- }
- .detail-form :deep(.el-form-item) {
- margin-bottom: 18px;
- }
- .detail-form :deep(.el-form-item__label) {
- color: #666;
- font-size: 14px;
- }
- .detail-form :deep(.el-form-item__label::before) {
- color: #f56c6c;
- }
- .app-container :deep(.form-row) {
- margin-bottom: 20px;
- }
- .app-container :deep(.form-item) {
- display: flex;
- align-items: flex-start;
- line-height: 32px;
- font-size: 14px;
- }
- .app-container :deep(.form-item .label) {
- color: #666;
- min-width: 100px;
- flex-shrink: 0;
- }
- .app-container :deep(.form-item .value) {
- color: #333;
- flex: 1;
- word-break: break-all;
- }
- .app-container :deep(.category-group) {
- display: flex;
- flex-wrap: wrap;
- gap: 16px;
- }
- .app-container :deep(.category-group .el-checkbox) {
- margin-right: 0;
- margin-bottom: 12px;
- }
- .app-container :deep(.supply-brand) {
- font-size: 14px;
- color: #333;
- padding: 8px 0;
- }
- .app-container :deep(.brand-input-wrapper) {
- margin-top: 12px;
- }
- .app-container :deep(.brand-dialog .el-dialog__header) {
- padding: 16px 20px 12px;
- border-bottom: 1px solid #ebeef5;
- }
- .app-container :deep(.brand-dialog .el-dialog__title) {
- font-size: 16px;
- font-weight: 600;
- color: #303133;
- }
- .app-container :deep(.brand-dialog .el-dialog__body) {
- padding: 16px 20px 18px;
- }
- .app-container :deep(.brand-dialog__search) {
- padding: 12px 12px 8px;
- background: #f7f9fc;
- border: 1px solid #ebeef5;
- border-radius: 10px;
- margin-bottom: 14px;
- }
- .app-container :deep(.brand-dialog__search .el-input__wrapper) {
- border-radius: 8px;
- }
- .app-container :deep(.brand-search-results) {
- border-radius: 10px;
- border: 1px solid #ebeef5;
- box-shadow: 0 2px 10px rgba(0, 0, 0, 0.04);
- }
- .app-container :deep(.brand-display-wrapper) {
- margin-top: 12px;
- min-height: 40px;
- padding: 8px;
- background: #f5f7fa;
- border-radius: 4px;
- }
- .app-container :deep(.brand-tags-container) {
- min-height: 80px;
- padding: 16px;
- background: #f5f7fa;
- border-radius: 4px;
- border: 1px solid #e4e7ed;
- }
- .app-container :deep(.brand-search-results) {
- max-height: 300px;
- overflow-y: auto;
- margin-bottom: 20px;
- border: 1px solid #e4e7ed;
- border-radius: 4px;
- }
- .app-container :deep(.search-results-title) {
- padding: 10px 16px;
- background: #f7f9fc;
- font-weight: 500;
- font-size: 14px;
- color: #606266;
- border-bottom: 1px solid #ebeef5;
- }
- .app-container :deep(.brand-result-item) {
- padding: 12px 16px;
- cursor: pointer;
- display: flex;
- justify-content: space-between;
- align-items: center;
- border-bottom: 1px solid #f2f4f7;
- transition: background-color 0.2s;
- }
- .app-container :deep(.brand-result-item:hover) {
- background-color: #f7f9fc;
- }
- .app-container :deep(.brand-result-item:active) {
- background-color: #eef5ff;
- }
- .app-container :deep(.brand-result-item:last-child) {
- border-bottom: none;
- }
- .app-container :deep(.brand-result-name) {
- font-size: 14px;
- color: #303133;
- font-weight: 500;
- }
- .app-container :deep(.brand-result-no) {
- font-size: 12px;
- color: #909399;
- }
- .app-container :deep(.selected-brands-section) {
- margin-top: 20px;
- }
- .app-container :deep(.section-label) {
- font-size: 14px;
- color: #606266;
- margin-bottom: 12px;
- font-weight: 500;
- }
- .app-container :deep(.brand-tags-container) {
- background: #fff;
- border: 1px dashed #dcdfe6;
- border-radius: 10px;
- min-height: 64px;
- padding: 12px;
- }
- .app-container :deep(.brand-tags-container .el-tag) {
- border-radius: 8px;
- }
- .app-container :deep(.image-upload) {
- display: inline-block;
- margin-left: 10px;
- }
- .app-container :deep(.upload-placeholder) {
- width: 100px;
- height: 100px;
- border: 1px dashed #d9d9d9;
- border-radius: 4px;
- display: flex;
- align-items: center;
- justify-content: center;
- cursor: pointer;
- color: #999;
- font-size: 24px;
- }
- .app-container :deep(.upload-placeholder:hover) {
- border-color: #409eff;
- color: #409eff;
- }
- </style>
|