index.vue 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613
  1. <template>
  2. <div class="mainContentBox">
  3. <avue-crud
  4. ref="crudRef"
  5. v-model:search="search"
  6. v-model="form"
  7. :data="data"
  8. :option="option"
  9. v-model:page="page"
  10. @row-save="createRow"
  11. @row-update="updateRow"
  12. @row-del="deleteRow"
  13. @search-change="searchChange"
  14. @search-reset="resetChange"
  15. @size-change="dataList"
  16. @current-change="dataList"
  17. @selection-change="selectionChange"
  18. >
  19. <template #menu-left="{ size }">
  20. <el-button
  21. type="primary"
  22. icon="el-icon-plus"
  23. :size="size"
  24. @click="openDialog(0,null)"
  25. >新增</el-button>
  26. <el-button
  27. :disabled="toDeleteIds.length < 1"
  28. type="danger"
  29. icon="el-icon-delete"
  30. :size="size"
  31. @click="multipleDelete"
  32. >删除</el-button
  33. >
  34. </template>
  35. <template #menu="{size,row,index}">
  36. <el-button
  37. type="info"
  38. link
  39. size="small"
  40. @click="openDialog(1,row)"
  41. ><i-ep-edit />查看</el-button>
  42. <el-button
  43. type="primary"
  44. link
  45. size="small"
  46. @click="openDialog(2,row)"
  47. ><i-ep-edit />{{row.state === '0' ? '编辑' : '流程'}}</el-button>
  48. </template>
  49. </avue-crud>
  50. <el-dialog
  51. v-model="dialog.visible"
  52. :title="dialog.title"
  53. width="75%"
  54. @close="dialog.visible = false"
  55. >
  56. <template #header="{ close, titleId, titleClass }">
  57. <el-button v-if="dialogType === 1" type="primary" @click="printPage" size="small">打印</el-button>
  58. </template>
  59. <div class="card-container" >
  60. <el-card style="width: 70%" shadow="always">
  61. <div ref="toPrintRef">
  62. <el-row style="text-align: center;">
  63. <el-col :span="24"><el-text tag="b">零、部(组)件领用单</el-text></el-col>
  64. </el-row>
  65. <el-row>
  66. <el-col :span="14" ></el-col>
  67. <el-col :span="5" ><el-text tag="p" v-if="form.applyCode">{{form.applyCode}}</el-text></el-col>
  68. <el-col :span="5"></el-col>
  69. </el-row>
  70. <el-row style="width: 100%;height: 30px;"></el-row>
  71. <el-row>
  72. <el-col :span="2" ><el-text tag="p">领用单位:</el-text></el-col>
  73. <el-col :span="6" >
  74. <el-text tag="p" v-if="dialogType === 1 || form.state > 0">{{form.applyOrg}}</el-text>
  75. <el-input v-else size="small" style="width:150px;padding-bottom: 5px;" v-model="form.applyOrg"/>
  76. </el-col>
  77. <el-col :span="2" ><el-text tag="p">发件单位: </el-text></el-col>
  78. <el-col :span="6" >
  79. <el-text tag="p" v-if="dialogType === 1 || form.state > 0">{{form.sendOrg}} </el-text>
  80. <el-input v-else size="small" style="width:150px;padding-bottom: 5px;" v-model="form.sendOrg"/>
  81. </el-col>
  82. <el-col :span="2" ><el-text tag="p">工单编号:</el-text></el-col>
  83. <el-col :span="6">
  84. <el-text tag="p" v-if="dialogType === 1 || form.state > 0">{{form.workOrderCode}}</el-text>
  85. <el-select
  86. v-else
  87. size="small"
  88. v-model="form.workOrderCode"
  89. placeholder="请选择工单号"
  90. clearable
  91. style="width:150px;padding-bottom: 5px;"
  92. filterable
  93. @change="changeOrder"
  94. >
  95. <el-option
  96. v-for="option in orderList"
  97. :key="option.workOrderCode"
  98. :label="option.workOrderCode"
  99. :value="option.workOrderCode"
  100. />
  101. </el-select>
  102. </el-col>
  103. </el-row>
  104. <el-table class="print-table"
  105. v-loading="loading"
  106. :data="tableDataList"
  107. border
  108. >
  109. <el-table-column label="序号" type="index" width="60"/>
  110. <el-table-column label="工作令号" prop="workCode">
  111. <template v-slot="{row}">
  112. <el-text v-if="dialogType === 1 || form.state > 0">{{row.workCode}}</el-text>
  113. <el-input v-else v-model="row.workCode"/>
  114. </template>
  115. </el-table-column>
  116. <el-table-column label="零、部(组)件图号" prop="materialCode" />
  117. <el-table-column label="名称" prop="materialName" />
  118. <el-table-column label="数量" align="num">
  119. <template v-slot="{row}">
  120. <el-text v-if="dialogType === 1 || form.state > 0">{{row.num}}</el-text>
  121. <el-input v-else v-model="row.num" type="number"/>
  122. </template>
  123. </el-table-column>
  124. <el-table-column label="实际接收" align="receiveNum" v-if="form.state === '6' || form.state === '8'">
  125. <template v-slot="{row}">
  126. <el-text>{{row.receiveNum}}</el-text>
  127. </template>
  128. </el-table-column>
  129. <el-table-column label="备注" align="remark">
  130. <template v-slot="{row}">
  131. <el-text v-if="dialogType === 1 || form.state > 0">{{row.remark}}</el-text>
  132. <el-input v-else v-model="row.remark"/>
  133. </template>
  134. </el-table-column>
  135. <el-table-column label="操作" align="remark" v-if="dialogType !== 1 && form.state === '0'">
  136. <template v-slot="{row,index}">
  137. <el-button type="danger" @click="minusItem(row)" icon="el-icon-minus" style="margin-left:15px;width:25px;height:25px;" circle />
  138. </template>
  139. </el-table-column>
  140. </el-table>
  141. <el-row>
  142. <el-col :span="2" ><el-text tag="p">领用人:</el-text></el-col>
  143. <el-col :span="4" ><el-text tag="p" >{{form.applyUser}}</el-text></el-col>
  144. <el-col :span="2" ><el-text tag="p">审核: </el-text></el-col>
  145. <el-col :span="4" ><el-text tag="p" >{{form.auditUser}} </el-text></el-col>
  146. <el-col :span="2" ><el-text tag="p">会签:</el-text></el-col>
  147. <el-col :span="4" ><el-text tag="p" >{{form.countersignUser}}</el-text></el-col>
  148. <el-col :span="2" ><el-text tag="p">批准:</el-text></el-col>
  149. <el-col :span="4" ><el-text tag="p" >{{form.approveUser}}</el-text></el-col>
  150. </el-row>
  151. </div>
  152. </el-card>
  153. <el-card style="width: 28%" shadow="always">
  154. <template #header>
  155. <div class="card-header">
  156. <span>领用流程</span>
  157. </div>
  158. <el-timeline style="max-width: 500px;">
  159. <el-timeline-item center type="success" placement="top">
  160. <el-card>
  161. <h4>申请</h4>
  162. <el-form ref="maintenanceInfoForm2" size="small" :model="form" label-width="auto" style="max-width: 400px">
  163. <el-form-item label="领用人员" prop="auditUser">
  164. <el-text tag="p" v-if="dialogType === 1 || form.state > 0">{{form.applyUser}}</el-text>
  165. <el-select
  166. v-else
  167. size="small"
  168. filterable
  169. v-model="form.applyUser"
  170. placeholder="请选择领用人员"
  171. clearable>
  172. <el-option
  173. v-for="option in userList"
  174. :key="option.userName"
  175. :label="option.nickName"
  176. :value="option.userName" />
  177. </el-select>
  178. </el-form-item>
  179. <el-form-item label="审核人员" v-if="form.state === '0'">
  180. <el-text tag="p" v-if="dialogType === 1 || form.state > 0">{{form.auditUser}}</el-text>
  181. <el-select
  182. v-else
  183. size="small"
  184. filterable
  185. v-model="form.auditUser"
  186. placeholder="请选择审核人员"
  187. clearable>
  188. <el-option
  189. v-for="option in userList"
  190. :key="option.userName"
  191. :label="option.nickName"
  192. :value="option.userName" />
  193. </el-select>
  194. </el-form-item>
  195. <el-form-item label="申请时间" v-if="form.state > 0">
  196. <el-text tag="p">{{form.created}}</el-text>
  197. </el-form-item>
  198. <el-form-item style="margin-left: 28%" v-if="dialogType !==1">
  199. <el-button type="primary" @click="saveForm(1)" v-if="form.state === '0'">申 请</el-button>
  200. <el-button type="success" @click="saveForm(0)" v-if="form.state === '0'">保 存</el-button>
  201. </el-form-item>
  202. </el-form>
  203. </el-card>
  204. </el-timeline-item>
  205. <el-timeline-item center placement="top" :type="form.state > 1 ? 'success' : 'primary'">
  206. <el-card>
  207. <h4>审核</h4>
  208. <el-form v-if="form.state >= 1" size="small" :model="form" label-width="auto" style="max-width: 400px">
  209. <el-form-item label="审核人员" prop="auditUser">
  210. <el-text tag="p">{{form.auditUser}}</el-text>
  211. </el-form-item>
  212. <el-form-item label="处理结果">
  213. <el-text tag="p" v-if="dialogType === 1 || form.state !== '1'">{{form.state === '1' ? '待审核' : form.auditState === 0 ? "通过" : "未通过"}}</el-text>
  214. <el-text tag="p" v-else-if="form.auditUser !== username">{{form.auditState ? form.auditState === 0 ? "通过" : "未通过" : "待审核"}}</el-text>
  215. <el-radio-group v-else v-model="form.auditState">
  216. <el-radio :value=0>通过</el-radio>
  217. <el-radio :value=1>不通过</el-radio>
  218. </el-radio-group>
  219. </el-form-item>
  220. <el-form-item label="会签人员" v-if="dialogType !== 1 && form.state === '1' && form.auditUser === username">
  221. <el-select
  222. size="small"
  223. filterable
  224. multiple
  225. v-model="form.countersignUsers"
  226. placeholder="请选择会签人员"
  227. clearable>
  228. <el-option
  229. v-for="option in userList"
  230. :key="option.userName"
  231. :label="option.nickName"
  232. :value="option.userName" />
  233. </el-select>
  234. </el-form-item>
  235. <el-form-item label="审核时间" v-if="form.audit && form.audit.time">
  236. <el-text tag="p" >{{form.audit.time}}</el-text>
  237. </el-form-item>
  238. <el-form-item style="margin-left: 35%">
  239. <el-button type="primary" @click="saveForm(2)" v-if="dialogType !== 1 && form.state === '1' && form.auditUser === username">审 核</el-button>
  240. </el-form-item>
  241. </el-form>
  242. </el-card>
  243. </el-timeline-item>
  244. <el-timeline-item center placement="top" :type="form.state > 3 ? 'success' : 'primary'">
  245. <el-card>
  246. <h4>会签</h4>
  247. <el-form v-if="form.state >= 3" size="small" :model="form" label-width="auto" style="max-width: 400px">
  248. <el-form-item v-for="item of form.countersign" label="会签人员:">
  249. <el-text tag="p" >{{item.user}}--</el-text>
  250. <el-text tag="p" v-if="dialogType === 1 || item.user !== username">{{item.state === -1 ? '未审核' : item.state === 0 ? '通过' : '未通过'}}</el-text>
  251. <el-text tag="p" v-else-if="item.state !== -1 && item.user === username">{{item.state === 0 ? '通过' : '未通过'}}</el-text>
  252. <el-radio-group v-model="form.countersignState" v-if="dialogType !== 1 && item.state === -1 && item.user === username">
  253. <el-radio :value=0>通过</el-radio>
  254. <el-radio :value=1>不通过</el-radio>
  255. </el-radio-group>
  256. </el-form-item>
  257. <el-form-item label="批准人员" v-if="dialogType !== 1 && form.countersignOk && form.state === '3'">
  258. <el-select
  259. size="small"
  260. v-model="form.approveUser"
  261. placeholder="请选择批准人员"
  262. clearable >
  263. <el-option
  264. v-for="option in userList"
  265. :key="option.userName"
  266. :label="option.nickName"
  267. :value="option.userName" />
  268. </el-select>
  269. </el-form-item>
  270. <el-form-item label="通过时间" v-if="form.countersignInfo && form.countersignInfo.time">
  271. <el-text tag="p" >{{form.countersignInfo.time}}</el-text>
  272. </el-form-item>
  273. <el-form-item style="margin-left: 35%">
  274. <el-button type="primary" v-if="dialogType !== 1 && form.state === '3' && form.countersignUser.includes(username) && form.countersignBtn" @click="saveForm(3)">审 核</el-button>
  275. </el-form-item>
  276. </el-form>
  277. </el-card>
  278. </el-timeline-item>
  279. <el-timeline-item center placement="top" :type="form.state > 5 ? 'success' : 'primary'">
  280. <el-card>
  281. <h4>批准</h4>
  282. <el-form v-if="form.state >= 5" size="small" :model="form" label-width="auto" style="max-width: 400px">
  283. <el-form-item label="审批人" v-if="form.state > 5">
  284. <el-text tag="p">{{form.approve.user}}</el-text>
  285. </el-form-item>
  286. <el-form-item label="审批结果">
  287. <el-text tag="p" v-if="dialogType === 1 || form.state === '6' || form.state === '7'">{{form.state === '5' ? '待审批' : form.state === '6' ? '通过' : '未通过'}}</el-text>
  288. <el-text tag="p" v-else-if="form.approveUser !== username">待审批</el-text>
  289. <el-radio-group v-else v-model="form.approveState">
  290. <el-radio :value=0>通过</el-radio>
  291. <el-radio :value=1>不通过</el-radio>
  292. </el-radio-group>
  293. </el-form-item>
  294. <el-form-item label="审批时间" v-if="form.state > 5">
  295. <el-text tag="p">{{form.approve.time}}</el-text>
  296. </el-form-item>
  297. <el-form-item style="margin-left: 35%">
  298. <el-button type="primary" @click="saveForm(4)" v-if="dialogType !== 1 && form.state === '5' && form.approveUser === username">审 核</el-button>
  299. </el-form-item>
  300. </el-form>
  301. </el-card>
  302. </el-timeline-item>
  303. </el-timeline>
  304. </template>
  305. </el-card>
  306. </div>
  307. </el-dialog>
  308. </div>
  309. </template>
  310. <script setup>
  311. import { useUserStoreHook } from "@/store/index";
  312. import { ref, getCurrentInstance } from "vue";
  313. import { html2CanvasPrint } from "@/utils/common";
  314. import { useCrud } from "@/hooks/userCrud";
  315. import dictDataUtil from "@/common/configs/dictDataUtil";
  316. import {queryApplyInfoDetails,queryWorkOrderList,saveApplyInfoDetails,auditApplyInfoDetails} from "@/api/order"
  317. import {getUserList} from "@/api/system/user"
  318. import { useCommonStoreHook } from "@/store";
  319. const { isShowTable, tableType } = toRefs(useCommonStoreHook());
  320. const test = () => {
  321. isShowTable.value = true;
  322. tableType.value = tableType.value == 1 ? 2 : 1;
  323. };
  324. // 1.定义ref
  325. const toPrintRef = ref(null);
  326. // 传入一个url,后面不带/
  327. const { form, data, option, search, page, toDeleteIds, Methords, Utils } =
  328. useCrud({
  329. src: "/api/v1/plan/requisition",
  330. });
  331. const { dataList, createRow, updateRow, deleteRow, searchChange, resetChange } = Methords; //增删改查
  332. const { selectionChange, multipleDelete } = Methords; //选中和批量删除事件
  333. const { checkBtnPerm, downloadTemplate, exportData } = Utils; //按钮权限等工具
  334. const { username } = useUserStoreHook().user;
  335. const minusItem =(row)=>{
  336. tableDataList.value = tableDataList.value.filter(item=>item.id !== row.id)
  337. }
  338. const changeOrder =(val)=>{
  339. queryApplyInfoDetails({workOrderCode: val}).then((data)=>{
  340. tableDataList.value = data.data
  341. })
  342. }
  343. const saveForm = (type) =>{
  344. let state = type;
  345. let step = null;
  346. let nextUsers = ""
  347. if(type === 1 || type === 0){
  348. if(tableDataList.value.length === 0){
  349. ElMessage.error("当前没有申请的物料信息")
  350. return;
  351. }
  352. for(let item of tableDataList.value){
  353. if(!item.workCode){
  354. ElMessage.error("工作令号不能为空")
  355. return;
  356. }
  357. if(!item.num || item.num <=0){
  358. ElMessage.error("物料数量不正确")
  359. return;
  360. }
  361. }
  362. if(!form.value.applyUser){
  363. ElMessage.error("领用人员不能为空")
  364. return;
  365. }
  366. if(!form.value.auditUser){
  367. ElMessage.error("审核人员不能为空")
  368. return;
  369. }
  370. const params = {...form.value,'state': state,details: tableDataList.value}
  371. saveApplyInfoDetails(params).then((data)=>{
  372. if(data.code === '200'){
  373. ElMessage.success(data.msg)
  374. dialog.visible = false
  375. dataList()
  376. }else{
  377. ElMessage.error(data.msg)
  378. }
  379. })
  380. return;
  381. }
  382. step = "audit";
  383. if(type === 2){
  384. if(form.value.auditState != undefined){
  385. if(form.value.auditState === 0 && form.value.countersignUsers.length === 0){
  386. ElMessage.error("会签人员不能为空")
  387. return;
  388. }
  389. }else{
  390. if(!form.value.auditState){
  391. ElMessage.error("请选择处理结果")
  392. return;
  393. }
  394. }
  395. nextUsers = form.value.countersignUsers.join(",")
  396. state = form.value.auditState
  397. }
  398. if(type === 3){
  399. step = "countersign";
  400. if(!form.value.approveUser && form.value.countersignOk){
  401. ElMessage.error("请选择审批人员")
  402. return;
  403. }
  404. if(form.value.countersignState === undefined){
  405. ElMessage.error("请选择处理结果")
  406. return;
  407. }
  408. nextUsers = form.value.approveUser
  409. state = form.value.countersignState
  410. }
  411. if(type === 4){
  412. step = "approve";
  413. if(form.value.approveState === undefined){
  414. ElMessage.error("请选择处理结果")
  415. return;
  416. }
  417. state = form.value.approveState
  418. }
  419. const params = {id: form.value.id,'state': state,currentStep: step,nextUser: nextUsers}
  420. auditApplyInfoDetails(params).then((data)=>{
  421. if(data.code === '200'){
  422. ElMessage.success(data.msg)
  423. dialog.visible = false
  424. dataList()
  425. }else{
  426. ElMessage.error(data.msg)
  427. }
  428. })
  429. }
  430. const loading = ref(false)
  431. const crudRef = ref(null); //crudRef.value 获取avue-crud对象
  432. const userList = ref([])
  433. const orderList = ref([])
  434. const dialogType = ref(false)
  435. const dialog = reactive({
  436. title: "领用单",
  437. visible: false,
  438. });
  439. const tableDataList = ref([])
  440. const openDialog = (type,row)=>{
  441. dialogType.value = type
  442. tableDataList.value = []
  443. form.value = {}
  444. form.value.sendOrg = "周转库";
  445. form.value.applyOrg = "制造中心"
  446. form.value.state = "0"
  447. if(type !== 0){
  448. queryApplyInfoDetails({applyCode: row.applyCode}).then((data)=>{
  449. tableDataList.value = data.data
  450. })
  451. form.value = row
  452. }
  453. form.value.countersign = []
  454. if(row && row.flowInfo){
  455. let json = JSON.parse(row.flowInfo)
  456. let auditInfo = json.audit
  457. if(auditInfo){
  458. form.value.audit =auditInfo.info
  459. form.value.auditState = form.value.audit.state
  460. }
  461. if(row.countersignUser){
  462. form.value.countersignUsers = row.countersignUser.split(",")
  463. }
  464. form.value.countersignBtn = false
  465. if(json.countersign){
  466. form.value.countersign = json.countersign.list
  467. form.value.countersignInfo = json.countersign.info
  468. //当断当前是否最后一个
  469. let isOk = true
  470. for(let obj of form.value.countersign){
  471. if(obj.state === -1 && obj.user === username){
  472. form.value.countersignBtn = true
  473. }
  474. if(obj.user !== username && obj.state === -1){
  475. isOk = false
  476. }
  477. }
  478. form.value.countersignOk = isOk;
  479. }
  480. if(json.approve){
  481. form.value.approve = json.approve.info
  482. }
  483. form.value.approveUser = row.approveUser
  484. }
  485. dialog.visible = true
  486. getUserList({}).then((data)=>{
  487. userList.value = data.data
  488. })
  489. }
  490. const printPage = ()=>{
  491. html2CanvasPrint(toPrintRef.value);
  492. }
  493. // 设置表格列或者其他自定义的option
  494. option.value = Object.assign(option.value, {
  495. delBtn: false,
  496. addBtn: false,
  497. editBtn: false,
  498. viewBtn: false,
  499. selection: true,
  500. column: [
  501. {
  502. label: "领用单号",
  503. prop: "applyCode",
  504. search: true,
  505. width: 150,
  506. overHidden: true,
  507. },
  508. {
  509. label: "工单单号",
  510. prop: "workOrderCode",
  511. search: true,
  512. width: 150,
  513. overHidden: true,
  514. },
  515. {
  516. label: "计划单号",
  517. prop: "orderCode",
  518. search: true,
  519. width: 150,
  520. overHidden: true,
  521. },
  522. {
  523. label: "领用单位",
  524. prop: "applyOrg",
  525. width: 150,
  526. overHidden: true,
  527. },
  528. {
  529. label: "发件单位",
  530. prop: "sendOrg",
  531. width: 150,
  532. overHidden: true,
  533. },
  534. {
  535. label: "领用人员",
  536. prop: "applyUser",
  537. width: 150,
  538. overHidden: true,
  539. search: true,
  540. },
  541. {
  542. label: "审核人员",
  543. prop: "auditUser",
  544. width: 150,
  545. overHidden: true,
  546. },
  547. {
  548. label: "会签人员",
  549. width: 150,
  550. overHidden: true,
  551. prop: "countersignUser",
  552. },
  553. {
  554. label: "审批人员",
  555. width: 150,
  556. overHidden: true,
  557. prop: "approveUser",
  558. },
  559. {
  560. label: "状态",
  561. prop: "state",
  562. width: 150,
  563. type: 'select',
  564. dicUrl: dictDataUtil.request_url + dictDataUtil.TYPE_CODE.requisition_state,
  565. props: {
  566. label: "dictLabel", // 下拉菜单显示的字段
  567. value: "dictValue" // 下拉菜单值的字
  568. },
  569. },
  570. {
  571. label: "创建时间",
  572. prop: "created",
  573. width: 160,
  574. display: false
  575. },
  576. ],
  577. });
  578. onMounted(() => {
  579. queryWorkOrderList({}).then((data)=>{
  580. if(!data.data){
  581. ElMessage.warning("请维护物料BOM")
  582. }
  583. orderList.value = data.data
  584. })
  585. // console.log("crudRef", crudRef)
  586. dataList();
  587. });
  588. </script>
  589. <style scoped>
  590. :deep(.card-container .el-form-item) {
  591. display: flex;
  592. justify-content: center;
  593. align-items: center;
  594. height: 15px; /* 根据需要调整高度 */
  595. }
  596. :deep(.el-timeline-item){
  597. padding-bottom: 0px;
  598. position: relative;
  599. }
  600. .card-container {
  601. display: flex;
  602. justify-content: space-around;
  603. }
  604. </style>