settlement-account.vue 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676
  1. <template>
  2. <div class="settlement-account-content">
  3. <div class="control-con-title">
  4. <div>
  5. <span class="policy-export-btn">账户列表</span>
  6. <span>
  7. <a-tooltip>
  8. <template slot="title">由销售人员上传需要进行结算的客户自运营的账户信息,需要注意开户主体需要是我司</template>
  9. <a-icon class="settlement-header-icon" type="question-circle"/>
  10. </a-tooltip>
  11. 客户自运营账户列表,需要销售/媒介人员进行上传
  12. </span>
  13. </div>
  14. <div>
  15. <span v-if="userSaleList.includes(userInfo().roleName)" class="add-acount-policy-btn">
  16. <a-button type="primary" @click="handleUploadAccount">上传账户数据</a-button>
  17. </span>
  18. </div>
  19. </div>
  20. <div class="control-con-header">
  21. <a-form
  22. class="grid-form"
  23. layout="inline"
  24. :form="searchForm"
  25. hide-required-mark
  26. >
  27. <a-row class="grid-form-options">
  28. <a-form-item
  29. class="grid-form-item"
  30. label="广告主名称:"
  31. :colon="false"
  32. >
  33. <a-input v-model="configForm.advertiserName" placeholder="请输入广告主名称" allow-clear/>
  34. </a-form-item>
  35. <a-form-item
  36. class="grid-form-item"
  37. label="产品名称:"
  38. :colon="false"
  39. >
  40. <a-input v-model="configForm.productName" placeholder="请输入产品名称" allow-clear/>
  41. </a-form-item>
  42. <a-form-item
  43. class="grid-form-item"
  44. label="项目名称:"
  45. :colon="false"
  46. >
  47. <a-input v-model="configForm.projectName" placeholder="请输入项目名称" allow-clear/>
  48. </a-form-item>
  49. <a-form-item
  50. class="grid-form-item"
  51. label="账户名称:"
  52. :colon="false"
  53. >
  54. <a-input v-model="configForm.accountName" placeholder="请输入账户名称" allow-clear/>
  55. </a-form-item>
  56. </a-row>
  57. <a-row>
  58. <a-form-item label="负责人:">
  59. <a-select
  60. v-model="configForm.createUserName"
  61. style="width: 100px"
  62. :filter-option="handleFilterOption"
  63. show-search
  64. allow-clear
  65. >
  66. <a-select-option
  67. v-for="item in allSaleListOption"
  68. :key="item.id"
  69. :value="item.realname"
  70. >
  71. {{ item.realname }}
  72. </a-select-option>
  73. </a-select>
  74. </a-form-item>
  75. <a-form-item label="媒体类型:">
  76. <a-select v-model="configForm.mediaId" style="width: 100px">
  77. <a-select-option value="no">不限</a-select-option>
  78. <a-select-option :value="1">头条</a-select-option>
  79. <a-select-option :value="2">快手</a-select-option>
  80. </a-select>
  81. </a-form-item>
  82. <a-form-item
  83. class="grid-form-item"
  84. label="时间:"
  85. :colon="false"
  86. >
  87. <a-range-picker
  88. v-model="configForm.time"
  89. format="YYYY-MM-DD"
  90. @change="handleAddTimesChange"
  91. />
  92. </a-form-item>
  93. <a-form-item class="form-handle-btn">
  94. <a-button type="default" class="reset-class" @click="handleResetList">重置</a-button>
  95. <a-button type="primary" @click="handleQueryList">搜索</a-button>
  96. </a-form-item>
  97. </a-row>
  98. </a-form>
  99. </div>
  100. <div class="control-con-table">
  101. <a-table
  102. ref="table"
  103. size="middle"
  104. bordered
  105. :columns="settlementColumns"
  106. :dataSource="dataSource"
  107. :pagination="false"
  108. :scroll="{x: 1800}"
  109. :loading="controlLoading"
  110. >
  111. <span slot="advertiserName" slot-scope="text">
  112. <a-tooltip placement="top">
  113. <template slot="title">
  114. <span>{{ text }}</span>
  115. </template>
  116. <span>{{ text }}</span>
  117. </a-tooltip>
  118. </span>
  119. <span slot="productName" slot-scope="text">
  120. <a-tooltip placement="top">
  121. <template slot="title">
  122. <span>{{ text }}</span>
  123. </template>
  124. <span>{{ text }}</span>
  125. </a-tooltip>
  126. </span>
  127. <span slot="accountName" slot-scope="text">
  128. <a-tooltip placement="top">
  129. <template slot="title">
  130. <span>{{ text }}</span>
  131. </template>
  132. <span>{{ text }}</span>
  133. </a-tooltip>
  134. </span>
  135. <span slot="mediaId" slot-scope="text">
  136. <span>{{ text === 1 ? '头条' : '快手' }}</span>
  137. </span>
  138. <span slot="operateType" slot-scope="text">
  139. <span>{{ text === 1 ? '自运营' : '代运营' }}</span>
  140. </span>
  141. <span slot="status" slot-scope="text, record">
  142. <a-switch :checked="text === 0" @change="handleSwitchChang($event, record)"/>
  143. </span>
  144. <span slot="action" slot-scope="text, record">
  145. <a @click="handleSettleDel(record)">删除</a>
  146. <a-divider type="vertical"/>
  147. <a disabled>更多</a>
  148. </span>
  149. </a-table>
  150. <a-pagination
  151. class="pagin-table-class"
  152. :total="totalAll"
  153. :show-total="total => `共 ${totalAll} 条`"
  154. size="small"
  155. show-size-changer
  156. show-quick-jumper
  157. @change="onShowSizeChange"
  158. @showSizeChange="onShowSizeChange"
  159. />
  160. </div>
  161. <!-- 上传账户数据 -->
  162. <a-modal
  163. v-if="policyOperationStatus"
  164. title="账户上传"
  165. :visible="policyOperationStatus"
  166. dialog-class="settlement-modal-class"
  167. :confirmLoading="confirmLoading"
  168. @ok="handlePolicyOperationSure"
  169. @cancel="handlePolicyOperationCancel"
  170. >
  171. <div>
  172. <a-form-model
  173. class="policy-operation-form"
  174. ref="policyOperationForm"
  175. :model="policyOperationForm"
  176. :rules="policyOperationRules"
  177. :label-col="labelCol"
  178. :wrapper-col="wrapperCol"
  179. >
  180. <a-form-model-item label="选择媒体">
  181. <a-radio-group v-model="policyOperationForm.mediaId" button-style="solid" @change="handleMediaIdChange">
  182. <a-radio-button :value="1">头条</a-radio-button>
  183. <a-radio-button :value="2">快手</a-radio-button>
  184. </a-radio-group>
  185. </a-form-model-item>
  186. <a-form-model-item label="选择广告主公司名称" prop="advertiserId">
  187. <a-select
  188. v-model="policyOperationForm.advertiserId"
  189. placeholder="请选择广告主名称"
  190. :filter-option="handleFilterOption"
  191. show-search
  192. @change="handleAdverOptionChange"
  193. >
  194. <a-select-option
  195. v-for="item in allAdverListOption"
  196. :key="item.advertiserId"
  197. :value="item.advertiserId"
  198. >
  199. {{ item.advertiserName }}
  200. </a-select-option>
  201. </a-select>
  202. </a-form-model-item>
  203. <a-form-model-item label="选择产品名称" prop="productId">
  204. <a-select
  205. v-model="policyOperationForm.productId"
  206. placeholder="请选择产品名称"
  207. :filter-option="handleFilterOption"
  208. show-search
  209. @change="handleProductOptionChange"
  210. >
  211. <a-select-option
  212. v-for="item in allProductListOption"
  213. :key="item.id"
  214. :value="item.id"
  215. >
  216. {{ item.productName }}
  217. </a-select-option>
  218. </a-select>
  219. </a-form-model-item>
  220. <a-form-model-item label="选择项目名称" prop="projectId">
  221. <a-select
  222. v-model="policyOperationForm.projectId"
  223. placeholder="请选择产品名称"
  224. :filter-option="handleFilterOption"
  225. show-search
  226. >
  227. <a-select-option
  228. v-for="item in allProjectListOption"
  229. :key="item.id"
  230. :value="item.id"
  231. >
  232. {{ item.projectName }}
  233. </a-select-option>
  234. </a-select>
  235. </a-form-model-item>
  236. <a-form-model-item label="运营方式">
  237. <a-radio-group v-model="policyOperationForm.operateType" button-style="solid">
  238. <a-radio-button :value="1">自运营</a-radio-button>
  239. <a-radio-button :value="2">代运营</a-radio-button>
  240. </a-radio-group>
  241. </a-form-model-item>
  242. <a-form-model-item label="附件上传">
  243. <a-upload
  244. name="file"
  245. :file-list="policyOperationForm.fileList"
  246. :customRequest="handleCustomRequest"
  247. :remove="handleRemoveUpload"
  248. >
  249. <a-button><a-icon type="upload"/>文件上传</a-button>
  250. </a-upload>
  251. <a class="file-down-title" @click="handleFileDownTitle">文件格式下载</a>
  252. <p class="upload-txt-rules">支持扩展名:.xlsx、.xls</p>
  253. </a-form-model-item>
  254. </a-form-model>
  255. </div>
  256. </a-modal>
  257. </div>
  258. </template>
  259. <script>
  260. import {mapGetters} from 'vuex';
  261. import moment from 'moment';
  262. import {getAction, postFileAction} from '@/api/manage';
  263. import {urlAcount} from './settlement-account-server.js';
  264. export default {
  265. name: 'settlement-account',
  266. data() {
  267. return {
  268. userSaleList: ['外部销售', '销售总监', '销售', '销售助理', '销售支持经理', '销售AM', '媒介', '管理员'],
  269. confirmLoading: false,
  270. allProjectListOption: [],
  271. allAdverListOption: [],
  272. allProductListOption: [],
  273. controlLoading: false,
  274. allSaleListOption: [],
  275. labelCol: {span: 7},
  276. wrapperCol: {span: 14},
  277. policyOperationForm: {
  278. advertiserId: undefined,
  279. productId: undefined,
  280. projectId: undefined,
  281. mediaId: 1,
  282. operateType: 1,
  283. fileList: []
  284. },
  285. policyOperationRules: {
  286. advertiserId: [{required: true, message: '请选择广告主公司名称', trigger: 'change'}],
  287. productId: [{required: true, message: '请选择产品名称', trigger: 'change'}],
  288. projectId: [{required: true, message: '请选择项目名称', trigger: 'change'}]
  289. },
  290. policyOperationStatus: false,
  291. totalAll: 0,
  292. dataSource: [],
  293. settlementColumns: [
  294. {
  295. title: '广告主主体名称',
  296. align: 'center',
  297. dataIndex: 'advertiserName',
  298. width: 240,
  299. ellipsis: true,
  300. scopedSlots: {customRender: 'advertiserName'}
  301. },
  302. {
  303. title: '产品名称',
  304. align: 'center',
  305. dataIndex: 'productName',
  306. ellipsis: true,
  307. width: 200,
  308. scopedSlots: {customRender: 'productName'}
  309. },
  310. {
  311. title: '项目名称',
  312. align: 'center',
  313. dataIndex: 'projectName',
  314. width: 180
  315. },
  316. {
  317. title: '账户ID',
  318. align: 'center',
  319. dataIndex: 'accountId',
  320. width: 150
  321. },
  322. {
  323. title: '账户名称',
  324. dataIndex: 'accountName',
  325. align: 'center',
  326. width: 160,
  327. ellipsis: true,
  328. scopedSlots: {customRender: 'accountName'}
  329. },
  330. {
  331. title: '媒体',
  332. dataIndex: 'mediaId',
  333. align: 'center',
  334. width: 150,
  335. scopedSlots: {customRender: 'mediaId'}
  336. },
  337. {
  338. title: '负责人',
  339. dataIndex: 'createUserName',
  340. width: 180,
  341. align: 'center'
  342. },
  343. {
  344. title: '运营方式',
  345. dataIndex: 'operateType',
  346. align: 'center',
  347. width: 150,
  348. scopedSlots: {customRender: 'operateType'}
  349. },
  350. {
  351. title: '账户状态',
  352. align: 'center',
  353. dataIndex: 'status',
  354. width: 150,
  355. scopedSlots: {customRender: 'status'}
  356. },
  357. {
  358. title: '操作',
  359. dataIndex: 'action',
  360. align: 'center',
  361. width: 250,
  362. fixed: 'right',
  363. scopedSlots: {customRender: 'action'}
  364. }
  365. ],
  366. configForm: {
  367. advertiserName: '',
  368. productName: '',
  369. projectName: '',
  370. accountName: '',
  371. creativeSale: 2,
  372. mediaId: 'no',
  373. time: [moment().subtract(7, 'days').format('YYYY-MM-DD'), moment().format('YYYY-MM-DD')]
  374. },
  375. tablePag: {
  376. page: 1,
  377. siz: 10
  378. }
  379. };
  380. },
  381. created() {
  382. this.searchForm = this.$form.createForm(this);
  383. },
  384. mounted() {
  385. this.handleInitTable();
  386. this.handleGetAllSaleList();
  387. this.handleGetAllAdverList(1);
  388. },
  389. methods: {
  390. ...mapGetters(['userInfo']),
  391. moment,
  392. handleMediaIdChange(e) {
  393. this.policyOperationForm.advertiserId = undefined;
  394. this.policyOperationForm.productId = undefined;
  395. this.policyOperationForm.projectId = undefined;
  396. this.policyOperationForm.operateType = 1;
  397. this.policyOperationForm.fileList = [];
  398. this.handleGetAllAdverList(e.target.value)
  399. },
  400. handleAddTimesChange(date, dateString) {
  401. this.configForm.time = dateString;
  402. },
  403. handleProductOptionChange(e) {
  404. this.policyOperationForm.projectId = undefined;
  405. const paramsData = {
  406. pageNo: 1,
  407. pageSize: 1000,
  408. mediaId: this.policyOperationForm.mediaId === 1 ? '1,3' : '2,4',
  409. advertiserId: this.policyOperationForm.advertiserId,
  410. productId: e
  411. };
  412. getAction('/ctop/project/list', paramsData).then(result => {
  413. if (result.success) {
  414. this.allProjectListOption = result.result.records || [];
  415. }
  416. else {
  417. this.$message.error(result.message);
  418. }
  419. }).catch(error => {
  420. console.log(error, 'eeee');
  421. });
  422. },
  423. handleAdverOptionChange(e) {
  424. this.policyOperationForm.productId = undefined;
  425. this.policyOperationForm.projectId = undefined;
  426. const paramsData = {
  427. pageNo: 1,
  428. pageSize: 1000,
  429. advertiserId: e
  430. };
  431. getAction('/ctop/product/list', paramsData).then(result => {
  432. if (result.success) {
  433. this.allProductListOption = result.result.records || [];
  434. }
  435. else {
  436. this.$message.error(result.message);
  437. }
  438. }).catch(error => {
  439. console.log(error, 'eeee');
  440. });
  441. },
  442. handleFilterOption(input, option) {
  443. return option.componentOptions.children[0].text.toLowerCase().indexOf(input.toLowerCase()) >= 0;
  444. },
  445. // 获取所有的广告主列表
  446. handleGetAllAdverList(type) {
  447. const paramsData = {
  448. userId: this.userInfo().id,
  449. mediaId: type,
  450. pageNo: 1,
  451. pageSize: 1000
  452. };
  453. getAction('/ctop/projectMember/participateListV3', paramsData).then(result => {
  454. if (result.success) {
  455. this.allAdverListOption = result.result || [];
  456. }
  457. else {
  458. this.$message.error(result.message);
  459. }
  460. }).catch(error => {
  461. console.log(error, 'eeee');
  462. });
  463. },
  464. // 获取所有的媒体 枚举值
  465. handleGetAllSaleList() {
  466. const paramsData = {
  467. userId: this.userInfo().id
  468. };
  469. getAction(urlAcount + '/finance/settLementController/getResponsibleUserByIds', paramsData).then(result => {
  470. if (result.code === 0) {
  471. this.allSaleListOption = result.result || [];
  472. }
  473. else {
  474. this.$message.error(result.message);
  475. }
  476. }).catch(error => {
  477. console.log(error, 'eeee');
  478. });
  479. },
  480. // 获取默认的列表数据
  481. handleInitTable() {
  482. this.controlLoading = true;
  483. const paramsData = {
  484. createUserId: this.userInfo().id,
  485. advertiserName: this.configForm.advertiserName,
  486. productName: this.configForm.productName,
  487. projectName: this.configForm.projectName,
  488. accountName: this.configForm.accountName,
  489. createUserName: this.configForm.createUserName,
  490. mediaId: this.configForm.mediaId === 'no' ? '' : this.configForm.mediaId,
  491. startTime: this.configForm.time[0],
  492. endTime: this.configForm.time[1],
  493. pageNo: this.tablePag.page,
  494. pageSize: this.tablePag.size
  495. };
  496. getAction(urlAcount + '/finance/settLementController/getSettlementList', paramsData).then(result => {
  497. if (result.code === 0) {
  498. let defaultList = result.result.list;
  499. this.dataSource = defaultList;
  500. this.totalAll = result.result.total;
  501. }
  502. else {
  503. this.dataSource = [];
  504. this.totalAll = 0;
  505. this.$message.error(result.message);
  506. }
  507. }).catch(error => {
  508. console.log(error, 'eeee');
  509. }).finally(() => {
  510. this.controlLoading = false;
  511. });
  512. },
  513. // 文件格式下载
  514. handleFileDownTitle() {
  515. const {mediaId} = this.policyOperationForm;
  516. if (mediaId === 1) {
  517. window.location.href = 'http://media-1301855440.cos.ap-chongqing.myqcloud.com/undefined/2021-08-17/%E5%A4%B4%E6%9D%A1%E8%B4%A6%E6%88%B7%E4%B8%8A%E4%BC%A0%E6%A8%A1%E6%9D%BF-1629185054420.xlsx';
  518. }
  519. else if (mediaId === 2) {
  520. window.location.href = 'http://media-1301855440.cos.ap-chongqing.myqcloud.com/undefined/2021-08-17/%E5%BF%AB%E6%89%8B%E8%B4%A6%E6%88%B7%E4%B8%8A%E4%BC%A0%E6%A8%A1%E6%9D%BF-1629185318124.xlsx';
  521. }
  522. },
  523. handleCustomRequest(info) {
  524. const isZip = info.file.name.indexOf('xlsx') !== -1 || info.file.name.indexOf('xls') !== -1;
  525. if (!isZip) {
  526. this.$message.error('上传模板只能是 xls、xlsx格式!');
  527. return;
  528. }
  529. this.policyOperationForm.fileList = [];
  530. this.$nextTick(() => {
  531. this.policyOperationForm.fileList.push(info.file);
  532. });
  533. },
  534. handleRemoveUpload(data) {
  535. let index = this.policyOperationForm.fileList.indexOf(data);
  536. let newUploadFile = this.policyOperationForm.fileList;
  537. newUploadFile.splice(index, 1);
  538. this.policyOperationForm.fileList = newUploadFile;
  539. },
  540. // 上传确定按钮操作
  541. handlePolicyOperationSure() {
  542. const {advertiserId, productId, projectId, mediaId, operateType, fileList} = this.policyOperationForm;
  543. this.$refs.policyOperationForm.validate(valid => {
  544. if (valid) {
  545. if (!fileList.length) {
  546. this.$message.error('请上传文件');
  547. return;
  548. }
  549. let paramsData = new FormData();
  550. paramsData.append('advertiserId', advertiserId);
  551. paramsData.append('productId', productId);
  552. paramsData.append('projectId', projectId);
  553. paramsData.append('mediaId', mediaId);
  554. paramsData.append('operateType', operateType);
  555. paramsData.append('file', fileList[0]);
  556. paramsData.append('createUserId', this.userInfo().id);
  557. this.confirmLoading = true;
  558. postFileAction(urlAcount + '/finance/settLementController/settlementAccountImport', paramsData, {
  559. headers: {
  560. 'Content-Type': 'multipart/form-data'
  561. }
  562. }).then(result => {
  563. if (result.code === 0) {
  564. this.$message.success(result.message);
  565. this.handlePolicyOperationCancel();
  566. this.handleInitTable();
  567. }
  568. else {
  569. this.$message.error(result.message);
  570. }
  571. }).catch(error => {
  572. console.log(error, 'eeee');
  573. }).finally(() => {
  574. this.confirmLoading = false;
  575. });
  576. }
  577. else {
  578. return false;
  579. }
  580. });
  581. },
  582. // 上传取消按钮操作
  583. handlePolicyOperationCancel() {
  584. this.policyOperationForm = {
  585. advertiserId: undefined,
  586. productId: undefined,
  587. projectId: undefined,
  588. mediaId: 1,
  589. operateType: 1,
  590. fileList: []
  591. };
  592. this.policyOperationStatus = false;
  593. },
  594. // 删除操作
  595. handleSettleDel(list) {
  596. let that = this;
  597. this.$confirm({
  598. title: '提示',
  599. content: '是否确认删除该条数据',
  600. onOk() {
  601. getAction(urlAcount + '/finance/settLementController/deleteSettlementById', {id: list.id}).then(result => {
  602. if (result.code === 0) {
  603. that.handleInitTable();
  604. that.$message.success('删除成功');
  605. }
  606. else {
  607. that.$message.error(result.message);
  608. }
  609. }).catch(error => {
  610. console.log(error, 'eeee');
  611. });
  612. }
  613. });
  614. },
  615. // 分页操作按钮
  616. onShowSizeChange(current, pageSize) {
  617. this.tablePag = {
  618. page: current,
  619. size: pageSize
  620. };
  621. this.handleInitTable();
  622. },
  623. // table 开关 操作按钮
  624. handleSwitchChang(checked, data) {
  625. const paramsData = {
  626. id: data.id,
  627. status: checked ? 0 : 1
  628. };
  629. getAction(urlAcount + '/finance/settLementController/updSettlementStatusById', paramsData).then(result => {
  630. if (result.code === 0) {
  631. this.$message.success(result.message);
  632. this.handleInitTable();
  633. }
  634. else {
  635. this.$message.error(result.message);
  636. }
  637. }).catch(error => {
  638. console.log(error, 'eeee');
  639. });
  640. },
  641. // 账户上传按钮
  642. handleUploadAccount() {
  643. this.policyOperationStatus = true;
  644. },
  645. // 查询的按钮
  646. handleQueryList() {
  647. this.tablePag = {
  648. page: 1,
  649. size: 10
  650. };
  651. this.handleInitTable();
  652. },
  653. // 重置的按钮
  654. handleResetList() {
  655. this.configForm = {
  656. advertiserName: '',
  657. productName: '',
  658. projectName: '',
  659. accountName: '',
  660. creativeSale: 2,
  661. mediaId: 'no',
  662. time: [moment().subtract(7, 'days').format('YYYY-MM-DD'), moment().format('YYYY-MM-DD')]
  663. };
  664. this.tablePag = {
  665. page: 1,
  666. size: 10
  667. };
  668. this.handleInitTable();
  669. }
  670. }
  671. };
  672. </script>
  673. <style lang="less" scoped>
  674. @import "settlement-account";
  675. </style>