| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457 |
- <template>
- <div class="create-skill-wrapper">
- <div class="create-skill-title">新建技能服务</div>
- <div class="progress-wrapper">
- <div class="progress-title">完成度: {{ percent }}%</div>
- <el-progress
- class="progress-bar"
- :show-text="false"
- color="#308eff"
- :percentage="percent"></el-progress>
- </div>
- <div class="form-wrapper">
- <!-- 第一步 -->
- <div v-show="currentStep === 1">
- <div class="skill-field">
- <div class="field-name"><span class="required">*</span> 技能标题</div>
- <el-input
- class="skill-title-input"
- :class="{ 'is-error': titleError }"
- v-model="title"
- maxlength="50"
- show-word-limit
- placeholder="请输入"></el-input>
- </div>
- </div>
- <!-- 第二步 -->
- <div v-show="currentStep === 2">
- <div class="price-field">
- <div class="price-wrapper">
- <div class="field-name"><span class="required">*</span> 技能价格</div>
- <el-input
- class="price-input"
- :class="{ 'is-error': priceError }"
- type="number"
- placeholder="请输入价格"
- v-model="price"></el-input>
- <span class="yuan">元</span>
- </div>
- <div class="cate-wrapper">
- <div class="field-name"><span class="required">*</span> 技能类别</div>
- <div class="cate-content">
- <el-cascader
- class="cate-cascader"
- :class="{ 'is-error': cateError }"
- v-model="selectedSkillCate"
- :options="skillCate"
- :props="{ expandTrigger: 'hover' }"
- placeholder="请选择类别"></el-cascader>
- </div>
- </div>
- </div>
- <div class="content-field">
- <div class="field-name"><span class="required">*</span> 技能描述</div>
- <div class="content-editor">
- <el-input
- class="content-input"
- type="textarea"
- :rows="8"
- :autosize="{ minRows: 8 }"
- placeholder="请输入技能描述"
- v-model="content"></el-input>
- </div>
- </div>
- </div>
- <!-- 第三步 -->
- <div v-show="currentStep === 3">
- <div class="image-field">
- <div class="field-name"><span class="required">*</span> 技能介绍图</div>
- <multi-uploader
- class="skill-image-uploader"
- :showTips="false"
- v-model="imageList"></multi-uploader>
- <div class="upload-tips">建议上传多张能证明技能价值的图片
- 第一张默认为封面
- 建议比例16:9(如:1920*1080、800*450)支持J(E)PG、PNG格式,小于5MB
- </div>
- </div>
- </div>
- </div>
- <div class="example-wrapper">
- <div class="example-content">
- <div class="example-title">
- <img class="example-icon" src="@/assets/img/skill/example-icon@2x.png" alt="example-icon">
- <span>示例</span>
- </div>
- <div class="example-text">{{ exampleText }}</div>
- </div>
- <img class="example-img" :src="exampleImage" alt="example-img">
- </div>
- <div class="actions-wrapper">
- <div class="actions-left">
- <el-button
- class="prev-btn"
- v-show="currentStep > 1"
- :disabled="currentStep === 1"
- @click="handlePrev">← 上一步</el-button>
- </div>
- <div class="actions-right">
- <el-button
- class="next-btn"
- :loading="publishIsLoading"
- :disabled="pcreateIsLoading"
- @click="handleNext">{{ currentStep === 3 ? '提交审核' : '下一步' }}</el-button>
- <el-button
- class="pcreate-btn"
- :loading="pcreateIsLoading"
- :disabled="publishIsLoading"
- v-show="currentStep === 3"
- @click="handlePcreate">存草稿</el-button>
- </div>
- </div>
- </div>
- </template>
- <script>
- import { mapState } from "vuex";
- import editor from "@/components/editor";
- import multiUploader from '@/components/multi-uploader';
- import ExampleImage1 from '@/assets/img/skill/example-img1@2x.png'
- import ExampleImage2 from '@/assets/img/skill/example-img2@2x.png'
- import ExampleImage3 from '@/assets/img/skill/example-img3@2x.png'
- export default {
- // async asyncData({ $axios, params }) {
- // let res = await $axios.$get(`/api/vip/getList`)
- // console.log('init', res)
- // },
- head: {
- title: "新建技能服务"
- },
- components: {
- editor,
- multiUploader
- },
- data() {
- return {
- ExampleImage1,
- ExampleImage2,
- ExampleImage3,
- currentStep: 1, // 当前的步骤:1、2、3
- sale_id: '', // 编辑时的 id
- title: '', // 技能标题
- price: '', // 技能价格
- selectedSkillCate: [], // 选中的技能分类
- skillCate: [], // 技能分类数据源
- content: '', // 技能描述
- defaultContent: '', // 默认的技能描述
- imageList: [], // 图片列表
- publishIsLoading: false, // 是否在提交审核
- pcreateIsLoading: false, // 是否在存草稿中
- priceError: false,
- titleError: false,
- cateError: false,
- contentError: false
- }
- },
- computed: {
- // 在示例中展示的文字
- exampleText () {
- let text = ''
- if (this.currentStep === 1) {
- text = `最好是一个细分类目下具体有场景的服务内容!
- 如:
- 1、我可以2小时内完成一个VUE公共组件编写
- 2、我可以完成小程序、公众号页面(100%)还原
- 3、我可以完成网站https证书安装部署,提高网站安全性和用户信任`
- } else if (this.currentStep === 2) {
- text = `服务内容需要把边界和风险描述清楚!
- 如:
- 服务包含的内容:
- 1、介绍你的服务包含哪些内容
- 2、明确好服务边界,需要由具体的量词描述
- 服务优势:
- 1、你有过哪些相关经验
- 2、你比其他人在哪些方面有优势
- 需客户提供的信息:
- 1、你的工作开展前需要客户提供哪些资料
- 其他:
- 1、将服务风险前置,如修改次数以及超出服务部分如何收费的规则等`
- } else if (this.currentStep === 3) {
- text = `您可以上传工作的最终交付物截图,增加技能的吸引力,让您的技能区别于其他人才,提高曝光率和成单率`
- }
- return text
- },
- // 在示例中展示的图片
- exampleImage () {
- let image = null
- if (this.currentStep === 1) {
- image = this.ExampleImage1
- } else if (this.currentStep === 2) {
- image = this.ExampleImage2
- } else if (this.currentStep === 3) {
- image = this.ExampleImage3
- }
- return image
- },
- // 新建/编辑技能的进度:0-100
- percent () {
- let val = 0
- if (this.currentStep === 2) {
- val = 33.3
- } else if (this.currentStep === 3) {
- val = 66.7
- }
- return val
- }
- },
- mounted () {
- this.needLogin()
- this._getSkillCate()
- this.sale_id = this.$route.query.sale_id || ''
- if (this.sale_id) {
- this._getSkillDetail()
- }
- },
- methods: {
- /** 获取技能分类 */
- _getSkillCate () {
- this.$axios.$post('/api/sale/cateListYes', { type: 2, point: 1 }).then(res => {
- if (res.status === 1) {
- let skillCate = res.data || []
- this.skillCate = skillCate.map(item => {
- let children = item.child_list.map(child => {
- return {
- value: child.category_id,
- label: child.name
- }
- })
- return {
- value: item.category_id,
- label: item.name,
- children: children
- }
- })
- }
- }).catch(err => {
- console.log('get skill cate error: ', err)
- })
- },
- /** 获取技能服务详情 */
- _getSkillDetail () {
- const self = this
- this.$axios.$post('/api/sale/saleInfo', { sale_id: this.sale_id }).then(res => {
- if (res.status === 1) {
- console.log('获取技能详情成功', res.data)
- self.title = res.data.title || ""
- self.price = res.data.price || ""
- self.content = res.data.content || self.defaultContent
- if (res.data.cate_id_one && res.data.cate_id_two) {
- self.selectedSkillCate = [res.data.cate_id_one, res.data.cate_id_two]
- }
- self._setSkillImages(res.data)
- }
- })
- },
- /** 创建、编辑技能 */
- _publishSkillData (actType) {
- const self = this
- const data = {
- title: this.title,
- price: this.price,
- content: this.content,
- img: this.imageList.map((it) => it.url).join(","),
- type: 1,
- cate_id_one: this.selectedSkillCate[0],
- cate_id_two: this.selectedSkillCate[1],
- act: actType,
- sale_id: this.sale_id || ''
- }
- if (actType === 'pcreate') {
- this.pcreateIsLoading = true
- } else {
- this.publishIsLoading = true
- }
- this.$axios.$post('/api/sale/create', data).then(res => {
- if (res.status === 1) {
- // self.$message.success(`${self.sale_id ? '编辑' : '创建'}技能成功!`)
- if (actType === 'pcreate') {
- self.$message.success('保存草稿成功')
- } else {
- self.$message.success('保存成功,平台将在1-3个工作日内完成审核')
- }
- setTimeout(() => {
- window.location.href = '/workbench/skill/index'
- }, 1200)
- } else {
- self.$message.error('保存失败')
- }
- }).then(() => {
- setTimeout(() => {
- self.pcreateIsLoading = false
- self.publishIsLoading = false
- }, 800)
- })
- },
- /** 编辑时初始化图片列表 */
- _setSkillImages (data) {
- let images = data.image.split(',')
- if (images && images.length > 0) {
- images.forEach((image, index) => {
- let imageName = this._getImageName(image);
- console.log("imageName", imageName);
- this.imageList.push({ name: imageName + index, url: image });
- })
- }
- },
- /** 通过 image url 获取名字 */
- _getImageName (url) {
- if (url) {
- try {
- const lastquotaIndex = url.lastIndexOf("/");
- const lastDotIndex = url.lastIndexOf('.');
- return url.substring(lastquotaIndex + 1, lastDotIndex);
- } catch (e) {
- console.log(e);
- }
- }
- return ""
- },
- /** 技能描述内容改变时 */
- handleChange (val) {
- this.content = val
- },
- /** 点击上一步 */
- handlePrev () {
- if (this.currentStep > 1) {
- this.currentStep--
- window.scroll(0, 103)
- }
- },
- /** 点击下一步 */
- handleNext () {
- this.titleError = false
- this.priceError = false
- this.cateError = false
- this.contentError = false
- // 在每一步做数据校验
- if (this.currentStep === 1) {
- if (this.title === '') {
- this.$message.error('请输入技能服务名称')
- this.titleError = true
- return
- }
- if (this.title.length < 5) {
- this.$message.error('技能服务名称不可少于5字符')
- this.titleError = true
- return
- }
- if (this.title.length > 50) {
- this.$message.error('技能服务名称不可超过50字符,请删减')
- this.titleError = true
- return
- }
- this.currentStep++
- window.scroll(0, 103)
- } else if (this.currentStep === 2) {
- if (this.price <= 0) {
- this.$message.error('请输入大于0的技能价格')
- this.priceError = true
- return
- }
- if (String(this.price).indexOf('.') > -1 &&
- String(this.price).length - String(this.price).indexOf('.') - 1 > 2) {
- this.priceError = true
- this.$message.error('技能价格最多保留两位小数')
- return
- }
- if (this.selectedSkillCate.length !== 2 ||
- (!this.selectedSkillCate[0] || !this.selectedSkillCate[1])) {
- this.cateError = true
- this.$message.error('请选择技能类别')
- return
- }
- if (!this.content) {
- this.contentError = true
- this.$message.error('请输入技能描述')
- return
- }
- this.currentStep++
- window.scroll(0, 103)
- } else if (this.currentStep === 3) {
- if (this.imageList.length === 0) {
- this.$message.error('请上传技能介绍图')
- return
- }
- this._publishSkillData(this.sale_id ? 'update' : 'create')
- }
- },
- /** 点击存草稿 */
- handlePcreate () {
- if (this.imageList.length === 0) {
- this.$message.error('请上传技能介绍图')
- return
- }
- this._publishSkillData('pcreate')
- }
- }
- }
- </script>
- <style scope lang="scss">
- @import "@/assets/css/skill/create.scss";
- </style>
- <style>
- input::-webkit-outer-spin-button,
- input::-webkit-inner-spin-button {
- -webkit-appearance: none !important;
- }
- input[type="number"]{
- -moz-appearance: textfield !important;
- }
- </style>
- <style lang="scss">
- // 编辑器样式
- .content-editor {
- .my-editor {
- .ql-snow {
- border: 1px solid #d7dfe8 !important;
- border-radius: 3px 3px 0 0 !important;
- }
- .quill-editor {
- border-width: 1px !important;
- border-top: 0 !important;
- border-color: #d7dfe8 !important;
- border-radius: 0 0 3px 3px !important;
- }
- }
- }
- // 图片上传器样式
- .skill-image-uploader {
- .el-upload-list__item {
- width: 300px !important;
- height: 168.75px !important;
- line-height: 168.75px !important;
- }
- .el-upload--picture-card {
- width: 300px !important;
- height: 168.75px !important;
- line-height: 168.75px !important;
- .el-upload-list__item-thumbnail {
- object-fit: scale-down !important;
- }
- }
- .el-upload-list--picture-card {
- .el-upload-list__item-thumbnail {
- object-fit: scale-down !important;
- }
- }
- }
- </style>
|