detail.vue 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753
  1. <template>
  2. <headerBar title="主图与详情生成" :menu="[
  3. {
  4. type: 'setting'
  5. }
  6. ]" />
  7. <div class="detail-container">
  8. <div>
  9. <!-- 主图LOGO部分 -->
  10. <div class="logo-section flex left top">
  11. <div class="section-title">
  12. <img src="@/assets/images/Photography/zhuangshi.png" style="width: 32px; height: 32px;" />
  13. 主图LOGO:
  14. </div>
  15. </div>
  16. <div class="logo-section flex left top">
  17. <upload :value="form.logo_path" @input="onInput"></upload>
  18. </div>
  19. <el-divider />
  20. <!-- 图片抠图与货号图生成 -->
  21. <div class="section">
  22. <div class="section-title">
  23. <img src="@/assets/images/Photography/zhuangshi.png" style="width: 32px; height: 32px;" />
  24. 图片抠图与货号图生成
  25. </div>
  26. <div class="section-content">
  27. <div v-if="showTips" class="instruction-out flex top left">
  28. <img style="fill: #000" src="@/assets/images/xinxi.svg" />
  29. <ol class="instruction-list">
  30. <li>请在下方确认图片拍摄过程中的顺序,确保所有拍摄的图片的顺序一致。</li>
  31. <li>使用中英文语号分隔。</li>
  32. <li>图片的名称不能随意修改,否则无法正常生成详情页。</li>
  33. <li>现有图片名称有:俯视、侧视、后视、鞋底、内里</li>
  34. </ol>
  35. <el-icon @click="showTips = false" class="close-icon">
  36. <Close />
  37. </el-icon>
  38. </div>
  39. <!-- 货号文件夹 -->
  40. <!-- <div class="form-item">
  41. <div class="label">货号文件夹:</div>
  42. <div class="folder-warp">
  43. <div class="folder-input">
  44. <el-input style="width: 60%;" v-model="folderPath" type="textarea" :rows="2" readonly
  45. placeholder="请选择货号文件夹" />
  46. <el-button class="check-button" type="primary" @click="selectFolder">
  47. <img src="@/assets/images/Photography/wenjian.png" style="width: 14px; " />
  48. 选择目标文件夹</el-button>
  49. </div>
  50. <div class="hint">
  51. <el-icon>
  52. <Warning />
  53. </el-icon> <text>选择货号的上级文件夹</text>
  54. </div>
  55. </div>
  56. </div>
  57. -->
  58. </div>
  59. </div>
  60. <el-divider />
  61. <!-- 选择详情模板部分 -->
  62. <div class="template-section ">
  63. <div class="flex between">
  64. <div class="section-title">
  65. <img src="@/assets/images/Photography/zhuangshi.png" style="width: 32px; height: 32px;" />
  66. 选择详情模版
  67. </div>
  68. <div class="template-pagination">
  69. <el-pagination background layout="prev, pager, next" v-model:current-page="queryParams.current"
  70. v-model:page-size.sync="queryParams.size" :total="totalPage" @current-change="onCurrentChange"
  71. @size-change="onSizeChange" />
  72. </div>
  73. </div>
  74. <div class="template-list">
  75. <div v-for="(template, index) in visibleTemplates" :key="index" class="template-item"
  76. @click="form.selectTemplate = template">
  77. <el-image :src="template.template_cover_image" fit="contain" class="cur-p"
  78. style="width: 100%; display: block;" />
  79. <div class="select-warp" :class="form.selectTemplate.id == template.id ? 'active' : ''">
  80. <el-icon color="#FFFFFF">
  81. <Select />
  82. </el-icon>
  83. </div>
  84. <div class="template-info">
  85. <span class="mar-left-10 chaochu_1">{{ template.template_name }}</span>
  86. <div class="template-view" @click="viewTemplate(template)">查看</div>
  87. </div>
  88. </div>
  89. </div>
  90. </div>
  91. <el-divider />
  92. <!-- 详情高级配置 -->
  93. <div class="section">
  94. <div class="section-title">
  95. <img src="@/assets/images/Photography/zhuangshi.png" style="width: 32px; height: 32px;" />
  96. 详情高级配置
  97. </div>
  98. <div class="section-content">
  99. <!-- 图片顺序 -->
  100. <div class="form-item">
  101. <div class="label">图片顺序:</div>
  102. <el-input v-model="imageOrder" placeholder="请输入图片顺序" class="specific-page-input">
  103. <template #append>
  104. <el-button class="explain-btn" link type="primary">说明</el-button>
  105. </template>
  106. </el-input>
  107. </div>
  108. <!-- 同款检验 -->
  109. <!-- <div class="form-item">
  110. <div class="label">同款检验:</div>
  111. <el-checkbox v-model="checkSimilar">同款下货号必须齐全</el-checkbox>
  112. </div>
  113. -->
  114. <!-- 可指定页面独修改 -->
  115. <!-- <div class="form-item">
  116. <div class="label">可指定页面独修改:</div>
  117. <el-input v-model="specificPage" placeholder="请输入入需要单独修改的页面,示例:4:1 (需修改模版的编号:第一张)"
  118. class="specific-page-input">
  119. <template #append>
  120. <el-button class="explain-btn" link type="primary">说明</el-button>
  121. </template>
  122. </el-input>
  123. </div>
  124. -->
  125. </div>
  126. </div>
  127. <el-divider />
  128. <!-- 详情资料准备部分 -->
  129. <div class="data-prep-section">
  130. <div class="flex-item left">
  131. <div class="section-title">
  132. <img src="@/assets/images/Photography/zhuangshi.png" style="width: 32px; height: 32px;" />
  133. 详情资料准备 (2选1)
  134. <el-button v-if="form.dataType == '1'" type="text" class="mar-left-10 fs-16" @click="downloadExcel">下载商品基础资料模版</el-button>
  135. </div>
  136. </div>
  137. <div class="flex-item left">
  138. <el-radio-group v-model="form.dataType" class="ml-4">
  139. <el-radio label="1" size="large">EXCEL文件选择</el-radio>
  140. <el-radio label="2" size="large">系统对接(和业务员联系)</el-radio>
  141. </el-radio-group>
  142. </div>
  143. <div v-if="form.dataType == '1'" class="excel-upload">
  144. <div class="flex bottom between">
  145. <div style="max-width: 160px;" class="mar-left-20">商品基础资料EXCEL文件选择:</div>
  146. <div class="flex bottom mar-left-20" style="flex-grow: 1;">
  147. <el-input type="textarea" v-model="form.excel_path" />
  148. </div>
  149. <el-button class="select-button button--primary1 mar-left-20" type="primary" @click="selectExcel">
  150. <img src="@/assets/images/Photography/wenjian.png" style="width: 16px; margin-right: 4px;" />
  151. 选择</el-button>
  152. </div>
  153. </div>
  154. </div>
  155. </div>
  156. <!-- 底部按钮 -->
  157. <div class="footer">
  158. <!-- <el-button class="button--primary1 footer-button" type="primary" @click="saveConfig">保存配置</el-button> -->
  159. <!-- <el-button class="button--primary1 footer-button" type="primary" @click="startProcess">开始处理</el-button> -->
  160. <el-button class="button--primary1 footer-button" type="primary" @click="generate">开始生成</el-button>
  161. </div>
  162. </div>
  163. <loading-dialog v-if="loadingDialogVisible" v-model="loadingDialogVisible" :requesting="requesting" :progress="progress" :message="message"
  164. :disabled-button="disabledButton" @button-click="handleComplete">
  165. <template v-if="partErrList && partErrList.length > 0" #errList>
  166. <div v-for="(item, idx) in partErrList" :key="idx">
  167. <span>{{ item.goods_art_no }}</span>:<span>{{ item.info }}</span>
  168. </div>
  169. </template>
  170. </loading-dialog>
  171. <el-dialog v-model="dialogVisible">
  172. <img style="width: 100%;" :src="dialogImageUrl" alt="Preview Image" />
  173. </el-dialog>
  174. </template>
  175. <script lang="ts" setup>
  176. import { getCompanyTemplatesApi } from '@/apis/other'
  177. import tokenInfo from '@/stores/modules/token';
  178. import useUserInfo from "@/stores/modules/user";
  179. import { useRoute, useRouter } from 'vue-router'
  180. import { ElMessage, ElMessageBox } from 'element-plus'
  181. import headerBar from '@/components/header-bar/index.vue'
  182. import { ref, computed, reactive, onMounted } from 'vue';
  183. import { Select } from '@element-plus/icons-vue'
  184. import upload from '@/components/upload'
  185. import client from "@/stores/modules/client";
  186. import icpList from '@/utils/ipc'
  187. const clientStore = client();
  188. import { getRouterUrl } from '@/utils/appfun'
  189. import { Close, Warning } from '@element-plus/icons-vue'
  190. import LoadingDialog from '@/views/Photography/components/LoadingDialog.vue'
  191. import { useCheckInfo } from '@/composables/userCheck';
  192. useCheckInfo();
  193. const showTips = ref(true)
  194. const folderPath = ref('') //货号文件夹
  195. // const reportMode = ref('normal') // 抠图模式
  196. const imageOrder = ref('俯视、侧视、后跟、鞋底、内里、组合、组合2、组合3') // 图片顺序
  197. const checkSimilar = ref(false) // 同款检验
  198. const specificPage = ref('') // 可指定页面独修改
  199. // 路由和状态管理初始化
  200. const route = useRoute();
  201. const router = useRouter();
  202. // 完成目录
  203. const completeDirectory = ref('')
  204. const loadingDialogVisible = ref(false)
  205. const progress = ref(0)
  206. const message = ref('正在为您处理,请稍后')
  207. const disabledButton = ref(true)
  208. let templates = ref([])
  209. let goods_art_nos = ref([])
  210. let partErrList = ref([])
  211. const excel_template_url = ref('')
  212. // 是否正在请求接口
  213. const requesting = ref(false)
  214. // 定义一个定时器变量
  215. const INTERVAL = ref<number | NodeJS.Timeout | null>(null);
  216. // 状态变量
  217. const totalPage = ref(0);
  218. const itemsPerPage = 4; // 每页显示的模板数量
  219. const dialogVisible = ref(false);
  220. const dialogImageUrl = ref('');
  221. const queryParams = reactive({ // 分页查询参数
  222. size: 1,
  223. current: 1,
  224. })
  225. const form = reactive({
  226. selectTemplate: {}, //选中的模板
  227. dataType: '1', // 1: 选择excel文件 2: 系统对接
  228. logo_path: '', // 主图LOGO
  229. excel_path: '', // 商品基础资料EXCEL文件选择
  230. })
  231. onMounted(() => {
  232. const goods_art_data = route.query.goods_art_nos
  233. goods_art_nos.value = Array.isArray(goods_art_data) ? goods_art_data : [goods_art_data]
  234. getCompanyTemplates()
  235. })
  236. // 计算属性,获取当前页可见的模板
  237. const visibleTemplates = computed(() => {
  238. const startIndex = (queryParams.current - 1) * itemsPerPage;
  239. const data = templates.value.slice(startIndex, startIndex + itemsPerPage);
  240. return data
  241. });
  242. // 查看模板详情
  243. const viewTemplate = (template) => {
  244. // 展示大图
  245. dialogVisible.value = true
  246. dialogImageUrl.value = template.template_preview_image
  247. };
  248. // 获取模版列表
  249. const getCompanyTemplates = async () => {
  250. const { data } = await getCompanyTemplatesApi()
  251. templates.value = data.list
  252. // 默认选中第一个模板
  253. if (templates.value.length > 0) {
  254. form.selectTemplate = templates.value[0]
  255. }
  256. excel_template_url.value = data.excel_template_url
  257. // 计算总页数
  258. totalPage.value = Math.ceil(templates.value.length / itemsPerPage);
  259. }
  260. const downloadExcel = () => {
  261. const a = document.createElement('a')
  262. a.href = excel_template_url.value,
  263. a.download = '商品基础资料模版'
  264. document.body.appendChild(a)
  265. a.click()
  266. setTimeout(() => {
  267. document.body.removeChild(a);
  268. }, 1000);
  269. }
  270. const onCurrentChange = (page) => {
  271. queryParams.current = page;
  272. };
  273. const onSizeChange = (data) => {
  274. };
  275. // 开始生成操作
  276. const generate = async function () {
  277. const tokenInfoStore = tokenInfo();
  278. const token = tokenInfoStore.getToken; // 使用 getToken() 获取 token
  279. let temp_list = []
  280. templates.value.map(item => {
  281. temp_list.push({
  282. template_id: item.template_id,
  283. template_local_classes: item.template_local_classes,
  284. })
  285. })
  286. const params = {
  287. goods_art_no: JSON.parse(JSON.stringify(goods_art_nos.value)),
  288. logo_path: form.logo_path || '',
  289. temp_name: form.selectTemplate.template_id || '',
  290. excel_path: form.dataType == '1' ? form.excel_path : '',
  291. template_image_order: form.selectTemplate.template_image_order,
  292. temp_list,
  293. token,
  294. }
  295. // 开启进度弹窗
  296. progress.value = 0
  297. openLoadingDialog(20)
  298. requesting.value = true
  299. console.log("params", "color:#3f7cff", params);
  300. clientStore.ipc.removeAllListeners(icpList.generate.generatePhotoDetail);
  301. clientStore.ipc.send(icpList.generate.generatePhotoDetail, params);
  302. clientStore.ipc.on(icpList.generate.generatePhotoDetail, (event, result) => {
  303. console.log('result', result)
  304. requesting.value = false
  305. partErrList.value = []
  306. clientStore.ipc.removeAllListeners(icpList.generate.generatePhotoDetail);
  307. clearInterval(INTERVAL.value)
  308. if (result.code === 0) {
  309. const { output_folder, list } = result.data
  310. const allSuccess = list.every(item => item.success);
  311. const allFailure = list.every(item => !item.success);
  312. if (allSuccess) {
  313. console.log("全部成功")
  314. handleSuccess(output_folder, '全部生成成功')
  315. } else if (allFailure) {
  316. console.log("全部失败");
  317. handleFailure(list)
  318. } else {
  319. console.log("部分成功,部分失败");
  320. handlePartSuccess(output_folder, list)
  321. }
  322. } else {
  323. console.log('code全部生成失败')
  324. handleFail(result.msg)
  325. }
  326. //生成失败 (接口请求失败)
  327. function handleFail(errorMsg: string) {
  328. loadingDialogVisible.value = false
  329. disabledButton.value = false
  330. if (errorMsg) {
  331. ElMessage.error(errorMsg)
  332. }
  333. }
  334. // 全部生成成功
  335. function handleSuccess(href, loadingMsg) {
  336. completeDirectory.value = href
  337. progress.value = 100
  338. disabledButton.value = false
  339. message.value = loadingMsg
  340. }
  341. // 部分成功
  342. function handlePartSuccess(output_folder: string, partSuccessList) {
  343. let errorList = []
  344. partSuccessList.map(item => {
  345. if (!item.success) {
  346. errorList.push(item)
  347. }
  348. })
  349. partErrList.value = errorList
  350. handleSuccess(output_folder, '部分货号生成失败')
  351. }
  352. // 全部生成失败
  353. function handleFailure(partSuccessList) {
  354. let errorList = []
  355. partSuccessList.map(item => {
  356. if (!item.success) {
  357. errorList.push(item)
  358. }
  359. })
  360. partErrList.value = errorList
  361. completeDirectory.value = ''
  362. progress.value = 100
  363. disabledButton.value = true
  364. message.value = '全部货号生成失败'
  365. }
  366. });
  367. }
  368. const openLoadingDialog = (timer: number) => {
  369. loadingDialogVisible.value = true
  370. disabledButton.value = true
  371. // 根据传入的秒数计算每次增加的进度值
  372. const step = 100 / timer
  373. INTERVAL.value = setInterval(() => {
  374. if (progress.value < 100) {
  375. progress.value = Math.round(progress.value + step)
  376. }
  377. }, 1000)
  378. }
  379. const onInput = (value) => {
  380. form.logo_path = value
  381. }
  382. function selectExcel() {
  383. clientStore.ipc.removeAllListeners(icpList.utils.openFile);
  384. clientStore.ipc.send(icpList.utils.openFile, {
  385. filters: [
  386. { name: '支持xls,xlsx', extensions: ['xlsx', 'xls'] }
  387. ],
  388. title: "选择基础文件资料"
  389. });
  390. clientStore.ipc.on(icpList.utils.openFile, async (event, result) => {
  391. form.excel_path = result
  392. clientStore.ipc.removeAllListeners(icpList.utils.openFile);
  393. })
  394. }
  395. const Router = useRouter()
  396. //打开主图详情
  397. function openPhotographySeniorDetail() {
  398. const { href } = Router.resolve({
  399. name: 'PhotographySeniorDetail'
  400. })
  401. clientStore.ipc.removeAllListeners(icpList.utils.openMain);
  402. let params = {
  403. title: '详情高级配置',
  404. width: 1000,
  405. height: 630,
  406. frame: true,
  407. id: "PhotographySeniorDetail",
  408. url: getRouterUrl(href)
  409. }
  410. clientStore.ipc.send(icpList.utils.openMain, params);
  411. }
  412. const handleComplete = () => {
  413. loadingDialogVisible.value = false
  414. // 这里可以添加打开目录的逻辑
  415. clientStore.ipc.removeAllListeners(icpList.utils.shellFun);
  416. let params = {
  417. action: 'openPath',
  418. params: completeDirectory.value?.replaceAll('/', '\\')
  419. }
  420. clientStore.ipc.send(icpList.utils.shellFun, params);
  421. }
  422. const selectFolder = () => {
  423. clientStore.ipc.removeAllListeners(icpList.utils.openDirectory);
  424. clientStore.ipc.send(icpList.utils.openDirectory);
  425. clientStore.ipc.on(icpList.utils.openDirectory, async (event, result) => {
  426. folderPath.value = result
  427. clientStore.ipc.removeAllListeners(icpList.utils.openDirectory);
  428. })
  429. }
  430. </script>
  431. <style lang="scss" scoped>
  432. .detail-container {
  433. background-color: #EAECED;
  434. width: 100%;
  435. min-width: 600px;
  436. padding: 20px;
  437. overflow: hidden;
  438. }
  439. .logo-section,
  440. .template-section,
  441. .data-prep-section {
  442. margin-bottom: 20px;
  443. }
  444. .logo-upload {
  445. border: 1px dashed #ccc;
  446. border-radius: 5px;
  447. padding: 50px 0;
  448. text-align: center;
  449. cursor: pointer;
  450. }
  451. .template-pagination button {
  452. margin-right: 5px;
  453. }
  454. .template-pagination span {
  455. display: inline-block;
  456. width: 20px;
  457. height: 20px;
  458. line-height: 20px;
  459. text-align: center;
  460. border: 1px solid #ccc;
  461. border-radius: 5px;
  462. margin-right: 5px;
  463. cursor: pointer;
  464. }
  465. .template-list {
  466. display: flex;
  467. flex-wrap: wrap;
  468. gap: 20px;
  469. margin-top: 10px;
  470. .template-item {
  471. width: calc(25% - 18px);
  472. border: 1px solid #ccc;
  473. border-radius: 10px;
  474. cursor: pointer;
  475. background: #f0f0f0;
  476. position: relative;
  477. overflow: hidden;
  478. .template-info {
  479. position: absolute;
  480. bottom: 0;
  481. left: 0;
  482. background: rgba($color: #000000, $alpha: .3);
  483. width: 100%;
  484. height: 36px;
  485. line-height: 36px;
  486. color: #eee;
  487. display: flex;
  488. align-items: center;
  489. justify-content: space-between;
  490. .template-view {
  491. background: #DFE2E3;
  492. color: #3366FF;
  493. height: 30px;
  494. line-height: 30px;
  495. padding: 0 10px;
  496. border-radius: 4px;
  497. margin-right: 10px;
  498. font-size: 14px;
  499. }
  500. }
  501. }
  502. }
  503. .excel-upload {
  504. width: 100%;
  505. background: #F7F7F7;
  506. padding: 20px 0;
  507. }
  508. .generate-button {
  509. padding: 10px 20px;
  510. color: white;
  511. border: none;
  512. border-radius: 5px;
  513. cursor: pointer;
  514. }
  515. .select-button {
  516. background: #DFE2E3 !important;
  517. color: #3366FF !important;
  518. height: 30px;
  519. line-height: 30px;
  520. padding: 0 10px;
  521. border-radius: 4px;
  522. margin-right: 10px;
  523. font-size: 14px;
  524. font-weight: 550;
  525. }
  526. .select-warp {
  527. width: 18px;
  528. height: 18px;
  529. border-radius: 4px;
  530. background-color: #fff;
  531. position: absolute;
  532. top: 10px;
  533. left: 10px;
  534. &.active {
  535. background-color: #1677FF;
  536. }
  537. }
  538. .section-title {
  539. display: flex;
  540. align-items: center;
  541. gap: 8px;
  542. font-weight: bold;
  543. margin-bottom: 16px;
  544. color: #474747;
  545. }
  546. .section {
  547. margin-bottom: 24px;
  548. .section-title {
  549. display: flex;
  550. align-items: center;
  551. gap: 8px;
  552. font-weight: bold;
  553. margin-bottom: 16px;
  554. color: #474747;
  555. }
  556. .section-content {
  557. padding-left: 16px;
  558. }
  559. }
  560. .instruction-out {
  561. background: #EAF3FF;
  562. border-radius: 4px;
  563. border: 1px solid #CBE1FF;
  564. padding: 10px 20px;
  565. width: 80%;
  566. position: relative;
  567. .instruction-list {
  568. margin: 0px 0 0 10px;
  569. padding-left: 20px;
  570. padding-right: 40px;
  571. width: 100%;
  572. li {
  573. margin-bottom: 4px;
  574. text-align: left;
  575. font-size: 14px;
  576. }
  577. }
  578. .close-icon {
  579. position: absolute;
  580. top: 12px;
  581. right: 19px;
  582. }
  583. }
  584. .form-item {
  585. margin: 16px 0;
  586. display: flex;
  587. .label {
  588. min-width: 120px;
  589. margin-right: 12px;
  590. }
  591. .folder-warp {
  592. width: 100%;
  593. display: flex;
  594. flex-direction: column;
  595. .folder-input {
  596. flex: 1;
  597. display: flex;
  598. align-items: center;
  599. .check-button {
  600. background: #DFE2E3;
  601. border-radius: 6px;
  602. padding: 6px 12px;
  603. color: #2957FF;
  604. margin-left: 20px;
  605. }
  606. }
  607. }
  608. .hint {
  609. text-align: left;
  610. color: #999;
  611. margin-top: 6px;
  612. font-size: 14px;
  613. color: #FF4C00;
  614. font-style: normal;
  615. }
  616. .specific-page-input {
  617. flex: 1;
  618. }
  619. }
  620. .image-order {
  621. flex: 1;
  622. display: flex;
  623. justify-content: space-between;
  624. align-items: center;
  625. }
  626. .footer {
  627. display: flex;
  628. justify-content: center;
  629. margin-top: 24px;
  630. .footer-button {
  631. padding: 10px 20px;
  632. }
  633. }
  634. .explain-btn {
  635. padding-left: 20px;
  636. padding-right: 20px;
  637. color: #2957FF !important;
  638. }
  639. </style>