index.vue 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594
  1. <!-- 购卡订单 -->
  2. <template>
  3. <div class="silent-expire-alarm">
  4. <!-- 搜索条件区 -->
  5. <!-- <div class="search-section">
  6. <a-form :model="searchForm" layout="inline">
  7. <a-form-item field="cardNumber" label="订单编号">
  8. <a-input v-model="searchForm.orderNumber" placeholder="请输入订单编号" allow-clear />
  9. </a-form-item>
  10. <a-form-item field="customerName" label="客户">
  11. <a-input v-model="searchForm.customerName" placeholder="请输入客户名称" allow-clear />
  12. </a-form-item>
  13. <a-form-item>
  14. <a-space>
  15. <a-button type="primary" @click="handleSearch">搜索</a-button>
  16. <a-button @click="resetSearch">重置</a-button>
  17. </a-space>
  18. </a-form-item>
  19. </a-form>
  20. </div> -->
  21. <div class="audit-btn" v-if="userType == 2">
  22. <a-button @click="openAudit" type="text">
  23. <template #icon>
  24. <icon-plus-circle />
  25. </template>
  26. <template #default>购卡</template>
  27. </a-button>
  28. </div>
  29. <!-- 数据表格 -->
  30. <a-table :data="tableData" :pagination="pageData" :columns="columns" @page-change="evChangePage"
  31. :scroll="{ x: 'auto' }">
  32. <!-- <template #status="{ record }">
  33. {{ record.status }}
  34. </template>
  35. <template #moderation_status="{ record }">
  36. {{ record.moderation_status }}
  37. </template> -->
  38. <template #operate="{ record }">
  39. <div v-if="userType == 1">
  40. <a-popconfirm content="审核" ok-text="通过" cancel-text="驳回" type="warning" @ok="platformCancel(record, 2)" @cancel="platformCancel(record, 3)">
  41. <a-button type="text">审核</a-button>
  42. </a-popconfirm>
  43. <a-button @click="uploadModal(record)" type="text">上传合同</a-button>
  44. </div>
  45. <div v-if="userType == 2">
  46. <a-popconfirm :content="`是否确认退订?`" type="warning" @ok="adminCancel(record)">
  47. <a-button type="text">退订</a-button>
  48. </a-popconfirm>
  49. <a-button @click="openDetail(record, 2)" type="text">查看</a-button>
  50. </div>
  51. </template>
  52. </a-table>
  53. <a-modal v-model:visible="uploadContract" title="上传合同" @cancel="handleCancel" @before-ok="handleBeforeOk"
  54. okText="保存" cancelText="关闭">
  55. <a-form :model="formContract" auto-label-width>
  56. <a-form-item field="customerName" label="客户名称">
  57. <!-- <a-input v-model="formContract.customerName" disabled placeholder="请输入客户" /> -->
  58. <div class="audit-txt" style="color:#418035;">{{ formContract.customerName }}</div>
  59. </a-form-item>
  60. <a-form-item field="orderNumber" label="订单编号">
  61. <!-- <a-input v-model="formContract.orderNumber" disabled placeholder="请输入单号" /> -->
  62. <div class="audit-txt">{{ formContract.orderNumber }}</div>
  63. </a-form-item>
  64. <a-form-item field="fileList" label="销售合同">
  65. <Upload v-model:modelValue="formContract.fileList"/>
  66. </a-form-item>
  67. </a-form>
  68. </a-modal>
  69. <!-- 创建 -->
  70. <a-modal v-model:visible="showAudit" title="购卡" width="600px" @cancel="cancelPurchase" centered
  71. :maskClosable="false" okText="确定" cancelText="关闭" :footer="null">
  72. <a-form ref="formRef" :rules="rules" :model="formState" @submit="submitPurchase">
  73. <a-form-item field="customerName" label="客户名称">
  74. <!-- <a-input v-model="formAudit.customerName" placeholder="请输入客户" /> -->
  75. <div class="audit-txt">{{ userName }}</div>
  76. </a-form-item>
  77. <a-form-item label="运营商" field="source">
  78. <a-select v-model="formState.source" :style="{ width: '380px' }" placeholder="请选择运营商">
  79. <a-option v-for="item of sourceList" :value="item.id" :label="item.label" />
  80. </a-select>
  81. </a-form-item>
  82. <a-form-item label="资费名称" field="tariffId">
  83. <a-select v-model="formState.tariffId" :style="{ width: '380px' }" @change="tariffChange"
  84. placeholder="请选择资费ID">
  85. <a-option v-for="item of tariffData" :value="item.value" :label="item.label" />
  86. </a-select>
  87. </a-form-item>
  88. <!-- <a-form-item label="资费详情" v-if="formState.tariffId">
  89. <div class="audit-txt">
  90. <div class="audit-tag">套餐类型<span>流量</span></div>
  91. <div class="audit-tag">资费编码<span>流量</span></div>
  92. <div class="audit-tag">资费编码<span>流量</span></div>
  93. <div class="audit-tag">资费编码<span>流量</span></div>
  94. </div>
  95. </a-form-item>
  96. <a-form-item label="资费计费详情" v-if="formState.tariffId">
  97. <div class="audit-txt">
  98. <div class="audit-tag">套餐类型<span>流量</span></div>
  99. <div class="audit-tag">资费编码<span>流量</span></div>
  100. <div class="audit-tag">资费编码<span>流量</span></div>
  101. <div class="audit-tag">资费编码<span>流量</span></div>
  102. </div>
  103. </a-form-item> -->
  104. <a-form-item label="卡类型" field="cardType">
  105. <a-select v-model="formState.cardType" :style="{ width: '380px' }" placeholder="请选择卡类型">
  106. <a-option v-for="item of orderType" :value="item.value" :label="item.label" />
  107. </a-select>
  108. </a-form-item>
  109. <a-form-item label="沉默期">
  110. <a-select v-model="formState.silencePeriod" :style="{ width: '380px' }" placeholder="请选择沉默期">
  111. <a-option v-for="item of silenceOptions" :value="item.value" :label="item.label" />
  112. </a-select>
  113. </a-form-item>
  114. <a-form-item label="流量池" field="flowPool">
  115. <a-radio-group v-model="formState.flowPool" :options="flowPoolData">
  116. <template #label="{ data }">
  117. <a-tag>{{ data.label }}</a-tag>
  118. </template>
  119. </a-radio-group>
  120. </a-form-item>
  121. <a-form-item label="购卡数量" field="num">
  122. <a-input v-model="formState.num" placeholder="请输入购卡数量" />
  123. </a-form-item>
  124. <a-form-item>
  125. <a-button type="primary" html-type="submit" style="margin-right: 10px;">确定</a-button>
  126. <a-button @click="cancelPurchase">取消</a-button>
  127. </a-form-item>
  128. </a-form>
  129. </a-modal>
  130. <!-- 详情 -->
  131. <a-modal v-model:visible="showDetail" width="800px" :title="currentIndex == 1 ? '退卡详情' : '查看'"
  132. @cancel="showDetail = false" :footer="null">
  133. <div class="detail-box">
  134. <div class="detail-item-box">
  135. <div class="detail-item">
  136. <div class="item-label">订单编号</div>
  137. <div class="item-content">53357981207</div>
  138. </div>
  139. <div class="detail-item">
  140. <div class="item-label">订单状态</div>
  141. <div class="item-content">已发货</div>
  142. </div>
  143. </div>
  144. <div class="detail-item-box">
  145. <div class="detail-item">
  146. <div class="item-label">发货日期</div>
  147. <div class="item-content">2024-10-24 17:46:33</div>
  148. </div>
  149. </div>
  150. <div class="detail-item-box">
  151. <div class="detail-item">
  152. <div class="item-label">运营商</div>
  153. <div class="item-content">泰国AIS</div>
  154. </div>
  155. <div class="detail-item">
  156. <div class="item-label">资费信息</div>
  157. <div class="item-content">1.0G/月</div>
  158. </div>
  159. </div>
  160. <div class="detail-item-box">
  161. <div class="detail-item">
  162. <div class="item-label">最短订阅周期</div>
  163. <div class="item-content">3个月</div>
  164. </div>
  165. <div class="detail-item">
  166. <div class="item-label">最长订阅周期</div>
  167. <div class="item-content">--</div>
  168. </div>
  169. </div>
  170. <div class="detail-item-box">
  171. <div class="detail-item">
  172. <div class="item-label">计费方式</div>
  173. <div class="item-content">按单流量消耗计费</div>
  174. </div>
  175. <div class="detail-item">
  176. <div class="item-label">结算周期</div>
  177. <div class="item-content">月</div>
  178. </div>
  179. </div>
  180. <div class="detail-item-box">
  181. <div class="detail-item">
  182. <div class="item-label">流量资费计费</div>
  183. <div class="item-content">0.8美金/G;MRC:0元;网络接入0元</div>
  184. </div>
  185. </div>
  186. <div class="detail-item-box">
  187. <div class="detail-item">
  188. <div class="item-label">卡类型</div>
  189. <div class="item-content">工业级PlugIn</div>
  190. </div>
  191. <div class="detail-item">
  192. <div class="item-label">卡板费</div>
  193. <div class="item-content">1美金</div>
  194. </div>
  195. </div>
  196. <div class="detail-item-box">
  197. <div class="detail-item">
  198. <div class="item-label">流量池</div>
  199. <div class="item-content">组池</div>
  200. </div>
  201. <div class="detail-item">
  202. <div class="item-label">沉默期</div>
  203. <div class="item-content">6个月</div>
  204. </div>
  205. </div>
  206. <div class="detail-item-box">
  207. <div class="detail-item">
  208. <div class="item-label">卡数量</div>
  209. <div class="item-content">10000;已分配0,已退回0,已转移0
  210. <!-- <a-button type="primary" @click="showCard = true" style="margin-left:10px;">分配卡号</a-button> -->
  211. </div>
  212. </div>
  213. </div>
  214. </div>
  215. <div class="detail-table">
  216. <a-table :columns="columnsDetail" :data="dataDetail" />
  217. </div>
  218. <div style="text-align: right;margin-top: 20px;">
  219. <a-button type="primary" html-type="submit" style="margin-right: 10px;" @click="operateHandle">确定</a-button>
  220. </div>
  221. </a-modal>
  222. <!-- <a-modal v-model:visible="showCard" width="800px" title="分配卡号" @cancel="showCard = false" @before-ok="submitCard"
  223. okText="确认" cancelText="取消">
  224. <a-textarea :auto-size="{
  225. minRows: 15,
  226. maxRows: 15
  227. }" v-model="cardNumber" max-length="1000" :show-word-limit="true" placeholder="请输入iccid,一行一个或者逗号分隔;不支持两种混合号码。"
  228. allow-clear />
  229. </a-modal> -->
  230. </div>
  231. </template>
  232. <script setup>
  233. import { ref, reactive, onMounted } from 'vue';
  234. import { Message } from '@arco-design/web-vue';
  235. import { tariffList } from "@/api/path/tariffManagement.api";
  236. import { purchaseOrderList, addPurchaseOrder, platformUpdate, adminUpdate } from '@/api/path/purchase';
  237. import { Getdictionary } from '@/mixins/index.js'
  238. import Upload from "@/components/upload/index.vue";
  239. const selectedKeys = ref([]);
  240. const rowSelection = reactive({
  241. type: 'checkbox',
  242. showCheckedAll: true,
  243. onlyCurrent: false,
  244. });
  245. const searchForm = reactive({
  246. cardNumber: '',
  247. customerName: '',
  248. });
  249. const columns = [
  250. { title: '序号', dataIndex: 'index', align: 'center',ellipsis:true },
  251. { title: '订单编号', dataIndex: 'id', align: 'center', ellipsis:true },
  252. { title: '审核状态', dataIndex: 'orderTypeName', align: 'center' ,ellipsis:true},
  253. { title: '订单状态', dataIndex: 'statusName', align: 'center' ,ellipsis:true},
  254. { title: '客户名称', dataIndex: 'userName', align: 'center',ellipsis:true },
  255. { title: '采购数量', dataIndex: 'quantity', align: 'center' ,ellipsis:true},
  256. { title: '运营商名称', dataIndex: 'quantity', align: 'center',ellipsis:true },
  257. { title: '资费', dataIndex: 'quantity', align: 'center',ellipsis:true },
  258. { title: '支付金额', dataIndex: 'paymentAmount', align: 'center',ellipsis:true },
  259. { title: '下单时间', dataIndex: 'createdAt', align: 'center',ellipsis:true },
  260. { title: '操作', slotName: 'operate', align: 'center',ellipsis:true}
  261. ];
  262. const columnsDetail = [{ title: 'ICCID', dataIndex: 'iccid' },
  263. { title: '池名称及编号', dataIndex: 'nameAndId' },
  264. { title: '卡状态', dataIndex: 'status' },
  265. ]
  266. const dataDetail = ref([{
  267. iccid: '8986061800002054589N',
  268. nameAndId: '泰国监控40G共享/53357981207',
  269. status: '沉默期'
  270. },
  271. {
  272. iccid: '8986061800002054588N',
  273. nameAndId: '泰国监控40G共享/53357981207',
  274. status: '沉默期'
  275. }, {
  276. iccid: '8986061800002054587N',
  277. nameAndId: '泰国监控40G共享/53357981207',
  278. status: '沉默期'
  279. }, {
  280. iccid: '8986061800002054586N',
  281. nameAndId: '泰国监控40G共享/53357981207',
  282. status: '沉默期'
  283. },])
  284. const userName = ref(localStorage.getItem('remember_user_name'))
  285. const userType = ref(JSON.parse(localStorage.getItem('user_login_information'))?.userType);// 1平台 2用户
  286. const tableData = ref([]);
  287. const formRef = ref(null);
  288. const currentIndex = ref(null);
  289. const rules = {
  290. source: [{ required: true, trigger: 'change', }],
  291. tariffId: [
  292. {
  293. required: true,
  294. trigger: 'change',
  295. },
  296. ],
  297. cardType: [
  298. {
  299. required: true,
  300. trigger: 'change',
  301. },
  302. ],
  303. flowPool: [
  304. {
  305. required: true,
  306. trigger: 'change',
  307. },
  308. ],
  309. num: [
  310. {
  311. required: true,
  312. trigger: 'change',
  313. },
  314. ],
  315. };
  316. const pageData = ref({
  317. total: 0,
  318. size: 10,
  319. current: 1,
  320. })
  321. const formState = ref({
  322. source: null,
  323. tariffId: null,
  324. cardType: null,
  325. silencePeriod: null,
  326. flowPool: null,
  327. num: null
  328. })
  329. const sourceList = ref([]) // 来源
  330. const tariffData = ref([]) // 自费
  331. const silenceOptions = ref([]); // 沉默期
  332. const orderType = ref([]); // 卡类型
  333. const flowPoolData = ref([]); // 组池
  334. const showAudit = ref(false);
  335. const handleDictValue = async () => {
  336. sourceList.value = await Getdictionary('source')
  337. orderType.value = await Getdictionary('cardType')
  338. silenceOptions.value = await Getdictionary('silenceOf')
  339. flowPoolData.value = await Getdictionary('groupPool')
  340. const param = {
  341. current: 1,
  342. size: 999,
  343. }
  344. tariffList(param).then(res => {
  345. tariffData.value = res.data.records.map(item => ({
  346. label: item.label,
  347. value: item.id,
  348. ...item
  349. }));
  350. })
  351. }
  352. // 订单列表
  353. const intData = async () => {
  354. const param = {
  355. current: pageData.value.current,
  356. size: pageData.value.size,
  357. }
  358. let res1 = await Getdictionary('subscriptionRelationshipStatus')
  359. let res2 = await Getdictionary('orderAuditStatus')
  360. purchaseOrderList(param).then(res => {
  361. tableData.value = (res.data.records || []).map((item,key) => {
  362. const statusName = res1.filter((item) => item.typeKey == 'subscriptionRelationshipStatus')?.find(val => item.status == val.value)?.label
  363. const orderTypeName = res2.filter((item) => item.typeKey == 'orderAuditStatus')?.find(val => item.status == val.value)?.label
  364. return {
  365. ...item,
  366. index: key + 1,
  367. orderTypeName,
  368. statusName,
  369. }
  370. });
  371. pageData.value.total = res.data.total;
  372. })
  373. }
  374. // 确认购卡
  375. const submitPurchase = ({ values, errors }) => {
  376. formRef.value.validate(async (errors) => {
  377. if (!errors) {
  378. const data = {
  379. source: String(formState.value.source),
  380. tariffId: formState.value.tariffId,
  381. quantity: Number(formState.value.num),
  382. cardType: formState.value.cardType,
  383. periodOfSilence: String(formState.value.silencePeriod),
  384. isTrafficPool: formState.value.flowPool
  385. }
  386. addPurchaseOrder(data).then(res => {
  387. intData();
  388. showAudit.value = false;
  389. })
  390. }
  391. })
  392. }
  393. // 取消
  394. const cancelPurchase = () => {
  395. showAudit.value = false;
  396. formRef.value.resetFields();
  397. Object.assign(formState, {
  398. source: null,
  399. tariffId: null,
  400. cardType: null,
  401. silencePeriod: null,
  402. flowPool: 0,
  403. num: null
  404. });
  405. }
  406. // 平台退订
  407. const platformCancel = (data, type) => {
  408. const param = {
  409. id: data.id,
  410. status: type
  411. }
  412. platformUpdate(param).then(res => {
  413. intData();
  414. })
  415. }
  416. // 用户退订
  417. const adminCancel = (data) => {
  418. const param = {
  419. id: data.id,
  420. status: data.status
  421. }
  422. adminUpdate(param).then(res => {
  423. intData();
  424. })
  425. }
  426. //
  427. const tariffChange = (e) => {
  428. formState.value.tariffId = e;
  429. // tariffObj.value = res.data.records.map(item=>{
  430. // })
  431. }
  432. //
  433. const operateHandle = () => {
  434. if (currentIndex.value == 1) {
  435. } else {
  436. showDetail.value = false;
  437. }
  438. }
  439. // 分页
  440. const evChangePage = (page) => {
  441. pageData.value.current = page
  442. intData()
  443. }
  444. onMounted(() => {
  445. intData();
  446. })
  447. // 上传合同的弹框
  448. const uploadContract = ref(false);
  449. const uploadModal = (item) => {
  450. uploadContract.value = true;
  451. formContract.customerName = item.customerName;
  452. formContract.orderNumber = item.sourceOrderId;
  453. };
  454. //订单详情的弹框
  455. const showDetail = ref(false);
  456. // 查看订单详情
  457. const openDetail = (item, current) => {
  458. currentIndex.value = current;
  459. uploadContract.value = true;
  460. }
  461. const handleBeforeOk = (done) => {
  462. window.setTimeout(() => {
  463. done()
  464. // prevent close
  465. // done(false)
  466. }, 3000)
  467. };
  468. const handleCancel = () => {
  469. uploadContract.value = false;
  470. }
  471. const handleSearch = () => {
  472. console.log('Search form data:', searchForm);
  473. Message.success('执行搜索操作');
  474. };
  475. const resetSearch = () => {
  476. Object.keys(searchForm).forEach(key => {
  477. if (Array.isArray(searchForm[key])) {
  478. searchForm[key] = [];
  479. } else {
  480. searchForm[key] = null;
  481. }
  482. });
  483. Message.success('搜索条件已重置');
  484. };
  485. // 文件上传的列表
  486. const formContract = reactive({
  487. orderNumber: '',
  488. customerName: '',
  489. fileList: []
  490. })
  491. // 触发购卡弹框
  492. const openAudit = () => {
  493. showAudit.value = true;
  494. handleDictValue();
  495. }
  496. // 分配卡号的值
  497. const cardNumber = ref('');
  498. const showCard = ref(false);
  499. const submitCard = () => {
  500. }
  501. </script>
  502. <style scoped lang="less">
  503. .silent-expire-alarm {
  504. padding: 20px !important;
  505. // background: #fcf;
  506. }
  507. .search-section {
  508. margin-bottom: 20px;
  509. }
  510. .arco-table-th {
  511. white-space: nowrap;
  512. }
  513. .audit-txt {
  514. display: flex;
  515. flex-wrap: wrap;
  516. .audit-tag {
  517. width: 180px;
  518. color: #b2b2b2;
  519. margin-right: 20px;
  520. span {
  521. color: #000;
  522. margin-left: 20px;
  523. }
  524. }
  525. }
  526. .audit-btn {
  527. margin-bottom: 10px;
  528. }
  529. .detail-box {
  530. .detail-item-box {
  531. display: flex;
  532. justify-content: space-between;
  533. align-items: center;
  534. margin-bottom: 10px;
  535. .detail-item {
  536. //styleName: Body/Medium;
  537. font-family: PingFang SC;
  538. font-size: 14px;
  539. font-weight: 400;
  540. line-height: 22px;
  541. text-align: left;
  542. display: flex;
  543. align-items: center;
  544. min-width: 350px;
  545. .item-label {
  546. color: rgba(0, 0, 0, 0.4);
  547. width: 120px;
  548. text-align: right;
  549. margin-right: 10px;
  550. }
  551. .item-content {
  552. color: rgba(51, 51, 51, 1);
  553. }
  554. }
  555. }
  556. }
  557. .detail-table {
  558. margin-top: 20px;
  559. }
  560. </style>