index.vue 90 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438
  1. <template xmlns:el-col="http://www.w3.org/1999/html">
  2. <div class="app-container">
  3. <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
  4. <el-form-item label="提醒状态">
  5. <el-button
  6. size="mini"
  7. type="danger"
  8. @click="handleRemindFilter('overdue')"
  9. >
  10. 逾期
  11. </el-button>
  12. <el-button
  13. size="mini"
  14. type="warning"
  15. @click="handleRemindFilter('urgent')"
  16. >
  17. 7天内到期
  18. </el-button>
  19. <el-button
  20. size="mini"
  21. type="primary"
  22. @click="handleRemindFilter('important')"
  23. >
  24. 15天内到期
  25. </el-button>
  26. <el-button
  27. size="mini"
  28. @click="handleRemindFilter('warnin')"
  29. >
  30. 30天内到期
  31. </el-button>
  32. </el-form-item>
  33. <el-form-item label="店铺名称" prop="storeName">
  34. <el-input
  35. v-model="queryParams.storeName"
  36. placeholder="请输入店铺名称"
  37. clearable
  38. size="small"
  39. @keyup.enter.native="handleQuery"
  40. />
  41. </el-form-item>
  42. <el-form-item label="地址" prop="address">
  43. <el-input
  44. v-model="queryParams.address"
  45. placeholder="请输入地址"
  46. clearable
  47. size="small"
  48. @keyup.enter.native="handleQuery"
  49. />
  50. </el-form-item>
  51. <el-form-item label="店铺电话" prop="phone">
  52. <el-input
  53. v-model="queryParams.phone"
  54. placeholder="请输入店铺电话"
  55. clearable
  56. size="small"
  57. @keyup.enter.native="handleQuery"
  58. />
  59. </el-form-item>
  60. <el-form-item label="状态" prop="status">
  61. <el-select v-model="queryParams.status" placeholder="请选择状态" clearable size="small">
  62. <el-option
  63. v-for="dict in statusOptions"
  64. :key="dict.dictValue"
  65. :label="dict.dictLabel"
  66. :value="dict.dictValue"
  67. />
  68. </el-select>
  69. </el-form-item>
  70. <el-form-item label="审核状态" prop="isAudit">
  71. <el-select v-model="queryParams.isAudit" placeholder="请选择审核状态" clearable size="small">
  72. <el-option
  73. v-for="dict in isAuditOptions"
  74. :key="dict.dictValue"
  75. :label="dict.dictLabel"
  76. :value="dict.dictValue"
  77. />
  78. </el-select>
  79. </el-form-item>
  80. <el-form-item label="登录帐号" prop="account">
  81. <el-input
  82. v-model="queryParams.account"
  83. placeholder="请输入登录帐号"
  84. clearable
  85. size="small"
  86. @keyup.enter.native="handleQuery"
  87. />
  88. </el-form-item>
  89. <el-form-item label="店铺Id" prop="storeSeq">
  90. <el-input
  91. v-model="queryParams.storeSeq"
  92. placeholder="请输入店铺Id"
  93. clearable
  94. size="small"
  95. @keyup.enter.native="handleQuery"
  96. />
  97. </el-form-item>
  98. <el-form-item label="商家Id" prop="merchantId">
  99. <el-input
  100. v-model="queryParams.merchantId"
  101. placeholder="请输入商家Id"
  102. clearable
  103. size="small"
  104. @keyup.enter.native="handleQuery"
  105. />
  106. </el-form-item>
  107. <el-form-item>
  108. <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
  109. <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
  110. </el-form-item>
  111. </el-form>
  112. <el-row :gutter="10" class="mb8">
  113. <el-col :span="1.5">
  114. <el-button
  115. type="primary"
  116. plain
  117. icon="el-icon-plus"
  118. size="mini"
  119. @click="handleAdd"
  120. v-hasPermi="['his:store:add']"
  121. >新增</el-button>
  122. </el-col>
  123. <el-col :span="1.5">
  124. <el-button
  125. type="success"
  126. plain
  127. icon="el-icon-edit"
  128. size="mini"
  129. :disabled="single"
  130. @click="handleUpdate"
  131. v-hasPermi="['his:store:edit']"
  132. >修改</el-button>
  133. </el-col>
  134. <el-col :span="1.5">
  135. <el-button
  136. type="danger"
  137. plain
  138. icon="el-icon-delete"
  139. size="mini"
  140. :disabled="multiple"
  141. @click="handleDelete"
  142. v-hasPermi="['his:store:remove']"
  143. >删除</el-button>
  144. </el-col>
  145. <el-col :span="1.5">
  146. <el-button
  147. type="warning"
  148. plain
  149. icon="el-icon-download"
  150. size="mini"
  151. :loading="exportLoading"
  152. @click="handleExport"
  153. v-hasPermi="['his:store:export']"
  154. >导出</el-button>
  155. </el-col>
  156. <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
  157. </el-row>
  158. <el-table v-loading="loading" border :data="storeList" @selection-change="handleSelectionChange">
  159. <el-table-column type="selection" width="55" align="center" />
  160. <!-- <el-table-column label="店铺id" align="center" prop="storeId" width="120px"/>-->
  161. <el-table-column label="商家ID" align="center" prop="merchantId" width="150px"/>
  162. <el-table-column label="店铺ID" align="center" prop="storeSeq" width="150px"/>
  163. <el-table-column label="店铺名称" align="center" prop="storeName" width="120px"/>
  164. <el-table-column label="机构全称" align="center" prop="fullName" width="120px"/>
  165. <el-table-column label="店铺LOGO" align="center" prop="logoUrl" width="100px">
  166. <template slot-scope="scope">
  167. <el-popover
  168. placement="right"
  169. title=""
  170. trigger="hover">
  171. <img slot="reference" :src="scope.row.logoUrl" width="80px" height="80px">
  172. <img :src="scope.row.logoUrl" style="max-width: 160px;">
  173. </el-popover>
  174. </template>
  175. </el-table-column>
  176. <el-table-column label="地址" align="center" prop="address" width="200px"/>
  177. <el-table-column label="店铺电话" align="center" prop="phone" width="120px"/>
  178. <el-table-column label="审核状态" align="center" prop="isAudit">
  179. <template slot-scope="scope">
  180. <dict-tag :options="isAuditOptions" :value="scope.row.isAudit"/>
  181. </template>
  182. </el-table-column>
  183. <el-table-column label="商品总数" align="center" prop="productCount" />
  184. <el-table-column label="状态" align="center" prop="status">
  185. <template slot-scope="scope">
  186. <dict-tag :options="statusOptions" :value="scope.row.status"/>
  187. </template>
  188. </el-table-column>
  189. <el-table-column label="销量" align="center" prop="salesCount" />
  190. <el-table-column label="余额" align="center" prop="balance" />
  191. <el-table-column label="累计金额" align="center" prop="totalMoney" />
  192. <el-table-column label="登录帐号" align="center" prop="account" width="150px" />
  193. <el-table-column label="上次审核日期" align="center" prop="qualificationUpdateTime" width="150px" />
  194. <el-table-column label="下次到期日" align="center" prop="nextQualificationUpdateTime" width="150px" />
  195. <el-table-column label="剩余天数" align="center" prop="daysDiff" width="150px" />
  196. <el-table-column label="提醒状态(标签)" align="center" prop="daysDiff" width="150px">
  197. <template slot-scope="scope">
  198. <el-tag
  199. v-if="scope.row.daysDiff !== null"
  200. :type="getRemindTagType(scope.row.daysDiff)"
  201. size="small"
  202. >
  203. {{ getRemindTagName(scope.row.daysDiff) }}
  204. </el-tag>
  205. <span v-else>-</span>
  206. </template>
  207. </el-table-column>
  208. <el-table-column label="创建时间" align="center" prop="createTime" width="150px"/>
  209. <el-table-column label="操作" align="center" class-name="small-padding fixed-width" fixed="right" width="300px">
  210. <template slot-scope="scope">
  211. <el-button
  212. size="mini"
  213. type="text"
  214. icon="el-icon-edit"
  215. @click="handleUpdate(scope.row, true)"
  216. v-hasPermi="['his:store:edit']"
  217. >修改</el-button>
  218. <el-button
  219. size="mini"
  220. type="text"
  221. icon="el-icon-s-promotion"
  222. @click="handleUpdate(scope.row, false)"
  223. >详情
  224. </el-button>
  225. <el-button
  226. size="mini"
  227. type="text"
  228. icon="el-icon-delete"
  229. @click="handleDelete(scope.row)"
  230. v-hasPermi="['his:store:remove']"
  231. >删除</el-button>
  232. <el-button
  233. size="mini"
  234. type="text"
  235. icon="el-icon-refresh"
  236. @click="handleRefresh(scope.row)"
  237. v-hasPermi="['his:store:refresh']"
  238. >重置密码</el-button>
  239. <el-button
  240. size="mini"
  241. type="text"
  242. icon="el-icon-s-promotion"
  243. @click="handleStoreExport(scope.row)"
  244. >导出
  245. </el-button>
  246. </template>
  247. </el-table-column>
  248. </el-table>
  249. <pagination
  250. v-show="total>0"
  251. :total="total"
  252. :page.sync="queryParams.pageNum"
  253. :limit.sync="queryParams.pageSize"
  254. @pagination="getList"
  255. />
  256. <!-- 添加或修改店铺管理对话框 -->
  257. <el-dialog :title="title" :visible.sync="open" width="800px" append-to-body :close-on-click-modal="false">
  258. <el-form ref="form" :model="form" :rules="rules" label-width="120px" label-position="top" :disabled="isViewMode">
  259. <el-divider content-position="left">基础信息</el-divider>
  260. <el-row>
  261. <el-col :span="12">
  262. <el-form-item label="店铺名称" prop="storeName">
  263. <el-input v-model="form.storeName" placeholder="请输入店铺名称" />
  264. </el-form-item>
  265. </el-col>
  266. <el-col :span="12">
  267. <el-form-item label="电话" prop="phone">
  268. <el-input v-model="form.phone" placeholder="请输入店铺电话" />
  269. </el-form-item>
  270. </el-col>
  271. </el-row>
  272. <el-form-item label="企业全称" prop="fullName">
  273. <el-input v-model="form.fullName" placeholder="请输入企业全称" />
  274. </el-form-item>
  275. <el-row>
  276. <el-col :span="12">
  277. <el-form-item label="店铺LOGO" prop="logoUrl">
  278. <el-upload
  279. v-model="form.logoUrl"
  280. class="avatar-uploader"
  281. :action="uploadUrl"
  282. :show-file-list="false"
  283. :on-success="handleAvatarSuccess"
  284. :before-upload="beforeAvatarUpload"
  285. :disabled="isDeleting"
  286. >
  287. <!-- 图片容器(包含图片和删除按钮,仅在有图片时显示) -->
  288. <div class="avatar-wrapper" v-if="form.logoUrl">
  289. <img :src="form.logoUrl" class="avatar" width="200px">
  290. <!-- 显示删除还是显示放大是更具编辑或者详情来的 -->
  291. <!-- <div v-if="isViewMode" class="view-mask" @click.stop="previewImage(form.logoUrl)">-->
  292. <!-- <i class="el-icon-zoom-in"></i>-->
  293. <!-- </div>-->
  294. <!-- <div v-else class="delete-mask" @click.stop="handleDeleteLogo">-->
  295. <!-- <i class="el-icon-delete"></i>-->
  296. <!-- </div>-->
  297. <!-- 并排显示就好了-->
  298. <div class="button-group">
  299. <div class="preview-btn" @click.stop="previewImage(form.logoUrl)">
  300. <i class="el-icon-zoom-in"></i>
  301. </div>
  302. <div v-if="!isViewMode" class="delete-btn" @click.stop="handleDeleteLogo">
  303. <i class="el-icon-delete"></i>
  304. </div>
  305. </div>
  306. </div>
  307. <!-- 未上传图片时显示的默认图标 -->
  308. <i v-else class="el-icon-plus avatar-uploader-icon"></i>
  309. </el-upload>
  310. </el-form-item>
  311. </el-col>
  312. <el-col :span="12"></el-col>
  313. <el-col :span="12">
  314. </el-col>
  315. </el-row>
  316. <el-row>
  317. <el-col :span="24">
  318. <el-form-item label="店铺介绍" prop="descs" >
  319. <el-input v-model="form.descs" placeholder="请输入店铺介绍" type="textarea" maxlength="100"/>
  320. </el-form-item>
  321. </el-col>
  322. </el-row>
  323. <el-row>
  324. <el-col :span="12">
  325. <el-form-item label="所属城市" prop="cityIds">
  326. <el-cascader
  327. ref="citySelect"
  328. v-model="form.cityIds"
  329. :options="citys"
  330. @change="handleCityChange">
  331. </el-cascader>
  332. </el-form-item>
  333. </el-col>
  334. <el-col :span="12">
  335. <el-form-item label="地址" prop="address">
  336. <el-input v-model="form.address" placeholder="请输入地址"/>
  337. </el-form-item>
  338. </el-col>
  339. </el-row>
  340. <el-row>
  341. <el-col :span="12">
  342. <el-form-item label="法人姓名" prop="legalPersonName">
  343. <el-input v-model="form.legalPersonName" placeholder="请输入法人姓名" />
  344. </el-form-item>
  345. </el-col>
  346. <el-col :span="12">
  347. <el-form-item label="统一社会信用代码" prop="unifiedSocialCreditCode">
  348. <el-input v-model="form.unifiedSocialCreditCode" placeholder="请输入统一社会信用代码" />
  349. </el-form-item>
  350. </el-col>
  351. </el-row>
  352. <el-form-item label="营业范围" prop="businessScope">
  353. <el-input v-model="form.businessScope" placeholder="请输入营业范围" type="textarea" />
  354. </el-form-item>
  355. <!-- 证书上传相关字段 -->
  356. <el-divider content-position="left">资质证书信息</el-divider>
  357. <el-row>
  358. <el-col :span="12">
  359. <el-form-item label="营业执照上传" prop="businessLicense">
  360. <el-upload
  361. class="avatar-uploader"
  362. :action="uploadUrl"
  363. :show-file-list="false"
  364. :on-success="(response, file) => handleFileSuccess(response, file, 'businessLicense')"
  365. :before-upload="beforeAvatarUpload"
  366. :disabled="isDeleting"
  367. >
  368. <!-- 图片容器(包含图片和删除按钮,仅在有图片时显示) -->
  369. <div class="avatar-wrapper" v-if="form.businessLicense">
  370. <img :src="form.businessLicense" class="avatar" width="200px">
  371. <!-- 悬停显示的删除按钮 -->
  372. <!-- <div class="delete-mask" @click.stop="handleDelete5">-->
  373. <!-- <i class="el-icon-delete"></i>-->
  374. <!-- </div>-->
  375. <div class="button-group">
  376. <div class="preview-btn" @click.stop="previewImage(form.businessLicense)">
  377. <i class="el-icon-zoom-in"></i>
  378. </div>
  379. <div v-if="!isViewMode" class="delete-btn" @click.stop="handleDelete5">
  380. <i class="el-icon-delete"></i>
  381. </div>
  382. </div>
  383. </div>
  384. <!-- 未上传图片时显示的默认图标 -->
  385. <div v-else class="no-image-placeholder">
  386. <span v-if="isViewMode">用户未上传</span>
  387. <i v-else class="el-icon-plus avatar-uploader-icon"></i>
  388. </div>
  389. </el-upload>
  390. </el-form-item>
  391. <el-col :span="12">
  392. <el-form-item label="营业执照编号" prop="businessCode" style="margin-left: 5px;margin-bottom: 20px">
  393. <el-input v-model="form.businessCode" placeholder="请输入营业制造编号" />
  394. </el-form-item>
  395. </el-col>
  396. </el-col>
  397. <el-col :span="12"></el-col>
  398. <el-col :span="12">
  399. <el-form-item label="营业执照是否长期有效" prop="isBusinessLicensePermanent">
  400. <el-switch
  401. @change="switchChange()"
  402. v-model="switchValue"
  403. active-color="#13ce66"
  404. inactive-color="#ff4949">
  405. </el-switch>
  406. </el-form-item>
  407. <el-form-item label="营业执照失效日期" prop="businessLicenseExpire" v-if="!switchValue">
  408. <el-date-picker
  409. v-model="form.businessLicenseExpire"
  410. type="daterange"
  411. value-format="yyyy-MM-dd"
  412. range-separator="至"
  413. start-placeholder="开始日期"
  414. end-placeholder="结束日期">
  415. </el-date-picker>
  416. </el-form-item>
  417. </el-col>
  418. </el-row>
  419. <div v-if="medicalMallConfig.isMedicalMall">
  420. <el-row>
  421. <el-col :span="12">
  422. <el-form-item label="药品经营许可证上传" prop="drugLicense">
  423. <el-upload
  424. class="avatar-uploader"
  425. :action="uploadUrl"
  426. :show-file-list="false"
  427. :on-success="(response, file) => handleFileSuccess(response, file, 'drugLicense')"
  428. :before-upload="beforeAvatarUpload"
  429. :disabled="isDeleting"
  430. >
  431. <!-- 图片容器(包含图片和删除按钮,仅在有图片时显示) -->
  432. <div class="avatar-wrapper" v-if="form.drugLicense">
  433. <img :src="form.drugLicense" class="avatar" width="200px">
  434. <!-- 悬停显示的删除按钮 -->
  435. <!-- <div class="delete-mask" @click.stop="handleDelete6">-->
  436. <!-- <i class="el-icon-delete"></i>-->
  437. <!-- </div>-->
  438. <div class="button-group">
  439. <div class="preview-btn" @click.stop="previewImage(form.drugLicense)">
  440. <i class="el-icon-zoom-in"></i>
  441. </div>
  442. <div v-if="!isViewMode" class="delete-btn" @click.stop="handleDelete6">
  443. <i class="el-icon-delete"></i>
  444. </div>
  445. </div>
  446. </div>
  447. <!-- 未上传图片时显示的默认图标 -->
  448. <div v-else class="no-image-placeholder">
  449. <span v-if="isViewMode">用户未上传</span>
  450. <i v-else class="el-icon-plus avatar-uploader-icon"></i>
  451. </div>
  452. </el-upload>
  453. </el-form-item>
  454. <el-col :sapn="24">
  455. <el-form-item label="药品经营许可证范围" prop="drugLicenseBusinessScope" style="margin-left: 5px">
  456. <el-input v-model="form.drugLicenseBusinessScope" placeholder="请输入药品经营许可证范围" type="textarea"/>
  457. </el-form-item>
  458. </el-col>
  459. <!-- 新增的单选框 -->
  460. <el-col :span="24">
  461. <el-form-item label="药品经营许可证范围是否包含" prop="drugScopeHasFrozen" style="margin-left: 5px">
  462. <el-radio-group v-model="form.drugScopeHasFrozen">
  463. <el-radio label="0">否</el-radio>
  464. <el-radio label="1">冷冻</el-radio>
  465. <el-radio label="2">冷藏</el-radio>
  466. <el-radio label="3">冷冻冷藏</el-radio>
  467. </el-radio-group>
  468. </el-form-item>
  469. </el-col>
  470. <!-- 结束 -->
  471. <el-col :span="14">
  472. <el-form-item label="药品经营许可证编号" prop="drugCode" style="margin-left: 5px">
  473. <el-input v-model="form.drugCode" placeholder="请输入药品经营许可证编号" />
  474. </el-form-item>
  475. </el-col>
  476. </el-col>
  477. <el-col :span="12">
  478. <el-form-item label="药品经营许可证有效期" prop="drugLicenseExpiry">
  479. <el-date-picker
  480. v-model="form.drugLicenseExpiry"
  481. type="daterange"
  482. value-format="yyyy-MM-dd"
  483. range-separator="至"
  484. start-placeholder="开始日期"
  485. end-placeholder="结束日期">
  486. </el-date-picker>
  487. </el-form-item>
  488. </el-col>
  489. </el-row>
  490. <el-row>
  491. <el-col :span="12">
  492. <el-form-item label="2类医疗器械备案证书上传" prop="medicalDevice2">
  493. <el-upload
  494. class="avatar-uploader"
  495. :action="uploadUrl"
  496. :show-file-list="false"
  497. :on-success="(response, file) => handleFileSuccess(response, file, 'medicalDevice2')"
  498. :before-upload="beforeAvatarUpload"
  499. :disabled="isDeleting"
  500. >
  501. <!-- 图片容器(包含图片和删除按钮,仅在有图片时显示) -->
  502. <div class="avatar-wrapper" v-if="form.medicalDevice2">
  503. <img :src="form.medicalDevice2" class="avatar" width="200px">
  504. <!-- 悬停显示的删除按钮 -->
  505. <!-- <div class="delete-mask" @click.stop="handleDelete7">-->
  506. <!-- <i class="el-icon-delete"></i>-->
  507. <!-- </div>-->
  508. <div class="button-group">
  509. <div class="preview-btn" @click.stop="previewImage(form.medicalDevice2)">
  510. <i class="el-icon-zoom-in"></i>
  511. </div>
  512. <div v-if="!isViewMode" class="delete-btn" @click.stop="handleDelete7">
  513. <i class="el-icon-delete"></i>
  514. </div>
  515. </div>
  516. </div>
  517. <!-- 未上传图片时显示的默认图标 -->
  518. <div v-else class="no-image-placeholder">
  519. <span v-if="isViewMode">用户未上传</span>
  520. <i v-else class="el-icon-plus avatar-uploader-icon"></i>
  521. </div>
  522. </el-upload>
  523. </el-form-item>
  524. <el-col :sapn="24">
  525. <el-form-item label="2类器械经营范围" prop="medicalDevice2BusinessScope" style="margin-left: 5px">
  526. <el-input v-model="form.medicalDevice2BusinessScope" placeholder="请输入2类器械经营范围" type="textarea"/>
  527. </el-form-item>
  528. </el-col>
  529. <el-col :span="14">
  530. <el-form-item label="2类器械生产备案编号" prop="medicalDevice2Code" style="margin-left: 5px">
  531. <el-input v-model="form.medicalDevice2Code" placeholder="请输入2类器械生产备案编号" />
  532. </el-form-item>
  533. </el-col>
  534. </el-col>
  535. <el-col :span="12"></el-col>
  536. <el-col :span="12">
  537. <el-form-item label="2类医疗器械备案是否长期有效" prop="isMedicalDevice2ExpiryPermanent">
  538. <el-switch
  539. @change="switchChange()"
  540. v-model="medicalDevice2ExpiryValue"
  541. active-color="#13ce66"
  542. inactive-color="#ff4949">
  543. </el-switch>
  544. </el-form-item>
  545. <el-form-item label="2类医疗器械备案有效期" prop="medicalDevice2Expiry" v-if="!medicalDevice2ExpiryValue">
  546. <el-date-picker
  547. v-model="form.medicalDevice2Expiry"
  548. type="daterange"
  549. value-format="yyyy-MM-dd"
  550. range-separator="至"
  551. start-placeholder="开始日期"
  552. end-placeholder="结束日期">
  553. </el-date-picker>
  554. </el-form-item>
  555. </el-col>
  556. </el-row>
  557. <el-row>
  558. <el-col :span="12">
  559. <el-form-item label="3类器械经营许可证上传" prop="medicalDevice3">
  560. <el-upload
  561. class="avatar-uploader"
  562. :action="uploadUrl"
  563. :show-file-list="false"
  564. :on-success="(response, file) => handleFileSuccess(response, file, 'medicalDevice3')"
  565. :before-upload="beforeAvatarUpload"
  566. :disabled="isDeleting"
  567. >
  568. <!-- 图片容器(包含图片和删除按钮,仅在有图片时显示) -->
  569. <div class="avatar-wrapper" v-if="form.medicalDevice3">
  570. <img :src="form.medicalDevice3" class="avatar" width="200px">
  571. <!-- 悬停显示的删除按钮 -->
  572. <!-- <div class="delete-mask" @click.stop="handleDelete2">-->
  573. <!-- <i class="el-icon-delete"></i>-->
  574. <!-- </div>-->
  575. <div class="button-group">
  576. <div class="preview-btn" @click.stop="previewImage(form.medicalDevice3)">
  577. <i class="el-icon-zoom-in"></i>
  578. </div>
  579. <div v-if="!isViewMode" class="delete-btn" @click.stop="handleDelete2">
  580. <i class="el-icon-delete"></i>
  581. </div>
  582. </div>
  583. </div>
  584. <!-- 未上传图片时显示的默认图标 -->
  585. <div v-else class="no-image-placeholder">
  586. <span v-if="isViewMode">用户未上传</span>
  587. <i v-else class="el-icon-plus avatar-uploader-icon"></i>
  588. </div>
  589. </el-upload>
  590. </el-form-item>
  591. <el-col :sapn="24">
  592. <el-form-item label="3类器械经营范围" prop="medicalDevice3BusinessScope" style="margin-left: 5px">
  593. <el-input v-model="form.medicalDevice3BusinessScope" placeholder="请输入3类器械经营范围" type="textarea"/>
  594. </el-form-item>
  595. </el-col>
  596. <el-form-item label="3类器械生产备案编号" prop="medicalDevice3Code" style="margin-left: 5px">
  597. <el-input v-model="form.medicalDevice3Code" placeholder="请输入3类器械生产备案编号" />
  598. </el-form-item>
  599. </el-col>
  600. <el-col :span="12"></el-col>
  601. <el-col :span="12">
  602. <el-form-item label="3类器械经营许可证有效期" prop="medicalDevice3Expiry">
  603. <el-date-picker
  604. v-model="form.medicalDevice3Expiry"
  605. type="daterange"
  606. value-format="yyyy-MM-dd"
  607. range-separator="至"
  608. start-placeholder="开始日期"
  609. end-placeholder="结束日期">
  610. </el-date-picker>
  611. </el-form-item>
  612. </el-col>
  613. </el-row>
  614. <el-row>
  615. <el-col :span="24">
  616. <el-form-item label="食品经营许可证/备案凭证上传" prop="foodLicense">
  617. <el-upload
  618. class="avatar-uploader"
  619. :action="uploadUrl"
  620. :show-file-list="false"
  621. :on-success="(response, file) => handleFoodLicenseSuccess(response, file)"
  622. :before-upload="beforeAvatarUpload"
  623. :disabled="isDeleting"
  624. :limit="3"
  625. :on-exceed="handleFoodLicenseExceed"
  626. >
  627. <!-- 图片容器(包含图片和删除按钮,仅在有图片时显示) -->
  628. <div v-if="form.foodLicense && form.foodLicense.length > 0" class="food-license-container">
  629. <div v-for="(url, index) in form.foodLicense" :key="index" class="food-license-item">
  630. <div class="avatar-wrapper">
  631. <img :src="url" class="avatar small-avatar" />
  632. <div class="button-group">
  633. <div class="preview-btn" @click.stop="previewImage(url)">
  634. <i class="el-icon-zoom-in"></i>
  635. </div>
  636. <div v-if="!isViewMode" class="delete-btn" @click.stop="handleDeleteFoodLicense(index)">
  637. <i class="el-icon-delete"></i>
  638. </div>
  639. </div>
  640. </div>
  641. </div>
  642. <!-- 添加上传按钮,当图片数量少于3张时显示 -->
  643. <div v-if="form.foodLicense.length < 3 && !isViewMode" class="avatar-wrapper add-btn small-avatar">
  644. <i class="el-icon-plus avatar-uploader-icon"></i>
  645. </div>
  646. </div>
  647. <!-- 未上传图片时显示的默认图标 -->
  648. <div v-else class="no-image-placeholder small-placeholder">
  649. <span v-if="isViewMode">用户未上传</span>
  650. <i v-else class="el-icon-plus avatar-uploader-icon"></i>
  651. </div>
  652. </el-upload>
  653. </el-form-item>
  654. <el-form-item label="食品经营许可证/备案凭证编号" prop="foodCode" style="margin-left: 5px">
  655. <el-input v-model="form.foodCode" placeholder="请输入食品经营许可证/备案凭证编号" />
  656. </el-form-item>
  657. </el-col>
  658. <el-col :span="12"></el-col>
  659. <el-col :span="12">
  660. <el-form-item label="食品经营许可证/备案凭证是否长期有效" prop="isFoodLicenseExpiryPermanent">
  661. <el-switch
  662. @change="switchChange()"
  663. v-model="foodLicenseExpiryValue"
  664. active-color="#13ce66"
  665. inactive-color="#ff4949">
  666. </el-switch>
  667. </el-form-item>
  668. <el-form-item label="食品经营许可证/备案凭证有效期" prop="foodLicenseExpiry" v-if="!foodLicenseExpiryValue">
  669. <el-date-picker
  670. v-model="form.foodLicenseExpiry"
  671. type="daterange"
  672. value-format="yyyy-MM-dd"
  673. range-separator="至"
  674. start-placeholder="开始日期"
  675. end-placeholder="结束日期">
  676. </el-date-picker>
  677. </el-form-item>
  678. </el-col>
  679. <el-col :sapn="24">
  680. <el-form-item label="食品经营许可证/备案凭证经营范围" prop="foodLicenseBusinessScope">
  681. <el-input v-model="form.foodLicenseBusinessScope" placeholder="请输入食品经营许可证/备案凭证经营范围" type="textarea"/>
  682. </el-form-item>
  683. </el-col>
  684. </el-row>
  685. </div>
  686. <div v-hasPermi="['his:store:AgreementSigned']">
  687. <el-divider content-position="left">签署协议与特殊资质信息</el-divider>
  688. <el-row :gutter="20">
  689. <el-col :span="8">
  690. <div class="agreement-section">
  691. <el-form-item label="其它资质-入驻协议">
  692. <el-input
  693. v-model="form.titleNameOne"
  694. placeholder="请输入标题"
  695. class="agreement-title"
  696. />
  697. <el-upload
  698. class="file-uploader"
  699. :action="uploadUrl"
  700. :show-file-list="false"
  701. :on-success="(response, file) => handleFileSuccess1(response, file, 'settlementAgreement')"
  702. :on-error="handleFileError"
  703. :before-upload="beforeFileUpload"
  704. :disabled="!!form.settlementAgreement"
  705. accept=".jpg,.jpeg,.png,.gif,.doc,.docx,.pdf"
  706. >
  707. <div v-if="form.settlementAgreement" class="uploaded-file">
  708. <img
  709. v-if="isImageFile(form.settlementAgreement, 'settlementAgreement')"
  710. :src="form.settlementAgreement"
  711. class="uploaded-img"
  712. width="100px"
  713. />
  714. <div v-else class="document-icon">
  715. <i :class="getDocumentIconClass(form.settlementAgreement, 'settlementAgreement')" class="icon"></i>
  716. <span class="file-name">{{ form.settlementAgreementFileName || getFileName(form.settlementAgreement) }}</span>
  717. </div>
  718. <i class="el-icon-delete delete-icon" @click.stop="handleFileRemove('settlementAgreement')"></i>
  719. </div>
  720. <div v-else class="upload-btn">
  721. <div class="upload-btn-inner">
  722. <i class="el-icon-plus"></i>
  723. <span class="upload-tip">点击上传</span>
  724. </div>
  725. </div>
  726. </el-upload>
  727. <el-form-item prop="settlementAgreementCode">
  728. <el-input
  729. v-model="form.settlementAgreementCode"
  730. placeholder="请输入备注内容"
  731. />
  732. </el-form-item>
  733. <el-form-item label="协议是否长期有效" prop="isEffectivePermanent1">
  734. <el-switch
  735. @change="switchChange()"
  736. v-model="medicalLicenseExpiryValue1"
  737. active-color="#13ce66"
  738. inactive-color="#ff4949">
  739. </el-switch>
  740. </el-form-item>
  741. <el-form-item
  742. label="协议有效期"
  743. prop="medicalLicenseExpiry"
  744. v-if="!medicalLicenseExpiryValue1"
  745. >
  746. <el-date-picker
  747. v-model="form.settlementAgreementExpiry"
  748. type="daterange"
  749. value-format="yyyy-MM-dd"
  750. range-separator="至"
  751. start-placeholder="开始日期"
  752. end-placeholder="结束日期" style="width: 100%">
  753. </el-date-picker>
  754. </el-form-item>
  755. </el-form-item>
  756. </div>
  757. </el-col>
  758. <el-col :span="8">
  759. <div class="agreement-section">
  760. <el-form-item label="质量保证协议">
  761. <el-input
  762. v-model="form.titleNameTwo"
  763. placeholder="请输入标题"
  764. class="agreement-title"
  765. />
  766. <el-upload
  767. class="file-uploader"
  768. :action="uploadUrl"
  769. :show-file-list="false"
  770. :on-success="(response, file) => handleFileSuccess1(response, file, 'qualityAssuranceAgreement')"
  771. :on-error="handleFileError"
  772. :before-upload="beforeFileUpload"
  773. :disabled="!!form.qualityAssuranceAgreement"
  774. accept=".jpg,.jpeg,.png,.gif,.doc,.docx,.pdf"
  775. >
  776. <div v-if="form.qualityAssuranceAgreement" class="uploaded-file">
  777. <img
  778. v-if="isImageFile(form.qualityAssuranceAgreement, 'qualityAssuranceAgreement')"
  779. :src="form.qualityAssuranceAgreement"
  780. class="uploaded-img"
  781. width="100px"
  782. />
  783. <div v-else class="document-icon">
  784. <i :class="getDocumentIconClass(form.qualityAssuranceAgreement, 'qualityAssuranceAgreement')" class="icon"></i>
  785. <span class="file-name">{{ form.qualityAssuranceAgreementFileName || getFileName(form.qualityAssuranceAgreement) }}</span>
  786. </div>
  787. <i class="el-icon-delete delete-icon" @click.stop="handleFileRemove('qualityAssuranceAgreement')"></i>
  788. </div>
  789. <div v-else class="upload-btn">
  790. <div class="upload-btn-inner">
  791. <i class="el-icon-plus"></i>
  792. <span class="upload-tip">点击上传</span>
  793. </div>
  794. </div>
  795. </el-upload>
  796. <el-form-item prop="qualityAssuranceAgreementCode">
  797. <el-input
  798. v-model="form.qualityAssuranceAgreementCode"
  799. placeholder="请输入备注内容"
  800. />
  801. </el-form-item>
  802. <el-form-item label="协议是否长期有效" prop="isEffectivePermanent2">
  803. <el-switch
  804. @change="switchChange()"
  805. v-model="medicalLicenseExpiryValue2"
  806. active-color="#13ce66"
  807. inactive-color="#ff4949">
  808. </el-switch>
  809. </el-form-item>
  810. <el-form-item
  811. label="协议有效期"
  812. prop="medicalLicenseExpiry"
  813. v-if="!medicalLicenseExpiryValue2"
  814. >
  815. <el-date-picker
  816. v-model="form.qualityAssuranceAgreementExpiry"
  817. type="daterange"
  818. value-format="yyyy-MM-dd"
  819. range-separator="至"
  820. start-placeholder="开始日期"
  821. end-placeholder="结束日期" style="width: 100%">
  822. </el-date-picker>
  823. </el-form-item>
  824. </el-form-item>
  825. </div>
  826. </el-col>
  827. <el-col :span="8">
  828. <div class="agreement-section">
  829. <el-form-item label="其它特殊资质">
  830. <el-input
  831. v-model="form.titleNameThree"
  832. placeholder="请输入标题"
  833. class="agreement-title"
  834. />
  835. <el-upload
  836. class="file-uploader"
  837. :action="uploadUrl"
  838. :show-file-list="false"
  839. :on-success="(response, file) => handleFileSuccess1(response, file, 'otherSpecialQualification')"
  840. :on-error="handleFileError"
  841. :before-upload="beforeFileUpload"
  842. :disabled="!!form.otherSpecialQualification"
  843. accept=".jpg,.jpeg,.png,.gif,.doc,.docx,.pdf"
  844. >
  845. <div v-if="form.otherSpecialQualification" class="uploaded-file">
  846. <img
  847. v-if="isImageFile(form.otherSpecialQualification, 'otherSpecialQualification')"
  848. :src="form.otherSpecialQualification"
  849. class="uploaded-img"
  850. width="100px"
  851. />
  852. <div v-else class="document-icon">
  853. <i :class="getDocumentIconClass(form.otherSpecialQualification, 'otherSpecialQualification')" class="icon"></i>
  854. <span class="file-name">{{ form.otherSpecialQualificationFileName || getFileName(form.otherSpecialQualification) }}</span>
  855. </div>
  856. <i class="el-icon-delete delete-icon" @click.stop="handleFileRemove('otherSpecialQualification')"></i>
  857. </div>
  858. <div v-else class="upload-btn">
  859. <div class="upload-btn-inner">
  860. <i class="el-icon-plus"></i>
  861. <span class="upload-tip">点击上传</span>
  862. </div>
  863. </div>
  864. </el-upload>
  865. <el-form-item prop="otherSpecialQualificationCode">
  866. <el-input
  867. v-model="form.otherSpecialQualificationCode"
  868. placeholder="请输入备注内容"
  869. />
  870. </el-form-item>
  871. <el-form-item label="协议是否长期有效" prop="isEffectivePermanent3">
  872. <el-switch
  873. @change="switchChange()"
  874. v-model="medicalLicenseExpiryValue3"
  875. active-color="#13ce66"
  876. inactive-color="#ff4949">
  877. </el-switch>
  878. </el-form-item>
  879. <el-form-item
  880. label="协议有效期"
  881. prop="medicalLicenseExpiry"
  882. v-if="!medicalLicenseExpiryValue3"
  883. >
  884. <el-date-picker
  885. v-model="form.otherSpecialQualificationExpiry"
  886. type="daterange"
  887. value-format="yyyy-MM-dd"
  888. range-separator="至"
  889. start-placeholder="开始日期"
  890. end-placeholder="结束日期" style="width: 100%">
  891. </el-date-picker>
  892. </el-form-item>
  893. </el-form-item>
  894. </div>
  895. </el-col>
  896. </el-row>
  897. </div>
  898. <el-divider content-position="left">店铺配置信息</el-divider>
  899. <el-col :span="12">
  900. <el-form-item label="网销报告" prop="reportUrl">
  901. <el-upload
  902. class="upload-demo"
  903. :action="uploadUrl"
  904. :on-preview="handlePreview"
  905. :on-remove="handleRemove"
  906. :before-remove="beforeRemove"
  907. multiple
  908. :limit="1"
  909. :on-exceed="handleExceed"
  910. :on-success="(response, file) => handleFileSuccess(response, file, 'reportUrl')"
  911. :file-list="reportFileList">
  912. <el-button size="small" type="primary">点击上传</el-button>
  913. </el-upload>
  914. </el-form-item>
  915. </el-col>
  916. <el-col :span="12">
  917. <el-form-item label="备案" prop="filingUrl">
  918. <el-upload
  919. class="upload-demo"
  920. :action="uploadUrl"
  921. :on-preview="handlePreview"
  922. :on-remove="handleRemove"
  923. :before-remove="beforeRemove"
  924. :on-success="(response, file) => handleFileSuccess(response, file, 'filingUrl')"
  925. multiple
  926. :limit="1"
  927. :on-exceed="handleExceed"
  928. :file-list="fileList">
  929. <el-button size="small" type="primary">点击上传</el-button>
  930. </el-upload>
  931. </el-form-item>
  932. </el-col>
  933. <el-form-item label="退货地址" prop="refundAddress">
  934. <el-input v-model="form.refundAddress" placeholder="请输入退货地址" />
  935. </el-form-item>
  936. <el-row>
  937. <el-col :span="12">
  938. <el-form-item label="退货电话" prop="refundPhone">
  939. <el-input v-model="form.refundPhone" placeholder="请输入退货电话" />
  940. </el-form-item>
  941. </el-col>
  942. <el-col :span="12">
  943. <el-form-item label="退货收货人" prop="refundConsignee">
  944. <el-input v-model="form.refundConsignee" placeholder="请输入退货收货人" />
  945. </el-form-item>
  946. </el-col>
  947. </el-row>
  948. <el-form-item label="寄件人电话" prop="sendPhone">
  949. <el-input v-model="form.sendPhone" placeholder="请输入寄件人电话" />
  950. </el-form-item>
  951. <el-row>
  952. <el-col :span="12">
  953. <el-form-item label="商品总数" prop="productCount">
  954. <el-input-number v-model="form.productCount" :min="0" label="描述文字"></el-input-number>
  955. </el-form-item>
  956. </el-col>
  957. <el-col :span="12">
  958. <el-form-item label="销量" prop="salesCount">
  959. <el-input-number v-model="form.salesCount" :min="0" label="描述文字"></el-input-number>
  960. </el-form-item>
  961. </el-col>
  962. </el-row>
  963. <el-row>
  964. <el-col :span="12">
  965. <el-form-item label="累计金额" prop="totalMoney">
  966. <el-input-number v-model="form.totalMoney" :precision="2" :step="0.1"></el-input-number>
  967. </el-form-item>
  968. </el-col>
  969. <el-col :span="12">
  970. </el-col>
  971. </el-row>
  972. <el-row>
  973. <el-col :span="12">
  974. <el-form-item label="状态">
  975. <el-radio-group v-model="form.status">
  976. <el-radio
  977. v-for="dict in statusOptions"
  978. :key="dict.dictValue"
  979. :label="parseInt(dict.dictValue)"
  980. >{{dict.dictLabel}}</el-radio>
  981. </el-radio-group>
  982. </el-form-item>
  983. </el-col>
  984. <el-col :span="12">
  985. <el-form-item label="分佣方式" prop="brokerageType" >
  986. <el-radio v-model="form.brokerageType" label="1">每盒</el-radio>
  987. <el-radio v-model="form.brokerageType" label="2">总价</el-radio>
  988. </el-form-item>
  989. </el-col>
  990. </el-row>
  991. <el-form-item label="配送方式" prop="shippingType">
  992. <el-checkbox-group v-model="form.shippingType" size="medium">
  993. <el-checkbox v-for="(item, index) in shippingTypeOptions" :key="index" :label="item.value"
  994. :disabled="item.disabled">{{item.label}}</el-checkbox>
  995. </el-checkbox-group>
  996. </el-form-item>
  997. <el-divider content-position="left">登录信息</el-divider>
  998. <el-form-item label="登录帐号" prop="account" v-if="title != '修改店铺管理'">
  999. <el-input v-model="form.account" placeholder="请输入登录帐号" />
  1000. </el-form-item>
  1001. <!-- tips-->
  1002. <span class="tip-text" v-if="title !== '修改店铺管理'">请及时修改密码,初试密码XyzAbc~12</span>
  1003. </el-form>
  1004. <div slot="footer" class="dialog-footer">
  1005. <el-button v-if="!isViewMode" type="primary" @click="submitForm">确 定</el-button>
  1006. <el-button @click="cancel">{{ isViewMode ? '关 闭' : '取 消' }}</el-button>
  1007. </div>
  1008. </el-dialog>
  1009. <!-- 修改图片预览对话框,增加更大的预览尺寸 -->
  1010. <el-dialog :visible.sync="imagePreviewVisible" width="1100px" append-to-body :modal-append-to-body="false" @close="imagePreviewVisible = false">
  1011. <img :src="previewImageUrl" style="width: 100%; height: auto; max-height: 700px; object-fit: contain;" />
  1012. </el-dialog>
  1013. <el-dialog
  1014. title="店铺资质消息提示"
  1015. :visible.sync="dialogVisible"
  1016. width="40%"
  1017. center>
  1018. <div v-for="(item,index) in promptList">({{index+1}})、{{item}}</div>
  1019. <span slot="footer" class="dialog-footer">
  1020. <el-button type="primary" @click="dialogVisible = false">已 知 晓</el-button>
  1021. </span>
  1022. </el-dialog>
  1023. </div>
  1024. </template>
  1025. <script>
  1026. import { listStore, getStore, delStore, addStore, updateStore, exportStore, refreshPasWod,exportFsStream, businessLicenseCheck} from '@/api/hisStore/store'
  1027. import storeDetails from '../components/storeDetails.vue';
  1028. import StoreDialog from '../components/StoreDialog.vue';
  1029. import {getCitys} from "@/api/store/city";
  1030. import { getConfigByKey } from '@/api/system/config'
  1031. import { qualifications } from '@/api/system/user';
  1032. export default {
  1033. name: "Store",
  1034. components: { storeDetails, StoreDialog },
  1035. data() {
  1036. return {
  1037. reportFileList:[],
  1038. fileList:[],
  1039. previewImageUrl: '', // 添加预览图片URL
  1040. imagePreviewVisible: false,// 添加图片预览对话框可见性控制
  1041. // 新增:控制LOGO上传组件禁用状态
  1042. isDeleting: false,
  1043. promptList:[],
  1044. dialogVisible: false,
  1045. // 控制是否为查看模式(只读)
  1046. isViewMode: false,
  1047. // 店铺对话框相关
  1048. storeDialogVisible: false,
  1049. storeDialogMode: 'add', // add, edit, detail
  1050. currentStoreData: {},
  1051. auditLogs: [],
  1052. switchValue:false,
  1053. switchMedicalValue:false,
  1054. medicalDevice2ExpiryValue:false,
  1055. medicalLicenseExpiryValue:false,
  1056. foodLicenseExpiryValue:false,
  1057. medicalLicenseExpiryValue1:false,//协议有效期控制
  1058. medicalLicenseExpiryValue2:false,//协议有效期控制
  1059. medicalLicenseExpiryValue3:false,//协议有效期控制
  1060. shippingType: [],
  1061. medicalMallConfig:{},
  1062. citys: [],
  1063. licenseuploadUrl: process.env.VUE_APP_BASE_API + "/common/uploadOSS",
  1064. uploadUrl: process.env.VUE_APP_BASE_API + "/common/uploadOSS",
  1065. baseUrl: process.env.VUE_APP_BASE_API,
  1066. shippingTypeOptions: [{
  1067. "label": "配送",
  1068. "value": "1"
  1069. }, {
  1070. "label": "自提",
  1071. "value": "2"
  1072. }, {
  1073. "label": "配送自提",
  1074. "value": "3"
  1075. }],
  1076. // 遮罩层
  1077. loading: true,
  1078. // 导出遮罩层
  1079. exportLoading: false,
  1080. // 选中数组
  1081. ids: [],
  1082. // 非单个禁用
  1083. single: true,
  1084. // 非多个禁用
  1085. multiple: true,
  1086. // 显示搜索条件
  1087. showSearch: true,
  1088. // 总条数
  1089. total: 0,
  1090. // 店铺管理表格数据
  1091. storeList: [],
  1092. // 弹出层标题
  1093. title: "",
  1094. // 是否显示弹出层
  1095. open: false,
  1096. // 状态字典
  1097. statusOptions: [],
  1098. // 审核状态字典
  1099. isAuditOptions: [],
  1100. deliveryTypeOptions: [],
  1101. // 查询参数
  1102. queryParams: {
  1103. pageNum: 1,
  1104. pageSize: 10,
  1105. storeName: null,
  1106. address: null,
  1107. phone: null,
  1108. status: null,
  1109. isAudit: null,
  1110. account: null,
  1111. daysDiffMin: null, // 添加最小剩余天数查询条件
  1112. daysDiffMax: null // 添加最大剩余天数查询条件
  1113. },
  1114. // 表单参数
  1115. form: {
  1116. medicalDevice3BusinessScope: null,
  1117. medicalDevice2BusinessScope: null,
  1118. settlementAgreementFileType: '', // 入驻协议文件类型(如 application/pdf)
  1119. qualityAssuranceAgreementFileType: '', // 质量保证协议文件类型
  1120. otherSpecialQualificationFileType: '', // 其他特殊资质文件类型
  1121. settlementAgreement: null,
  1122. settlementAgreementFileName: null, // 新增:存储文件名
  1123. qualityAssuranceAgreement: null,
  1124. qualityAssuranceAgreementFileName: null, // 新增:存储文件名
  1125. otherSpecialQualification: null,
  1126. otherSpecialQualificationFileName: null, // 新增:存储文件名
  1127. foodLicense: [], // 食品经营许可证/备案凭证上传(支持多张图片)
  1128. },
  1129. // 表单校验
  1130. rules: {
  1131. drugLicenseBusinessScope: [
  1132. { required: true, message: "药品经营许可证范围不能为空", trigger: "blur" }
  1133. ],
  1134. // 添加新的验证规则
  1135. drugScopeHasFrozen: [
  1136. { required: true, message: "请选择药品经营许可证范围是否包含冷冻/冷藏", trigger: "change" }
  1137. ],
  1138. storeName: [
  1139. { required: true, message: "店铺名称不能为空", trigger: "blur" }
  1140. ],
  1141. fullName: [
  1142. { required: true, message: "店铺名称不能为空", trigger: "blur" }
  1143. ],
  1144. businessLicenseExpire: [
  1145. { required: true, message: "营业执照失效日期不能为空", trigger: "blur" }
  1146. ],
  1147. businessLicense: [
  1148. { required: true, message: "营业执照不能为空", trigger: "blur" }
  1149. ],
  1150. businessCode:[
  1151. { required: true, message: "营业执照编号不能为空", trigger: "blur" }
  1152. ],
  1153. drugLicense: [
  1154. { required: true, message: "药品经营许可证不能为空", trigger: "blur" }
  1155. ],
  1156. drugCode:[
  1157. { required: true, message: "药品经营许可证编号不能为空", trigger: "blur" }
  1158. ],
  1159. drugLicenseExpiry: [
  1160. { required: true, message: "药品经营许可证有效期不能为空", trigger: "blur" }
  1161. ],
  1162. // medicalDevice3: [
  1163. // { required: true, message: "3类器械经营许可证不能为空", trigger: "blur" }
  1164. // ],
  1165. // medicalDevice3Code: [
  1166. // { required: true, message: "3类器械生产备案编号不能为空", trigger: "blur" }
  1167. // ],
  1168. // medicalDevice3Expiry: [
  1169. // { required: true, message: "3类器械经营许可证有效期不能为空", trigger: "blur" }
  1170. // ],
  1171. // foodLicense: [
  1172. // {
  1173. // validator: (rule, value, callback) => {
  1174. // if (!value || (Array.isArray(value) && value.length === 0)) {
  1175. // callback(new Error('请至少上传一张食品经营许可证图片'));
  1176. // } else {
  1177. // callback();
  1178. // }
  1179. // },
  1180. // trigger: 'change'
  1181. // }
  1182. // ],
  1183. // foodCode: [
  1184. // { required: true, message: "食品经营许可证编号不能为空", trigger: "blur" }
  1185. // ],
  1186. // foodLicenseExpiry: [
  1187. // { required: true, message: "食品经营许可证有效期不能为空", trigger: "blur" }
  1188. // ],
  1189. logoUrl: [
  1190. { required: true, message: "店铺LOGO不能为空", trigger: "blur" }
  1191. ],
  1192. cityIds: [
  1193. { required: true, message: "所属城市不能为空", trigger: "blur" }
  1194. ],
  1195. address: [
  1196. { required: true, message: "地址不能为空", trigger: "blur" }
  1197. ],
  1198. licenseImages: [
  1199. { required: true, message: "资质证书不能为空", trigger: "blur" }
  1200. ],
  1201. shippingType: [
  1202. { required: true, message: "配送方式不能为空", trigger: "blur" }
  1203. ],
  1204. account: [
  1205. { required: true, message: "登录账号不能为空", trigger: "blur" }
  1206. ],
  1207. brokerageType: [
  1208. { required: true, message: "分佣方式不能为空", trigger: "blur" }
  1209. ],
  1210. refundPhone: [
  1211. { required: true, message: "退货电话不能为空", trigger: "blur" }
  1212. ],
  1213. refundAddress: [
  1214. { required: true, message: "退货地址不能为空", trigger: "blur" }
  1215. ],
  1216. refundConsignee: [
  1217. { required: true, message: "退货收货人不能为空", trigger: "blur" }
  1218. ],
  1219. sendPhone: [
  1220. { required: true, message: "寄件人电话不能为空", trigger: "blur" },
  1221. ],
  1222. phone: [
  1223. {
  1224. pattern: /^1[3|4|5|6|7|8|9][0-9]\d{8}$/,
  1225. message: "请输入正确的手机号码",
  1226. trigger: "blur",
  1227. required: true
  1228. }
  1229. ],
  1230. // 新增字段校验规则
  1231. enterpriseShortName: [
  1232. { required: true, message: "企业简称不能为空", trigger: "blur" }
  1233. ],
  1234. enterpriseFullName: [
  1235. { required: true, message: "企业全称不能为空", trigger: "blur" }
  1236. ],
  1237. contactPhone: [
  1238. { required: true, message: "电话号码不能为空", trigger: "blur" }
  1239. ],
  1240. enterpriseAddress: [
  1241. { required: true, message: "企业地址不能为空", trigger: "blur" }
  1242. ],
  1243. legalPersonName: [
  1244. { required: true, message: "法人姓名不能为空", trigger: "blur" }
  1245. ],
  1246. unifiedSocialCreditCode: [
  1247. { required: true, message: "统一社会信用代码不能为空", trigger: "blur" }
  1248. ],
  1249. businessScope: [
  1250. { required: true, message: "营业范围不能为空", trigger: "blur" }
  1251. ],
  1252. password: [
  1253. { required: true, message: "新密码不能为空", trigger: "blur" },
  1254. { min: 6, max: 20, message: "长度在 6 到 20 个字符", trigger: "blur" }
  1255. ],
  1256. }
  1257. };
  1258. },
  1259. created() {
  1260. this.getCitys();
  1261. this.getList();
  1262. getConfigByKey("medicalMall.func.switch").then(response => {
  1263. if(response.data && response.data.configValue) {
  1264. this.medicalMallConfig = JSON.parse(response.data.configValue);
  1265. }
  1266. });
  1267. this.getDicts("sys_company_status").then(response => {
  1268. this.statusOptions = response.data;
  1269. });
  1270. this.getDicts("sys_company_isaudit").then(response => {
  1271. this.isAuditOptions = response.data;
  1272. });
  1273. this.getDicts("sys_store_delivery_type").then(response => {
  1274. this.deliveryTypeOptions = response.data;
  1275. });
  1276. this.$nextTick(()=>{
  1277. console.log("是否执行资质提示方法")
  1278. this.handleNoticeInfo();
  1279. })
  1280. },
  1281. methods: {
  1282. // 处理提醒状态筛选
  1283. handleRemindFilter(type) {
  1284. // 重置其他查询条件
  1285. this.resetForm("queryForm");
  1286. // 根据不同类型设置查询参数
  1287. switch (type) {
  1288. case 'overdue': // 严重逾期
  1289. this.queryParams.daysDiffMin = null;
  1290. this.queryParams.daysDiffMax = 0;
  1291. break;
  1292. case 'urgent': // 紧急提醒 (7天内)
  1293. this.queryParams.daysDiffMin = 0;
  1294. this.queryParams.daysDiffMax = 7;
  1295. break;
  1296. case 'important': // 重点提醒 (15天内)
  1297. this.queryParams.daysDiffMin = 0;
  1298. this.queryParams.daysDiffMax = 15;
  1299. break;
  1300. case 'warning': // 常规预警 (30天内)
  1301. this.queryParams.daysDiffMin = 0;
  1302. this.queryParams.daysDiffMax = 30;
  1303. break;
  1304. default: // 默认情况,清空条件
  1305. this.queryParams.daysDiffMin = null;
  1306. this.queryParams.daysDiffMax = null;
  1307. break;
  1308. }
  1309. this.handleQuery();
  1310. },
  1311. // 获取提醒标签类型
  1312. getRemindTagType(daysDiff) {
  1313. if (daysDiff < 0) {
  1314. return 'danger'; // 严重逾期 - 红色
  1315. } else if (daysDiff <= 7) {
  1316. return 'warning'; // 紧急提醒 - 橙色
  1317. } else if (daysDiff <= 15) {
  1318. return ''; // 重点提醒 - 黄色 (Element UI 中空字符串是黄色)
  1319. } else if (daysDiff <= 30) {
  1320. return 'primary'; // 常规预警 - 蓝色 (Element UI 中 primary 是蓝色)
  1321. }
  1322. return 'info'; // 其他情况 - 灰色
  1323. },
  1324. // 获取提醒标签名称
  1325. getRemindTagName(daysDiff) {
  1326. if (daysDiff < 0) {
  1327. return '逾期';
  1328. } else if (daysDiff <= 7) {
  1329. return '7天内到期';
  1330. } else if (daysDiff <= 15) {
  1331. return '15天内到期';
  1332. } else if (daysDiff <= 30) {
  1333. return '30天内到期';
  1334. }
  1335. return '正常';
  1336. },
  1337. // 添加图片预览方法
  1338. previewImage(url) {
  1339. this.previewImageUrl = url;
  1340. this.imagePreviewVisible = true;
  1341. },
  1342. handleNoticeInfo() {
  1343. qualifications()
  1344. .then(response => {
  1345. console.log("noticeInfo接口完整响应:", response);
  1346. if (response.code === 200) {
  1347. this.promptList = response.data;
  1348. if (this.promptList && this.promptList.length > 0) {
  1349. this.dialogVisible = true;
  1350. }
  1351. console.log("通知信息请求完成!", this.promptList);
  1352. } else {
  1353. console.warn("接口返回非成功状态:", response.code);
  1354. }
  1355. })
  1356. .catch(err => {
  1357. console.error("获取通知信息失败:", err);
  1358. this.$message.error("加载通知信息失败,请稍后重试");
  1359. });
  1360. },
  1361. // 在 methods 中添加新的方法
  1362. checkBusinessLicense(imageUrl) {
  1363. if (!imageUrl) return;
  1364. // 使用正确的参数格式调用接口
  1365. businessLicenseCheck(imageUrl).then(response => {
  1366. if (response.code === 200) {
  1367. if (!response.data.flag) {
  1368. // 检查失败,显示错误信息
  1369. this.$message.error(response.data.message || '营业执照校验失败');
  1370. // 清除刚上传的图片
  1371. this.form.businessLicense = '';
  1372. this.$forceUpdate();
  1373. }else {
  1374. // 检查成功,回填数据
  1375. this.form.legalPersonName = response.data.person; // 法人姓名
  1376. this.form.unifiedSocialCreditCode = response.data.regNum; // 统一社会信用代码
  1377. this.form.businessScope = response.data.businessStr; // 营业范围
  1378. this.form.businessCode = response.data.regNum; // 营业执照编号
  1379. }
  1380. } else {
  1381. this.$message.error('营业执照校验接口调用失败');
  1382. }
  1383. }).catch(error => {
  1384. console.error('营业执照校验失败:', error);
  1385. this.$message.error('营业执照校验失败');
  1386. });
  1387. },
  1388. handleCityChange(value) {
  1389. var nodes = this.$refs.citySelect.getCheckedNodes();
  1390. this.form.address = nodes[0].pathLabels[0] + nodes[0].pathLabels[1] + nodes[0].pathLabels[2];
  1391. this.form.cityIds = value.toString();
  1392. },
  1393. getCitys() {
  1394. getCitys().then(res => {
  1395. this.loading = false;
  1396. this.citys = res.data;
  1397. })
  1398. },
  1399. licensehandleAvatarSuccess(res, file) {
  1400. if (res.code === 200) {
  1401. this.form.licenseImages = res.url;
  1402. this.$forceUpdate()
  1403. } else {
  1404. this.msgError(res.msg);
  1405. }
  1406. },
  1407. handleAvatarSuccess(res, file) {
  1408. if (res.code === 200) {
  1409. this.form.logoUrl = res.url;
  1410. this.$forceUpdate()
  1411. } else {
  1412. this.msgError(res.msg);
  1413. }
  1414. },
  1415. beforeAvatarUpload(file) {
  1416. const isLt1M = file.size / 1024 / 1024 < 1;
  1417. if (!isLt1M) {
  1418. this.$message.error('上传图片大小不能超过 1MB!');
  1419. }
  1420. return isLt1M;
  1421. },
  1422. handleBizLicenseSuccess(res, file) {
  1423. if (res.code === 200) {
  1424. this.form.bizLicense = res.url;
  1425. this.$forceUpdate()
  1426. } else {
  1427. this.msgError(res.msg);
  1428. }
  1429. },
  1430. beforeBizLicenseUpload(file) {
  1431. const isLt1M = file.size / 1024 / 1024 < 5;
  1432. if (!isLt1M) {
  1433. this.$message.error('上传图片大小不能超过 5MB!');
  1434. }
  1435. return isLt1M;
  1436. },
  1437. // 通用文件上传成功处理函数
  1438. handleFileSuccess(response, file, field) {
  1439. if (response.code === 200) {
  1440. this.$set(this.form, field, response.url);
  1441. this.$forceUpdate();
  1442. // 如果是营业执照上传,则进行检查
  1443. if (field === 'businessLicense') {
  1444. this.checkBusinessLicense(response.url);
  1445. }
  1446. } else {
  1447. this.msgError(response.msg);
  1448. }
  1449. },
  1450. // 食品经营许可证上传成功处理函数
  1451. handleFoodLicenseSuccess(response, file) {
  1452. if (response.code === 200) {
  1453. // 初始化数组(如果尚未初始化)
  1454. if (!Array.isArray(this.form.foodLicense)) {
  1455. this.$set(this.form, 'foodLicense', []);
  1456. }
  1457. // 添加新上传的图片URL到数组中
  1458. this.form.foodLicense.push(response.url);
  1459. this.$forceUpdate();
  1460. } else {
  1461. this.msgError(response.msg);
  1462. }
  1463. },
  1464. // 食品经营许可证上传超出限制处理函数
  1465. handleFoodLicenseExceed(files, fileList) {
  1466. this.$message.warning(`当前最多只能上传 3 张图片`);
  1467. },
  1468. /** 查询店铺管理列表 */
  1469. getList() {
  1470. this.loading = true;
  1471. listStore(this.queryParams).then(response => {
  1472. this.storeList = response.rows;
  1473. this.total = response.total;
  1474. this.loading = false;
  1475. });
  1476. },
  1477. // 取消按钮
  1478. cancel() {
  1479. this.open = false;
  1480. this.reset();
  1481. },
  1482. // 表单重置
  1483. reset() {
  1484. this.switchValue = false;
  1485. this.switchMedicalValue=false;
  1486. // 重置时确保isDeleting为false
  1487. this.isDeleting = false;
  1488. this.form = {
  1489. storeId: null,
  1490. cityIds: null,
  1491. storeName: null,
  1492. descs: null,
  1493. logoUrl: null,
  1494. address: null,
  1495. lng: null,
  1496. lat: null,
  1497. phone: null,
  1498. licenseImages: null,
  1499. productCount: null,
  1500. status: 0,
  1501. createTime: null,
  1502. updateTime: null,
  1503. salesCount: null,
  1504. balance: null,
  1505. totalMoney: null,
  1506. isAudit: 0,
  1507. account: null,
  1508. password: null,
  1509. shippingType: ["1"],
  1510. brokerageType: "1",
  1511. brokerageRate: 0,
  1512. fullName: null,
  1513. // 重置新增字段
  1514. enterpriseShortName: null, // 企业简称
  1515. enterpriseFullName: null, // 企业全称
  1516. contactPhone: null, // 联系电话
  1517. enterpriseAddress: null, // 企业地址
  1518. legalPersonName: null, // 法人姓名
  1519. unifiedSocialCreditCode: null, // 统一社会信用代码
  1520. businessScope: null, // 营业范围
  1521. // 重置证书相关字段
  1522. businessLicense: null, // 营业执照文件
  1523. businessLicenseExpire: null, // 营业执照失效日期
  1524. drugLicense: null, // 药品经营许可证有效期
  1525. drugLicenseExpiry: null, // 药品经营许可证文件
  1526. // 医疗器械相关证书
  1527. medicalDevice1: null, // 一类医疗器械备案证书
  1528. medicalDevice1Expiry: null, // 二类医疗器械备案有效期
  1529. medicalDevice2: null, // 二类器械生产备案文件
  1530. medicalDevice2Expiry: null, // 一类生产备案有效期
  1531. medicalDevice3: null, // 三类器械经营许可证文件
  1532. medicalDevice3Expiry: null, // 三类器械经营许可证有效期
  1533. // 其他许可证相关字段
  1534. foodLicense: [], // 食品经营许可证文件(支持多张图片)
  1535. foodLicenseExpiry: null, // 食品经营许可证有效期
  1536. medicalLicense: null, // 医疗机构执业许可证文件
  1537. medicalLicenseExpiry: null, // 医疗机构执业许可证有效期
  1538. settlementAgreement: null, //其它资质-入驻协议
  1539. settlementAgreementFileName: null,
  1540. qualityAssuranceAgreementFileName: null, // 新增:质量保证协议文件名
  1541. otherSpecialQualificationFileName: null,// 新增:其他特殊资质文件名
  1542. settlementAgreementExpiry: null,//其它资质-有效期
  1543. qualityAssuranceAgreement: null,//质量保证协议
  1544. qualityAssuranceAgreementExpiry: null,//质量保证协议有效期
  1545. otherSpecialQualification: null,//其它特殊资质
  1546. otherSpecialQualificationExpiry: null,//其它特殊资质有效期
  1547. businessCode: null,
  1548. drugLicenseBusinessScope:null,
  1549. drugScopeHasFrozen: null,
  1550. drugCode:null,
  1551. medicalDevice1Code:null,
  1552. medicalDevice2Code:null,
  1553. medicalDevice3Code:null,
  1554. foodCode:null,
  1555. medicalCode:null,
  1556. otherSpecialQualificationCode:null,
  1557. qualityAssuranceAgreementCode:null,
  1558. settlementAgreementCode: null,
  1559. titleNameOne: null,
  1560. titleNameTwo: null,
  1561. titleNameThree: null,
  1562. settlementAgreementFileType: '',
  1563. qualityAssuranceAgreementFileType: '',
  1564. otherSpecialQualificationFileType: ''
  1565. };
  1566. this.resetForm("form");
  1567. },
  1568. /** 搜索按钮操作 */
  1569. handleQuery() {
  1570. this.queryParams.pageNum = 1;
  1571. this.getList();
  1572. },
  1573. /** 重置按钮操作 */
  1574. resetQuery() {
  1575. this.queryParams.daysDiffMin = null;
  1576. this.queryParams.daysDiffMax = null;
  1577. this.resetForm("queryForm");
  1578. this.handleQuery();
  1579. },
  1580. // 多选框选中数据
  1581. handleSelectionChange(selection) {
  1582. this.ids = selection.map(item => item.storeId)
  1583. this.single = selection.length !== 1
  1584. this.multiple = !selection.length
  1585. },
  1586. /** 新增按钮操作 */
  1587. handleAdd() {
  1588. this.reset();
  1589. this.isViewMode = false; // 新增时可编辑
  1590. this.open = true;
  1591. this.title = "添加店铺";
  1592. },
  1593. // 修复LOGO删除逻辑:确保删除后可重新上传
  1594. handleDeleteLogo() {
  1595. this.deleteImage('logoUrl', 'Logo');
  1596. },
  1597. handleDelete2() {
  1598. this.deleteImage('medicalDevice3', '3类器械经营许可证');
  1599. },
  1600. // 删除指定索引的食品经营许可证图片
  1601. handleDeleteFoodLicense(index) {
  1602. this.$confirm(`确定要删除这张食品经营许可证图片吗?`, '提示', {
  1603. confirmButtonText: '确定',
  1604. cancelButtonText: '取消',
  1605. type: 'warning'
  1606. }).then(() => {
  1607. this.form.foodLicense.splice(index, 1);
  1608. this.$message.success('图片已删除');
  1609. this.$forceUpdate();
  1610. }).catch(() => {
  1611. this.$message.info('已取消删除');
  1612. });
  1613. },
  1614. handleDelete5() {
  1615. this.deleteImage('businessLicense', '营业执照');
  1616. },
  1617. handleDelete6() {
  1618. this.deleteImage('drugLicense', '药品经营许可证');
  1619. },
  1620. handleDelete7() {
  1621. this.deleteImage('medicalDevice2', '2类医疗器械备案证书');
  1622. },
  1623. // 通用图片删除方法
  1624. deleteImage(field, itemType) {
  1625. this.isDeleting = true; // 临时禁用上传组件
  1626. this.$confirm(`确定要删除这张${itemType}吗?`, '提示', {
  1627. confirmButtonText: '确定',
  1628. cancelButtonText: '取消',
  1629. type: 'warning'
  1630. }).then(() => {
  1631. this.form[field] = ''; // 清空图片URL
  1632. this.$message.success(`${itemType}已删除`);
  1633. }).catch(() => {
  1634. this.$message.info('已取消删除');
  1635. }).finally(() => {
  1636. this.isDeleting = false; // 无论操作结果,恢复上传组件可用
  1637. this.$forceUpdate(); // 强制刷新确保状态同步
  1638. });
  1639. },
  1640. /** 修改/详情按钮操作 */
  1641. handleUpdate(row, isEdit = true) {
  1642. this.reset();
  1643. this.isViewMode = !isEdit; // 设置是否为查看模式
  1644. const storeId = row.storeId || this.ids
  1645. getStore(storeId).then(response => {
  1646. this.form = response.data;
  1647. // 如果后端返回的数据中没有这个字段,则设置默认值
  1648. if (this.form.drugScopeHasFrozen === undefined) {
  1649. this.form.drugScopeHasFrozen = null;
  1650. }
  1651. if(this.form.isBusinessLicensePermanent == 1){
  1652. this.switchValue = true;
  1653. }
  1654. if(this.form.isMedicalDevice1ExpiryPermanent == 1){
  1655. this.switchMedicalValue = true;
  1656. }
  1657. if(this.form.isMedicalDevice2ExpiryPermanent == 1){
  1658. this.medicalDevice2ExpiryValue = true;
  1659. }
  1660. if(this.form.isMedicalLicenseExpiryPermanent == 1){
  1661. this.medicalLicenseExpiryValue = true;
  1662. }
  1663. if(this.form.isEffectivePermanent1 == 1){
  1664. this.medicalLicenseExpiryValue1 = true;
  1665. }
  1666. if(this.form.isFoodLicenseExpiryPermanent == 1){
  1667. this.foodLicenseExpiryValue = true;
  1668. }
  1669. if(this.form.isEffectivePermanent2 == 1){
  1670. this.medicalLicenseExpiryValue2 = true;
  1671. }
  1672. if(this.form.isEffectivePermanent3 == 1){
  1673. this.medicalLicenseExpiryValue3 = true;
  1674. }
  1675. this.open = true;
  1676. this.title = this.isViewMode ? "店铺详情" : "修改店铺";
  1677. let str = this.form.shippingType
  1678. this.form.shippingType = str.split(",")
  1679. this.form.cityIds = ((this.form.cityIds).split(",")).map(Number)
  1680. const dateFields = [
  1681. 'drugLicenseExpiry',
  1682. 'medicalDevice1Expiry',
  1683. 'medicalDevice2Expiry',
  1684. 'medicalDevice3Expiry',
  1685. 'foodLicenseExpiry',
  1686. 'medicalLicenseExpiry',
  1687. 'businessLicenseExpire'
  1688. ];
  1689. dateFields.forEach(field => {
  1690. const startField = field + 'Start';
  1691. const endField = field + 'End';
  1692. if (this.form[startField] && this.form[endField]) {
  1693. this.$set(this.form, field, [this.form[startField], this.form[endField]]);
  1694. }
  1695. });
  1696. // 入驻协议有效期
  1697. if (this.form.settlementAgreementStart && this.form.settlementAgreementEnd) {
  1698. this.$set(this.form, 'settlementAgreementExpiry', [
  1699. this.form.settlementAgreementStart,
  1700. this.form.settlementAgreementEnd
  1701. ]);
  1702. }
  1703. // 质量保证协议有效期
  1704. if (this.form.qualityAssuranceAgreementStart && this.form.qualityAssuranceAgreementEnd) {
  1705. this.$set(this.form, 'qualityAssuranceAgreementExpiry', [
  1706. this.form.qualityAssuranceAgreementStart,
  1707. this.form.qualityAssuranceAgreementEnd
  1708. ]);
  1709. }
  1710. // 其它特殊资质有效期
  1711. if (this.form.otherSpecialQualificationStart && this.form.otherSpecialQualificationEnd) {
  1712. this.$set(this.form, 'otherSpecialQualificationExpiry', [
  1713. this.form.otherSpecialQualificationStart,
  1714. this.form.otherSpecialQualificationEnd
  1715. ]);
  1716. }
  1717. this.reportFileList = this.urlToFileList(this.form.reportUrl);
  1718. this.fileList = this.urlToFileList(this.form.filingUrl);
  1719. // 处理食品经营许可证图片数据,支持逗号分隔的字符串
  1720. if (this.form.foodLicense) {
  1721. if (typeof this.form.foodLicense === 'string') {
  1722. // 如果是逗号分隔的字符串,则分割成数组
  1723. this.form.foodLicense = this.form.foodLicense.split(',').filter(url => url.trim() !== '');
  1724. } else if (!Array.isArray(this.form.foodLicense)) {
  1725. // 如果既不是字符串也不是数组,则初始化为空数组
  1726. this.form.foodLicense = [];
  1727. }
  1728. } else {
  1729. // 如果为空,则初始化为空数组
  1730. this.form.foodLicense = [];
  1731. }
  1732. });
  1733. },
  1734. // 验证所有执照有效性验证方法
  1735. validateLicenses() {
  1736. // 验证营业执照
  1737. if (!this.validateSingleLicense(!this.switchValue, this.form.businessLicenseExpire, "营业执照")) {
  1738. return false;
  1739. }
  1740. // 验证2类医疗器械备案
  1741. if (!this.validateSingleLicense(!this.medicalDevice2ExpiryValue, this.form.medicalDevice2Expiry, "2类医疗器械备案")) {
  1742. return false;
  1743. }
  1744. // 验证食品经营许可证/备案凭证
  1745. if (!this.validateSingleLicense(!this.foodLicenseExpiryValue, this.form.foodLicenseExpiry, "食品经营许可证/备案凭证")) {
  1746. return false;
  1747. }
  1748. // 验证药品经营许可证(无长期有效开关,直接检查有效期)
  1749. if (!this.validateLicenseWithoutSwitch(this.form.drugLicenseExpiry, "药品经营许可证")) {
  1750. return false;
  1751. }
  1752. // 验证3类器械经营许可证(无长期有效开关,直接检查有效期)
  1753. if (!this.validateLicenseWithoutSwitch(this.form.medicalDevice3Expiry, "3类器械经营许可证")) {
  1754. return false;
  1755. }
  1756. return true;
  1757. },
  1758. // 验证单个执照的方法(适用于有长期有效开关的证件)
  1759. validateSingleLicense(isExpiryRequired, expiryDateRange, licenseName) {
  1760. // 如果不是长期有效,检查是否过期
  1761. if (isExpiryRequired) {
  1762. // 检查是否设置了有效期
  1763. if (!expiryDateRange || expiryDateRange.length !== 2) {
  1764. this.$message.warning(`请设置${licenseName}的有效期!`);
  1765. return false;
  1766. }
  1767. // 获取结束日期
  1768. const endDate = new Date(expiryDateRange[1]);
  1769. // 获取当前日期
  1770. const currentDate = new Date();
  1771. // 比较日期(忽略时间部分)
  1772. endDate.setHours(0, 0, 0, 0);
  1773. currentDate.setHours(0, 0, 0, 0);
  1774. // 如果结束日期早于当前日期,说明已过期
  1775. if (endDate < currentDate) {
  1776. this.$message.warning(`${licenseName}已过期,请更新${licenseName}有效期时间或设置为长期有效!`);
  1777. return false;
  1778. }
  1779. }
  1780. return true;
  1781. },
  1782. // 验证无开关控制的证件有效期
  1783. validateLicenseWithoutSwitch(expiryDateRange, licenseName) {
  1784. // 检查是否设置了有效期
  1785. if (!expiryDateRange || expiryDateRange.length !== 2) {
  1786. this.$message.warning(`请设置${licenseName}的有效期!`);
  1787. return false;
  1788. }
  1789. // 获取结束日期
  1790. const endDate = new Date(expiryDateRange[1]);
  1791. // 获取当前日期
  1792. const currentDate = new Date();
  1793. // 比较日期(忽略时间部分)
  1794. endDate.setHours(0, 0, 0, 0);
  1795. currentDate.setHours(0, 0, 0, 0);
  1796. // 如果结束日期早于当前日期,说明已过期
  1797. if (endDate < currentDate) {
  1798. this.$message.warning(`${licenseName}已过期,请更新${licenseName}有效期时间!`);
  1799. return false;
  1800. }
  1801. return true;
  1802. },
  1803. /** 提交按钮 */
  1804. submitForm() {
  1805. this.$refs["form"].validate(valid => {
  1806. if (valid) {
  1807. // 添加所有执照有效性检查
  1808. if (!this.validateLicenses()) {
  1809. return; // 验证失败,停止提交
  1810. }
  1811. // 处理表单数据
  1812. const formData = Object.assign({}, this.form);
  1813. // 处理城市ID
  1814. if (formData.cityIds) {
  1815. formData.cityIds = formData.cityIds.toString();
  1816. }
  1817. // 处理配送方式
  1818. if (formData.shippingType) {
  1819. formData.shippingType = formData.shippingType.toString();
  1820. }
  1821. // 处理日期范围字段
  1822. const dateRangeFields = [
  1823. 'drugLicenseExpiry',
  1824. 'medicalDevice2Expiry',
  1825. 'medicalDevice1Expiry',
  1826. 'medicalDevice3Expiry',
  1827. 'foodLicenseExpiry',
  1828. 'medicalLicenseExpiry',
  1829. 'businessLicenseExpire'
  1830. ];
  1831. dateRangeFields.forEach(field => {
  1832. if (formData[field] && formData[field].length === 2) {
  1833. formData[`${field}Start`] = formData[field][0];
  1834. formData[`${field}End`] = formData[field][1];
  1835. }
  1836. });
  1837. //其他执照处理
  1838. const agreementFields = [
  1839. {
  1840. expiryField: 'settlementAgreementExpiry',
  1841. startField: 'settlementAgreementStart',
  1842. endField: 'settlementAgreementEnd',
  1843. message: '其它资质-入驻协议,有效期开始日期或结束日期不能为空!'
  1844. },
  1845. {
  1846. expiryField: 'qualityAssuranceAgreementExpiry',
  1847. startField: 'qualityAssuranceAgreementStart',
  1848. endField: 'qualityAssuranceAgreementEnd',
  1849. message: '质量保证协议,有效期开始日期或结束日期不能为空!'
  1850. },
  1851. {
  1852. expiryField: 'otherSpecialQualificationExpiry',
  1853. startField: 'otherSpecialQualificationStart',
  1854. endField: 'otherSpecialQualificationEnd',
  1855. message: '其它特殊资质,有效期开始日期或结束日期不能为空!'
  1856. }
  1857. ];
  1858. for (const field of agreementFields) {
  1859. if (formData[field.expiryField] && formData[field.expiryField].length === 2) {
  1860. formData[field.startField] = formData[field.expiryField][0];
  1861. formData[field.endField] = formData[field.expiryField][1];
  1862. } else {
  1863. if (formData[field.expiryField.replace('Expiry', '')] != null) {
  1864. return this.$message.warning(field.message);
  1865. }
  1866. }
  1867. }
  1868. // 处理各类许可证是否永久有效的开关状态
  1869. formData.isFoodLicenseExpiryPermanent = this.foodLicenseExpiryValue ? 1 : 0;
  1870. formData.isBusinessLicensePermanent = this.switchValue ? 1 : 0;
  1871. formData.isMedicalDevice1ExpiryPermanent = this.switchMedicalValue ? 1 : 0;
  1872. formData.isMedicalDevice2ExpiryPermanent = this.medicalDevice2ExpiryValue ? 1 : 0;
  1873. formData.isMedicalLicenseExpiryPermanent = this.medicalLicenseExpiryValue ? 1 : 0;
  1874. formData.isEffectivePermanent1 = this.medicalLicenseExpiryValue1 ? 1 : 0;
  1875. formData.isEffectivePermanent2 = this.medicalLicenseExpiryValue2 ? 1 : 0;
  1876. formData.isEffectivePermanent3 = this.medicalLicenseExpiryValue3 ? 1 : 0;
  1877. // 处理食品经营许可证图片数据,转换为逗号分隔的字符串
  1878. if (Array.isArray(formData.foodLicense)) {
  1879. formData.foodLicense = formData.foodLicense.join(',');
  1880. }
  1881. if (formData.storeId != null) {
  1882. updateStore(formData).then(response => {
  1883. this.msgSuccess("修改成功");
  1884. this.open = false;
  1885. this.getList();
  1886. });
  1887. } else {
  1888. addStore(formData).then(response => {
  1889. this.msgSuccess("新增成功");
  1890. this.open = false;
  1891. this.getList();
  1892. });
  1893. }
  1894. }
  1895. });
  1896. },
  1897. /** 删除按钮操作 */
  1898. handleDelete(row) {
  1899. const storeIds = row.storeId || this.ids;
  1900. this.$confirm('是否确认删除店铺管理编号为"' + storeIds + '"的数据项?', "警告", {
  1901. confirmButtonText: "确定",
  1902. cancelButtonText: "取消",
  1903. type: "warning"
  1904. }).then(function() {
  1905. return delStore(storeIds);
  1906. }).then(() => {
  1907. this.getList();
  1908. this.msgSuccess("删除成功");
  1909. }).catch(() => {
  1910. });
  1911. },
  1912. handleRefresh(row) {
  1913. const storeIds = row.storeId || this.ids;
  1914. this.$confirm('是否确认重置店铺管理编号为"' + storeIds + '"的密码为XyzAbc~12 ', "警告", {
  1915. confirmButtonText: "确定",
  1916. cancelButtonText: "取消",
  1917. type: "warning"
  1918. }).then(function() {
  1919. return refreshPasWod(storeIds);
  1920. }).then(() => {
  1921. this.getList();
  1922. this.msgSuccess("修改成功");
  1923. }).catch(() => {
  1924. });
  1925. },
  1926. /** 导出按钮操作 */
  1927. handleExport() {
  1928. const queryParams = this.queryParams;
  1929. this.$confirm('是否确认导出所有店铺管理数据项?', "警告", {
  1930. confirmButtonText: "确定",
  1931. cancelButtonText: "取消",
  1932. type: "warning"
  1933. }).then(() => {
  1934. this.exportLoading = true;
  1935. return exportStore(queryParams);
  1936. }).then(response => {
  1937. this.download(response.msg);
  1938. this.exportLoading = false;
  1939. }).catch(() => {
  1940. });
  1941. },
  1942. handleStoreExport(row){
  1943. const queryStoreId = row.storeId;
  1944. this.exportLoading = true;
  1945. exportFsStream({ queryStoreId: queryStoreId }).then(response => {
  1946. this.download(response.msg);
  1947. this.exportLoading = false;
  1948. }).catch(() => {
  1949. this.exportLoading = false;
  1950. });
  1951. },
  1952. //长期有效营业执照选择
  1953. switchChange(){
  1954. console.log(this.form.isBusinessLicensePermanent);
  1955. },
  1956. // 判断是否为图片文件(根据URL后缀)
  1957. isImageFile(url, field) {
  1958. // 若有存储的文件类型,直接用 MIME 类型判断
  1959. if (this.form[`${field}FileType`]) {
  1960. return this.form[`${field}FileType`].startsWith('image/');
  1961. }
  1962. // 后备:用 URL 后缀判断
  1963. const imageExts = ['jpg', 'jpeg', 'png', 'gif'];
  1964. const ext = url.split('.').pop()?.toLowerCase() || '';
  1965. return imageExts.includes(ext);
  1966. },
  1967. // 根据文件类型获取文档图标(优先用 MIME 类型)
  1968. getDocumentIconClass(url, field) {
  1969. // 若有存储的文件类型,直接用 MIME 类型判断
  1970. if (this.form[`${field}FileType`]) {
  1971. const fileType = this.form[`${field}FileType`];
  1972. if (fileType === 'application/msword' || fileType === 'application/vnd.openxmlformats-officedocument.wordprocessingml.document') {
  1973. return 'el-icon-document';
  1974. } else if (fileType === 'application/pdf') {
  1975. return 'el-icon-file-pdf';
  1976. }
  1977. return 'el-icon-file';
  1978. }
  1979. // 后备:用 URL 后缀判断
  1980. const ext = url.split('.').pop()?.toLowerCase() || '';
  1981. if (ext === 'doc' || ext === 'docx') {
  1982. return 'el-icon-document';
  1983. } else if (ext === 'pdf') {
  1984. return 'el-icon-file-pdf';
  1985. }
  1986. return 'el-icon-file';
  1987. },
  1988. // /// 从URL中提取文件名代码回退
  1989. getFileName(url) {
  1990. return url.split('/').pop().split('?')[0].slice(-8);
  1991. },
  1992. // 文件上传前校验
  1993. beforeFileUpload(file) {
  1994. // 校验文件类型
  1995. const acceptTypes = [
  1996. 'image/jpeg',
  1997. 'image/png',
  1998. 'image/gif',
  1999. 'application/msword',
  2000. 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
  2001. 'application/pdf'
  2002. ];
  2003. if (!acceptTypes.includes(file.type)) {
  2004. this.$message.error('请上传JPG、PNG、GIF、Word或PDF格式的文件');
  2005. return false;
  2006. }
  2007. // 2. 校验文件大小(10MB)
  2008. const maxSize = 10 * 1024 * 1024; // 10MB
  2009. if (file.size > maxSize) {
  2010. this.$message.error('文件大小不能超过10MB');
  2011. return false;
  2012. }
  2013. return true;
  2014. },
  2015. // 文件上传成功处理(复用原有逻辑,仅优化提示)
  2016. handleFileSuccess1(response, file, field) {
  2017. this.form[field] = response.url;
  2018. this.form[`${field}FileName`] = file.name;
  2019. this.form[`${field}FileType`] = file.type; // 新增:记录文件 MIME 类型
  2020. this.$message.success(`文件:${file.name}上传成功`);
  2021. },
  2022. // 文件上传失败处理
  2023. handleFileError(err, file) {
  2024. this.$message.error(`文件《${file.name}》上传失败,请重试`);
  2025. },
  2026. // 移除已上传文件
  2027. handleFileRemove(field) {
  2028. this.form[field] = '';
  2029. this.form[`${field}FileName`] = ''; // 清空文件名
  2030. this.$message.info('文件已移除');
  2031. },
  2032. handleRemove(file, fileList) {
  2033. console.log(file, fileList);
  2034. },
  2035. handlePreview(file) {
  2036. console.log(file);
  2037. },
  2038. handleExceed(files, fileList) {
  2039. this.$message.warning(`当前限制选择 1 个文件,本次选择了 ${files.length} 个文件,共选择了 ${files.length + fileList.length} 个文件`);
  2040. },
  2041. beforeRemove(file, fileList) {
  2042. return this.$confirm(`确定移除 ${ file.name }?`);
  2043. },
  2044. // 将逗号分隔的URL字符串转换为文件对象数组
  2045. urlToFileList(urlStr) {
  2046. if (!urlStr) return [];
  2047. return urlStr.split(',').map(url => {
  2048. const fileName = url.substring(url.lastIndexOf('/') + 1);
  2049. return {
  2050. name: fileName,
  2051. url: url,
  2052. uid: Date.now() + Math.random().toString(36).substr(2, 9) // 生成唯一ID
  2053. };
  2054. });
  2055. },
  2056. }
  2057. };
  2058. </script>
  2059. <style>
  2060. .file-uploader {
  2061. display: inline-block;
  2062. }
  2063. /* 已上传文件容器 */
  2064. .uploaded-file {
  2065. position: relative;
  2066. display: inline-block;
  2067. cursor: default;
  2068. }
  2069. /* 已上传图片样式 */
  2070. .uploaded-img {
  2071. width: 150px;
  2072. height: 150px;
  2073. border-radius: 4px;
  2074. border: 1px solid #e4e7ed;
  2075. vertical-align: middle;
  2076. }
  2077. /* 文档图标容器 */
  2078. /* 文档图标容器 */
  2079. .document-icon {
  2080. width: 150px;
  2081. height: 150px;
  2082. border: 1px solid #e4e7ed;
  2083. border-radius: 4px;
  2084. display: flex;
  2085. flex-direction: column;
  2086. align-items: center;
  2087. justify-content: center;
  2088. background-color: #f5f7fa;
  2089. vertical-align: middle;
  2090. }
  2091. .document-icon .icon {
  2092. font-size: 36px;
  2093. color: #409eff;
  2094. margin-bottom: 8px;
  2095. font-family: "element-icons" !important; /* 强制使用 Element 图标字体 */
  2096. display: inline-block; /* 确保图标正常渲染 */
  2097. font-style: normal;
  2098. font-weight: normal;
  2099. font-variant: normal;
  2100. text-transform: none;
  2101. line-height: 1;
  2102. vertical-align: baseline;
  2103. -webkit-font-smoothing: antialiased; /* 优化渲染 */
  2104. -moz-osx-font-smoothing: grayscale; /* Firefox 优化渲染 */
  2105. }
  2106. .document-icon .file-name {
  2107. font-size: 12px;
  2108. color: #606266;
  2109. white-space: nowrap;
  2110. overflow: hidden;
  2111. text-overflow: ellipsis;
  2112. width: 80%;
  2113. text-align: center;
  2114. }
  2115. /* 删除图标 */
  2116. .delete-icon {
  2117. position: absolute;
  2118. top: -8px;
  2119. right: -8px;
  2120. width: 20px;
  2121. height: 20px;
  2122. line-height: 20px;
  2123. text-align: center;
  2124. background-color: #f56c6c;
  2125. color: #fff;
  2126. border-radius: 50%;
  2127. cursor: pointer;
  2128. font-size: 12px;
  2129. box-shadow: 0 2px 4px rgba(0,0,0,0.1);
  2130. }
  2131. /* 上传按钮(外层正方形边框) */
  2132. .upload-btn {
  2133. width: 150px;
  2134. height: 150px;
  2135. /* 正方形边框 - 实线边框,默认灰色 */
  2136. border: 1px solid #dcdfe6;
  2137. border-radius: 4px;
  2138. display: flex;
  2139. align-items: center;
  2140. justify-content: center;
  2141. cursor: pointer;
  2142. transition: all 0.3s;
  2143. }
  2144. /* 上传按钮 hover 效果(边框变色) */
  2145. .upload-btn:hover {
  2146. border-color: #409eff;
  2147. background-color: #f0f7ff; /* 轻微背景色变化,增强交互感 */
  2148. }
  2149. /* 上传按钮内部内容容器 */
  2150. .upload-btn-inner {
  2151. display: flex;
  2152. flex-direction: column;
  2153. align-items: center;
  2154. justify-content: center;
  2155. color: #c0c4cc;
  2156. }
  2157. .upload-btn-inner i {
  2158. font-size: 28px;
  2159. margin-bottom: 8px;
  2160. }
  2161. .upload-btn-inner .upload-tip {
  2162. font-size: 12px;
  2163. }
  2164. /* 上传说明 */
  2165. .upload-desc {
  2166. margin-top: 8px;
  2167. font-size: 12px;
  2168. color: #909399;
  2169. }
  2170. .avatar-uploader .el-upload {
  2171. border: 1px dashed #d9d9d9;
  2172. border-radius: 6px;
  2173. cursor: pointer;
  2174. position: relative;
  2175. overflow: hidden;
  2176. }
  2177. .avatar-uploader .el-upload:hover {
  2178. border-color: #409EFF;
  2179. }
  2180. .avatar-uploader-icon {
  2181. font-size: 28px;
  2182. color: #8c939d;
  2183. width: 150px;
  2184. height: 150px;
  2185. line-height: 150px !important;
  2186. text-align: center;
  2187. }
  2188. .el-divider__text {
  2189. font-size: 16px;
  2190. font-weight: bold;
  2191. }
  2192. /* LOGO上传区域样式优化 */
  2193. .avatar-wrapper {
  2194. position: relative;
  2195. display: inline-block;
  2196. }
  2197. .avatar {
  2198. width: 200px;
  2199. height: 200px;
  2200. object-fit: cover;
  2201. border-radius: 4px;
  2202. }
  2203. .delete-mask {
  2204. position: absolute;
  2205. top: 0;
  2206. left: 0;
  2207. width: 100%;
  2208. height: 100%;
  2209. background-color: rgba(0, 0, 0, 0.5);
  2210. color: white;
  2211. display: flex;
  2212. align-items: center;
  2213. justify-content: center;
  2214. font-size: 24px;
  2215. opacity: 0;
  2216. cursor: pointer;
  2217. transition: opacity 0.3s ease;
  2218. border-radius: 4px;
  2219. }
  2220. .avatar-wrapper:hover .delete-mask {
  2221. opacity: 1;
  2222. }
  2223. .avatar-uploader {
  2224. display: inline-block;
  2225. }
  2226. .agreement-section {
  2227. border: 1px solid #ebeef5;
  2228. border-radius: 4px;
  2229. padding: 15px;
  2230. margin-bottom: 20px;
  2231. background-color: #fafafa;
  2232. }
  2233. .agreement-section .agreement-title {
  2234. margin-bottom: 10px;
  2235. }
  2236. .agreement-section .el-form-item {
  2237. margin-bottom: 15px;
  2238. }
  2239. .agreement-section .el-form-item__label {
  2240. font-weight: normal;
  2241. }
  2242. .agreement-section .el-date-editor.el-input__inner {
  2243. width: 100%;
  2244. }
  2245. .agreement-section .el-date-editor--daterange.el-input__inner {
  2246. width: 100%;
  2247. }
  2248. /* 并排按钮样式 */
  2249. .button-group {
  2250. position: absolute;
  2251. top: 10px;
  2252. right: 10px;
  2253. display: flex;
  2254. gap: 5px;
  2255. }
  2256. .preview-btn,
  2257. .delete-btn {
  2258. width: 30px;
  2259. height: 30px;
  2260. border-radius: 50%;
  2261. background-color: rgba(0, 0, 0, 0.5);
  2262. color: white;
  2263. display: flex;
  2264. align-items: center;
  2265. justify-content: center;
  2266. cursor: pointer;
  2267. font-size: 16px;
  2268. transition: background-color 0.3s;
  2269. }
  2270. .preview-btn:hover {
  2271. background-color: rgba(0, 0, 0, 0.7);
  2272. }
  2273. .delete-btn:hover {
  2274. background-color: #f56c6c;
  2275. }
  2276. /* 无图片占位符样式 */
  2277. .no-image-placeholder {
  2278. width: 200px;
  2279. height: 200px;
  2280. border: 1px dashed #d9d9d9;
  2281. border-radius: 6px;
  2282. display: flex;
  2283. align-items: center;
  2284. justify-content: center;
  2285. color: #999;
  2286. background-color: #fafafa;
  2287. }
  2288. .small-placeholder {
  2289. width: 150px;
  2290. height: 150px;
  2291. }
  2292. .avatar-wrapper {
  2293. position: relative;
  2294. display: inline-block;
  2295. }
  2296. .avatar {
  2297. width: 200px;
  2298. height: 200px;
  2299. object-fit: cover;
  2300. border-radius: 4px;
  2301. }
  2302. .small-avatar {
  2303. width: 150px;
  2304. height: 150px;
  2305. }
  2306. /* 食品经营许可证容器 */
  2307. .food-license-container {
  2308. display: flex;
  2309. flex-direction: row;
  2310. flex-wrap: wrap;
  2311. gap: 10px;
  2312. align-items: flex-start;
  2313. justify-content: flex-start;
  2314. }
  2315. /* 食品经营许可证单项 */
  2316. .food-license-item {
  2317. position: relative;
  2318. display: inline-block;
  2319. text-align: center;
  2320. }
  2321. /* 添加按钮样式 */
  2322. .add-btn {
  2323. display: flex;
  2324. align-items: center;
  2325. justify-content: center;
  2326. cursor: pointer;
  2327. border: 1px dashed #d9d9d9;
  2328. background-color: #fafafa;
  2329. width: 150px;
  2330. height: 150px;
  2331. }
  2332. .add-btn:hover {
  2333. border-color: #409EFF;
  2334. background-color: #f0f7ff;
  2335. }
  2336. </style>